Got SRGS ABNF generation to compile.

This commit is contained in:
bjorn
2008-09-23 12:56:25 +00:00
parent 75df5cf443
commit 34c5617ef6
3 changed files with 27 additions and 46 deletions

View File

@@ -10,6 +10,7 @@ import GF.Compile.GFCCtoJS
import GF.Infra.Option import GF.Infra.Option
import GF.Speech.CFG import GF.Speech.CFG
import GF.Speech.PGFToCFG import GF.Speech.PGFToCFG
import GF.Speech.SRGS_ABNF
import GF.Speech.SRGS_XML import GF.Speech.SRGS_XML
import GF.Speech.JSGF import GF.Speech.JSGF
import GF.Speech.GSL import GF.Speech.GSL
@@ -38,6 +39,8 @@ exportPGF opts fmt pgf =
FmtBNF -> single "bnf" bnfPrinter FmtBNF -> single "bnf" bnfPrinter
FmtSRGS_XML -> single "grxml" (srgsXmlPrinter sisr) FmtSRGS_XML -> single "grxml" (srgsXmlPrinter sisr)
FmtSRGS_XML_NonRec -> single "grxml" srgsXmlNonRecursivePrinter FmtSRGS_XML_NonRec -> single "grxml" srgsXmlNonRecursivePrinter
FmtSRGS_ABNF -> single "gram" (srgsAbnfPrinter sisr)
FmtSRGS_ABNF_NonRec -> single "gram" srgsXmlNonRecursivePrinter
FmtJSGF -> single "jsgf" (jsgfPrinter sisr) FmtJSGF -> single "jsgf" (jsgfPrinter sisr)
FmtGSL -> single "gsl" gslPrinter FmtGSL -> single "gsl" gslPrinter
FmtVoiceXML -> single "vxml" grammar2vxml FmtVoiceXML -> single "vxml" grammar2vxml

View File

@@ -50,8 +50,7 @@ data SRG = SRG { srgName :: String -- ^ grammar name
} }
deriving (Eq,Show) deriving (Eq,Show)
data SRGRule = SRGRule Cat [SRGAlt] -- ^ SRG category name, original category name data SRGRule = SRGRule Cat [SRGAlt]
-- and productions
deriving (Eq,Show) deriving (Eq,Show)
-- | maybe a probability, a rule name and an EBNF right-hand side -- | maybe a probability, a rule name and an EBNF right-hand side

View File

