diff options
| author | aarne <unknown> | 2005-06-02 09:23:52 +0000 |
|---|---|---|
| committer | aarne <unknown> | 2005-06-02 09:23:52 +0000 |
| commit | a38a894481aff1b658b1d86409a1eaa59c737f2e (patch) | |
| tree | 7f955c733808000e1a20af013a1aa63bc11a1bbd /src/GF/Compile | |
| parent | d1ce9df4643af5f27972771ad6baf4d7bc81d369 (diff) | |
lin rules by parsing
Diffstat (limited to 'src/GF/Compile')
| -rw-r--r-- | src/GF/Compile/MkConcrete.hs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/GF/Compile/MkConcrete.hs b/src/GF/Compile/MkConcrete.hs new file mode 100644 index 000000000..6295e9851 --- /dev/null +++ b/src/GF/Compile/MkConcrete.hs @@ -0,0 +1,71 @@ +---------------------------------------------------------------------- +-- | +-- Module : MkConcrete +-- Maintainer : AR +-- Stability : (stable) +-- Portability : (portable) +-- +-- > CVS $Date: +-- > CVS $Author: +-- > CVS $Revision: +-- +-- Compile a gfl file into a concrete syntax by using the parser on a resource grammar. +----------------------------------------------------------------------------- + +module GF.Compile.MkConcrete (mkConcrete) where + +import GF.Grammar.Values (Tree,tree2exp) +import GF.Grammar.PrGrammar (prt_) +import GF.Compile.ShellState (absId,stateGrammarWords) +import GF.API + +import GF.Data.Operations +import GF.Infra.UseIO + +import Data.Char +import Control.Monad + +-- translate strings into lin rules by parsing in a resource +-- grammar. AR 2/6/2005 + +-- Format of rule (on one line): +-- lin F x y = in C "ssss" ; +-- Format of resource path (on first line): +-- --# -resource=PATH +-- Other lines are copied verbatim. + + +mkConcrete :: FilePath -> IO () +mkConcrete file = do + cont <- liftM lines $ readFileIf file + let res = getResPath cont + gr <- file2grammar res + let abs = prt_ $ absId gr + let parser cat = parse gr (string2GFCat abs cat) + let mor = \w -> isInBinTree w $ sorted2tree [(w,()) | w <- stateGrammarWords gr] + writeFile (suffixFile "gf" (justModuleName file)) $ unlines $ + map (mkCnc parser mor) cont + +getResPath :: [String] -> String +getResPath s = case head (dropWhile (all isSpace) s) of + '-':'-':'#':path -> reverse (takeWhile (not . (=='=')) (reverse path)) + _ -> error "first line must be --# -resource=<PATH>" + +mkCnc :: (String -> String -> [Tree]) -> (String -> Bool) -> String -> String +mkCnc parser morph line = case words line of + "lin" : rest -> mkLinRule rest + _ -> line + where + mkLinRule s = + let + (pre,str) = span (/= "in") s + ([cat],rest) = splitAt 1 $ tail str + lin = init (tail (unwords (init rest))) -- unquote + def = case parser cat lin of + [t] -> prt_ $ tree2exp t + t:_ -> prt_ (tree2exp t) +++ "{- AMBIGUOUS -}" + [] -> "" + in + if null def + then "-- NO PARSE " ++ line + else "lin " ++ unwords pre +++ def +++ ";" |