@@ -17,21 +17,15 @@
-- FIXME: convert to UTF-8 -- FIXME: convert to UTF-8
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Speech.PrSRGS_ABNF (srgsAbnfPrinter, srgsAbnfNonRecursivePrinter) where module GF.Speech.SRGS_ABNF (srgsAbnfPrinter, srgsAbnfNonRecursivePrinter) where
import GF.Conversion.Types
import GF.Data.Utilities import GF.Data.Utilities
import GF.Formalism.CFG
import GF.Formalism.Utilities (Symbol(..), NameProfile(..), Profile(..), filterCats)
import GF.Infra.Ident
import GF.Infra.Print
import GF.Infra.Option import GF.Infra.Option
import GF.Probabilistic.Probabilistic (Probs) import GF.Speech.CFG
import GF.Speech.SISR import GF.Speech.SISR as SISR
import GF.Speech.SRG import GF.Speech.SRG
import GF.Speech.RegExp import GF.Speech.RegExp
import GF.Compile.ShellState (StateGrammar) import PGF (PGF, CId)
import GF.Today
import Data.Char import Data.Char
import Data.List import Data.List
@@ -43,49 +37,33 @@ width :: Int
width = 75 width = 75
srgsAbnfPrinter :: Maybe SISRFormat srgsAbnfPrinter :: Maybe SISRFormat
-> Bool -- ^ Include probabilities -> PGF -> CId -> String
-> Options srgsAbnfPrinter sisr pgf cnc = showDoc $ prABNF sisr $ makeSimpleSRG pgf cnc
-> StateGrammar -> String
srgsAbnfPrinter sisr probs opts s = showDoc $ prABNF sisr probs $ makeSimpleSRG opts s
srgsAbnfNonRecursivePrinter :: Options -> StateGrammar -> String srgsAbnfNonRecursivePrinter :: PGF -> CId -> String
srgsAbnfNonRecursivePrinter opts s = showDoc $ prABNF Nothing False $ makeNonRecursiveSRG opts s srgsAbnfNonRecursivePrinter pgf cnc = showDoc $ prABNF Nothing $ makeNonRecursiveSRG pgf cnc
showDoc = renderStyle (style { lineLength = width }) showDoc = renderStyle (style { lineLength = width })
prABNF :: Maybe SISRFormat -> Bool -> SRG -> Doc prABNF :: Maybe SISRFormat -> SRG -> Doc
prABNF sisr probs srg@(SRG{grammarName=name,grammarLanguage=ml, prABNF sisr srg
startCat=start,origStartCat=origStart,rules=rs}) = header $++$ foldr ($++$) empty (map prRule (srgRules srg))
= header $++$ vcat topCatRules $++$ foldr ($++$) empty (map prRule rs)
where where
header = text "#ABNF 1.0 UTF-8;" $$ header = text "#ABNF 1.0 UTF-8;" $$
meta "description" meta "description" ("Speech recognition grammar for " ++ srgName srg) $$
("Speech recognition grammar for " ++ name meta "generator" "Grammatical Framework" $$
++ ". " ++ "Original start category: " ++ origStart) $$
meta "generator" ("Grammatical Framework " ++ version) $$
language $$ tagFormat $$ mainCat language $$ tagFormat $$ mainCat
language = maybe empty (\l -> text "language" <+> text l <> char ';') ml language = maybe empty (\l -> text "language" <+> text l <> char ';') (srgLanguage srg)
tagFormat | isJust sisr = text "tag-format" <+> text "<semantics/1.0>" <> char ';' tagFormat | isJust sisr = text "tag-format" <+> text "<semantics/1.0>" <> char ';'
| otherwise = empty | otherwise = empty
mainCat = case cfgCatToGFCat origStart of mainCat = text "root" <+> prCat (srgStartCat srg) <> char ';'
Just c -> text "root" <+> prCat (catFormId c) <> char ';' prRule (SRGRule cat alts) = rule (isExternalCat srg cat) cat (map prAlt alts)
Nothing -> empty
prRule (SRGRule cat origCat rhs) =
comment origCat $$
rule False cat (map prAlt rhs)
-- FIXME: use the probability
prAlt (SRGAlt mp n rhs) = sep [initTag, p (prItem sisr n rhs), finalTag] prAlt (SRGAlt mp n rhs) = sep [initTag, p (prItem sisr n rhs), finalTag]
where initTag = tag sisr (profileInitSISR n) where initTag = tag sisr (profileInitSISR n)
finalTag = tag sisr (profileFinalSISR n) finalTag = tag sisr (profileFinalSISR n)
p = if isEmpty initTag && isEmpty finalTag then id else parens p = if isEmpty initTag && isEmpty finalTag then id else parens
topCatRules = [rule True (catFormId tc) (map (it tc) cs) | (tc,cs) <- srgTopCats srg] prCat :: Cat -> Doc
where it i c = prCat c <+> tag sisr (topCatSISR c)
catFormId :: String -> String
catFormId = (++ "_cat")
prCat :: SRGCat -> Doc
prCat c = char '$' <> text c prCat c = char '$' <> text c
prItem :: Maybe SISRFormat -> CFTerm -> SRGItem -> Doc prItem :: Maybe SISRFormat -> CFTerm -> SRGItem -> Doc
@@ -102,10 +80,11 @@ prItem sisr t = f 0
f _ (RESymbol s) = prSymbol sisr t s f _ (RESymbol s) = prSymbol sisr t s
prSymbol :: Maybe SISRFormat -> CFTerm -> Symbol SRGNT Token -> Doc prSymbol :: Maybe SISRFormat -> CFTerm -> SRGSymbol -> Doc
prSymbol sisr cn (Cat n@(c,_)) = prCat c <+> tag sisr (catSISR cn n) prSymbol sisr cn (NonTerminal n@(c,_)) = prCat c <+> tag sisr (catSISR cn n)
prSymbol _ cn (Tok t) | all isPunct (prt t) = empty -- removes punctuation prSymbol _ cn (Terminal t)
| otherwise = text (prt t) -- FIXME: quote if there is whitespace or odd chars | all isPunct t = empty -- removes punctuation
| otherwise = text t -- FIXME: quote if there is whitespace or odd chars
tag :: Maybe SISRFormat -> (SISRFormat -> SISRTag) -> Doc tag :: Maybe SISRFormat -> (SISRFormat -> SISRTag) -> Doc
tag Nothing _ = empty tag Nothing _ = empty
@@ -126,7 +105,7 @@ comment s = text "//" <+> text s
alts :: [Doc] -> Doc alts :: [Doc] -> Doc
alts = fsep . prepunctuate (text "| ") alts = fsep . prepunctuate (text "| ")
rule :: Bool -> SRGCat -> [Doc] -> Doc rule :: Bool -> Cat -> [Doc] -> Doc
rule pub c xs = p <+> prCat c <+> char '=' <+> nest 2 (alts xs) <+> char ';' rule pub c xs = p <+> prCat c <+> char '=' <+> nest 2 (alts xs) <+> char ';'
where p = if pub then text "public" else empty where p = if pub then text "public" else empty