slight change in gfcc syntax and evaluation

This commit is contained in:
aarne
2006-10-07 14:08:58 +00:00
parent 2f284deb1c
commit f9cc79eba6
12 changed files with 678 additions and 164 deletions

View File

@@ -44,7 +44,7 @@ abstract Swadesh = Cat ** {
-- Prepositions
at_Prep : Prep ;
-- at_Prep : Prep ;
in_Prep : Prep ;
with_Prep : Prep ;

View File

@@ -12,7 +12,7 @@
-- GFC to GFCC compiler. AR Aug-Oct 2006
-----------------------------------------------------------------------------
module GF.Canon.CanonToGFCC (prCanon2gfcc, prCanon2f_gfcc) where
module GF.Canon.CanonToGFCC (prCanon2gfcc) where
import GF.Canon.AbsGFC
import qualified GF.Canon.GFC as GFC
@@ -30,11 +30,6 @@ import qualified GF.Infra.Modules as M
import qualified GF.Infra.Option as O
import GF.UseGrammar.Linear (expandLinTables, unoptimizeCanon)
-- these are needed for FCFG printing and might be moved
import GF.FCFG.ToFCFG (printFGrammar)
import GF.Conversion.GFC (gfc2fcfg)
import GF.Infra.Option (noOptions)
import GF.Infra.Ident
import GF.Data.Operations
import GF.Text.UTF8
@@ -49,25 +44,12 @@ prCanon2gfcc :: CanonGrammar -> String
prCanon2gfcc =
Pr.printTree . canon2gfcc . reorder . utf8Conv . canon2canon . normalize
-- print FCFG corresponding to the GFCC
prCanon2f_gfcc :: CanonGrammar -> String
prCanon2f_gfcc =
unlines . map printFGrammar . toFCFG .
reorder . utf8Conv . canon2canon . normalizeNoOpt
where
toFCFG cgr@(M.MGrammar (am:cms)) =
[gfc2fcfg noOptions (M.MGrammar [am,cm],c) | cm@(c,_) <- cms]
-- gfc2fcfg :: Options -> (CanonGrammar, Ident) -> FGrammar
-- This is needed to reorganize the grammar. GFCC has its own back-end optimization.
-- But we need to have the canonical order in tables, created by valOpt
normalize :: CanonGrammar -> CanonGrammar
normalize = share . unoptimizeCanon . Sub.unSubelimCanon where
share = M.MGrammar . map (shareModule valOpt) . M.modules --- allOpt
-- for FCFG generation
normalizeNoOpt = unoptimizeCanon . Sub.unSubelimCanon
-- Generate GFCC from GFCM.
-- this assumes a grammar translated by canon2canon
@@ -133,10 +115,20 @@ reorder cg = M.MGrammar $
cncs = sortBy (\ (x,_) (y,_) -> compare x y)
[(lang, concr lang) | lang <- M.allConcretes cg abs]
concr la = sortBy (\ (f,_) (g,_) -> compare f g)
[changeTyp finfo |
[finfo |
(i,mo) <- mos, M.isModCnc mo, elem i (M.allExtends cg la),
finfo <- tree2list (M.jments mo)]
-- one grammar per language - needed for symtab generation
repartition :: CanonGrammar -> [CanonGrammar]
repartition cg = [M.partOfGrammar cg (lang,mo) |
let abs = maybe (error "no abstract") id $ M.greatestAbstract cg,
let mos = M.allModMod cg,
lang <- M.allConcretes cg abs,
let mo = errVal
(error ("no module found for " ++ A.prt lang)) $ M.lookupModule cg lang
]
-- convert to UTF8 if not yet converted
utf8Conv :: CanonGrammar -> CanonGrammar
utf8Conv = M.MGrammar . map toUTF8 . M.modules where

View File

@@ -56,6 +56,7 @@ data Term =
| FV [Term]
| W String Term
| RP Term Term
| TM
deriving (Eq,Ord,Show)
data Tokn =

View File

@@ -32,21 +32,23 @@ lookMap :: (Show i, Ord i) => a -> i -> Map i a -> a
lookMap d c m = maybe d id $ Data.Map.lookup c m
lookLin :: GFCC -> CId -> CId -> Term
lookLin mcfg lang fun = lookMap term0 fun $ lookMap undefined lang $ concretes mcfg
lookLin mcfg lang fun =
lookMap (term0 fun) fun $ lookMap undefined lang $ concretes mcfg
linearize :: GFCC -> CId -> Exp -> String
linearize mcfg lang = realize . linExp mcfg lang
realize :: Term -> String
realize trm = case trm of
R (t:_) -> realize t
R ts -> realize (ts !! 0)
S ss -> unwords $ Prelude.map realize ss
K (KS s) -> s
K (KP s _) -> unwords s ---- prefix choice TODO
K t -> case t of
KS s -> s
KP s _ -> unwords s ---- prefix choice TODO
W s t -> s ++ realize t
FV (t:_) -> realize t
RP _ r -> realize r
FV ts -> realize (ts !! 0) ---- other variants TODO
RP _ r -> realize r
TM -> "?"
_ -> "ERROR " ++ show trm ---- debug
linExp :: GFCC -> CId -> Exp -> Term
@@ -56,7 +58,7 @@ linExp mcfg lang tree@(Tr at trees) =
AS s -> R [kks (show s)] -- quoted
AI i -> R [kks (show i)]
AF d -> R [kks (show d)]
AM -> R [kks "?"]
AM -> TM
where
lin = linExp mcfg lang
comp = compute mcfg lang
@@ -65,8 +67,8 @@ linExp mcfg lang tree@(Tr at trees) =
exp0 :: Exp
exp0 = Tr (AS "NO_PARSE") []
term0 :: Term
term0 = kks "UNKNOWN_ID"
term0 :: CId -> Term
term0 (CId s) = R [kks ("#" ++ s ++ "#")]
kks :: String -> Term
kks = K . KS
@@ -74,42 +76,40 @@ kks = K . KS
compute :: GFCC -> CId -> [Term] -> Term -> Term
compute mcfg lang args = comp where
comp trm = case trm of
P r (FV ts) -> FV $ Prelude.map (comp . P r) ts
P r p -> case (comp r, comp p) of
-- for the suffix optimization
(W s (R ss), p') -> case comp $ idx ss (getIndex p' p') of
K (KS u) -> kks (s ++ u)
(r', p') -> comp $ idx (getFields r') (getIndex (P r' p') p')
P r p -> proj (comp r) (comp p)
RP i t -> RP (comp i) (comp t)
W s t -> W s (comp t)
R ts -> R $ Prelude.map comp ts
V i -> idx args (fromInteger i) -- already computed
S ts -> S $ Prelude.filter (/= S []) $ Prelude.map comp ts
F c -> comp $ look c -- global const: not comp'd (if contains argvar)
FV ts -> FV $ Prelude.map comp ts
W s t -> W s (comp t)
R ts -> R $ Prelude.map comp ts
V i -> idx args (fromInteger i) -- already computed
F c -> comp $ look c -- not computed (if contains argvar)
FV ts -> FV $ Prelude.map comp ts
S ts -> S $ Prelude.filter (/= S []) $ Prelude.map comp ts
_ -> trm
look = lookLin mcfg lang
idx xs i =
if length xs <= i ---- debug
then trace ("ERROR in compiler producing " ++ show xs ++ " !! " ++ show i)
(last xs)
else xs !! i
getIndex t0 t = case t of
C i -> fromInteger i
RP p _ -> getIndex t0 $ p
_ -> trace ("ERROR in compiler: index from " ++ show t) 0
---- TODO: this is workaround for a compiler bug
-- R (u : _) -> trace (show t ++ " IN\n" ++ show t0) $ getIndex t0 u
idx xs i = xs !! i
getFields t = case t of
R rs -> rs
RP _ r -> getFields r
_ -> trace ("ERROR in compiler: fields from " ++ show t) [t]
proj r p = case (r,p) of
(_, FV ts) -> FV $ Prelude.map (proj r) ts
(W s t, _) -> kks (s ++ getString (proj t p))
_ -> comp $ getField r (getIndex p)
getString t = case t of
K (KS s) -> s
_ -> trace ("ERROR in grammar compiler: string from "++ show t) "ERR"
getIndex t = case t of
C i -> fromInteger i
RP p _ -> getIndex p
TM -> 0 -- default value for parameter
_ -> trace ("ERROR in grammar compiler: index from " ++ show t) 0
getField t i = case t of
R rs -> idx rs i
RP _ r -> getField r i
TM -> TM
_ -> trace ("ERROR in grammar compiler: field from " ++ show t) t
mkGFCC :: Grammar -> GFCC
mkGFCC (Grm (Hdr a cs) ab@(Abs funs) ccs) = GFCC {

View File

@@ -1,6 +1,6 @@
Grm. Grammar ::= Header ";" Abstract ";" [Concrete] ";" ;
Grm. Grammar ::= Header ";" Abstract ";" [Concrete] ;
Hdr. Header ::= "grammar" CId "(" [CId] ")" ;
Abs. Abstract ::= "abstract" "{" [AbsDef] "}" ";" ;
Abs. Abstract ::= "abstract" "{" [AbsDef] "}" ;
Cnc. Concrete ::= "concrete" CId "{" [CncDef] "}" ;
Fun. AbsDef ::= CId ":" Type "=" Exp ;
@@ -19,7 +19,7 @@ trA. Exp ::= Atom ;
define trA a = Tr a [] ;
R. Term ::= "[" [Term] "]" ; -- record/table
P. Term ::= Term "[" Term "]" ; -- projection/selection
P. Term ::= "(" Term "!" Term ")" ; -- projection/selection
S. Term ::= "(" [Term] ")" ; -- sequence with ++
K. Term ::= Tokn ; -- token
V. Term ::= "$" Integer ; -- argument
@@ -28,6 +28,7 @@ F. Term ::= CId ; -- global constant
FV. Term ::= "[|" [Term] "|]" ; -- free variation
W. Term ::= "(" String "+" Term ")" ; -- prefix + suffix table
RP. Term ::= "(" Term "@" Term ")"; -- record parameter alias
TM. Term ::= "?" ; -- lin of metavariable
KS. Tokn ::= String ;
KP. Tokn ::= "[" "pre" [String] "[" [Variant] "]" "]" ;
@@ -37,7 +38,7 @@ Var. Variant ::= [String] "/" [String] ;
terminator Concrete ";" ;
terminator AbsDef ";" ;
terminator CncDef ";" ;
terminator CId "" ;
separator CId "," ;
separator Term "," ;
terminator Exp "" ;
terminator String "" ;

File diff suppressed because one or more lines are too long

View File

@@ -166,21 +166,21 @@ happyOutTok x = unsafeCoerce# x
{-# INLINE happyOutTok #-}
happyActOffsets :: HappyAddr
happyActOffsets = HappyA# "\x12\x01\x12\x01\x13\x01\x0b\x01\x3a\x00\x30\x00\x00\x00\x25\x00\x60\x00\x1e\x00\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x09\x01\x0c\x01\x00\x00\x06\x01\x64\x00\x08\x01\x9d\x00\xff\xff\x00\x00\x00\x00\x00\x00\xbb\x00\x00\x00\x08\x01\x1e\x00\x06\x00\x0a\x01\x1e\x00\x00\x00\x00\x00\xb5\x00\x2b\x00\x2a\x00\xb2\x00\x05\x01\x05\x01\x07\x01\x4e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x00\x00\x04\x01\x00\x00\x60\x00\x04\x01\x38\x00\x03\x01\x02\x01\x01\x01\xfb\x00\x00\x01\xff\x00\xfe\x00\xfd\x00\xfa\x00\xfc\x00\xf9\x00\xf8\x00\xf5\x00\xf6\x00\xf4\x00\xf3\x00\x00\x00\xef\x00\xf7\x00\x00\x00\xf2\x00\x1e\x00\x00\x00\xec\x00\x00\x00\x1e\x00\x00\x00\xf1\x00\xf0\x00\xed\x00\xee\x00\x00\x00\xea\x00\xeb\x00\xba\x00\xe9\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\xe7\x00\x00\x00\x00\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\xab\x00\x0b\x00\x00\x00\xe5\x00\xe4\x00\xe3\x00\xe2\x00\x00\x00\x29\x00\x00\x00\xe8\x00\x00\x00\x07\x00\xe6\x00\x28\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x23\x00\xb9\x00\x80\x00\x00\x00\x00\x00\xe1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x00\x00\xdc\x00\x00\x00\x00\x00"#
happyActOffsets = HappyA# "\x0c\x01\x0c\x01\x0d\x01\x0b\x01\x32\x00\xfa\xff\x04\x01\x28\x00\x51\x00\x1a\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x01\x1a\x00\x00\x00\x00\x00\x01\x01\x05\x01\x00\x00\x09\x01\xab\x00\xfe\x00\xb2\x00\xff\xff\x00\x00\x00\x00\x00\x00\x07\x01\x00\x00\xfc\x00\x1a\x00\x00\x00\x06\x00\xff\x00\x1a\x00\x00\x00\x00\x00\x02\x01\xfa\x00\x29\x00\x0f\x00\xed\xff\xfa\x00\xfa\x00\xfd\x00\xf9\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x00\x00\x00\x00\x00\xf9\x00\x00\x00\x51\x00\xf9\x00\xfb\x00\xf8\x00\xf6\x00\xf7\x00\xf5\x00\xf4\x00\xf3\x00\xf2\x00\xef\x00\xea\x00\xf0\x00\xe9\x00\xe6\x00\xe5\x00\xf1\x00\xe3\x00\xee\x00\x00\x00\xed\x00\xe8\x00\xe2\x00\xe7\x00\x1a\x00\xda\x00\x00\x00\x00\x00\xec\x00\xeb\x00\xe4\x00\xd7\x00\xd8\x00\x00\x00\xdf\x00\xd5\x00\x23\x00\xe0\x00\x1a\x00\x00\x00\x00\x00\x00\x00\xaa\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x1a\x00\x1a\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2d\x00\x24\x00\x00\x00\x00\x00\xd1\x00\xdd\x00\xce\x00\x00\x00\x07\x00\xcd\x00\xe1\x00\x00\x00\xde\x00\x00\x00\x05\x00\x00\x00\x28\x00\x00\x00\x00\x00\xaa\x00\xdc\x00\xdb\x00\xd9\x00\x00\x00\x00\x00\x00\x00\xd4\x00\x00\x00\x00\x00\x00\x00\xc7\x00\xcc\x00\x00\x00\x00\x00"#
happyGotoOffsets :: HappyAddr
happyGotoOffsets = HappyA# "\x8c\x00\xdf\x00\xe0\x00\xde\x00\xc9\x00\x31\x00\x74\x00\xad\x00\xbe\x00\x98\x00\x04\x00\x53\x00\xdb\x00\xd2\x00\xd0\x00\xce\x00\x63\x00\xcb\x00\xc8\x00\xac\x00\x00\x00\x00\x00\x00\x00\xdd\x00\x00\x00\xdd\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\x00\x4d\x00\xda\x00\x49\x00\x00\x00\x00\x00\xd9\x00\x03\x00\xa1\x00\xd8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\x00\x00\x00\xd7\x00\x00\x00\x00\x00\xd6\x00\x00\x00\x00\x00\xd5\x00\x00\x00\xd4\x00\x00\x00\x00\x00\x00\x00\xd3\x00\x00\x00\x00\x00\xcf\x00\x00\x00\xc2\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x89\x00\x00\x00\xc5\x00\xbf\x00\x85\x00\xb3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x94\x00\x7e\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x81\x00\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x6c\x00\x00\x00\x68\x00\x46\x00\xa1\x00\x17\x00\x00\x00\xf7\xff\x08\x00\x00\x00\x03\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
happyGotoOffsets = HappyA# "\x01\x00\xd6\x00\xd3\x00\xcf\x00\xc5\x00\xa9\x00\x6b\x00\xa8\x00\xb9\x00\x93\x00\x04\x00\xf8\xff\xca\x00\xc6\x00\xc1\x00\x74\x00\x66\x00\xc0\x00\xbe\x00\xb3\x00\x00\x00\x00\x00\x00\x00\xd2\x00\x00\x00\xd2\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x62\x00\x00\x00\x50\x00\xd0\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x00\x4f\x00\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcb\x00\x00\x00\x00\x00\xc9\x00\x00\x00\xbd\x00\x00\x00\x00\x00\x00\x00\xae\x00\x00\x00\x00\x00\xa7\x00\x00\x00\x9d\x00\x00\x00\x00\x00\x55\x00\x00\x00\x8f\x00\x9c\x00\x89\x00\x7b\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00\x00\x00\x00\x72\x00\xb0\x00\x00\x00\x54\x00\x00\x00\x00\x00\x80\x00\x7c\x00\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\xa4\x00\x00\x00\x00\x00\x3b\x00\x00\x00\x39\x00\x1d\x00\x4f\x00\x5e\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x92\x00\x00\x00\x97\x00\x00\x00\x00\x00\x75\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00"#
happyDefActions :: HappyAddr
happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\xff\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xff\xca\xff\xc8\xff\xc6\xff\xc4\xff\xc2\xff\xbf\xff\xbd\xff\xbd\xff\x00\x00\xeb\xff\xba\xff\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xff\xd2\xff\xd1\xff\xc1\xff\xd4\xff\x00\x00\xc2\xff\xc2\xff\x00\x00\xc2\xff\xea\xff\xe8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xff\xda\xff\xd9\xff\xdc\xff\x00\x00\xd8\xff\xe9\xff\x00\x00\xdd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\xff\x00\x00\x00\x00\xc4\xff\x00\x00\x00\x00\xc3\xff\x00\x00\xbf\xff\x00\x00\xbd\xff\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xff\x00\x00\xcd\xff\xc1\xff\x00\x00\xc2\xff\xbe\xff\xbc\xff\xbd\xff\xbb\xff\xb9\xff\xcb\xff\xc0\xff\xd5\xff\x00\x00\x00\x00\xd7\xff\xd0\xff\xc5\xff\xc7\xff\xc9\xff\x00\x00\x00\x00\x00\x00\xdf\xff\xe1\xff\x00\x00\x00\x00\x00\x00\xc6\xff\x00\x00\xc4\xff\x00\x00\xca\xff\x00\x00\x00\x00\x00\x00\xe2\xff\x00\x00\xe0\xff\xde\xff\xd6\xff\xbb\xff\x00\x00\x00\x00\xce\xff\xcf\xff\x00\x00\xe3\xff\xe4\xff\xe5\xff\xe6\xff\x00\x00\xe7\xff\x00\x00\xcc\xff"#
happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\xff\x00\x00\x00\x00\x00\x00\x00\x00\xbb\xff\xc9\xff\xc7\xff\xc5\xff\xc3\xff\xc0\xff\xbd\xff\xbb\xff\xbb\xff\x00\x00\xeb\xff\xb8\xff\x00\x00\x00\x00\x00\x00\x00\x00\xcc\xff\xd2\xff\xd1\xff\xbf\xff\xd4\xff\x00\x00\xc0\xff\xcd\xff\xc0\xff\x00\x00\xc0\xff\xea\xff\xe8\xff\xc2\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xff\xda\xff\xd9\xff\xdc\xff\x00\x00\xd8\xff\xe9\xff\x00\x00\xdd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xff\x00\x00\x00\x00\xc3\xff\x00\x00\x00\x00\x00\x00\xbd\xff\xbb\xff\x00\x00\x00\x00\x00\x00\xc3\xff\x00\x00\xd3\xff\x00\x00\xcc\xff\xbf\xff\x00\x00\xc0\xff\xbc\xff\xba\xff\xbb\xff\xb9\xff\xb7\xff\xca\xff\xbe\xff\xd5\xff\x00\x00\x00\x00\x00\x00\xd7\xff\xd0\xff\xc1\xff\xc4\xff\xc6\xff\xc8\xff\x00\x00\x00\x00\xdf\xff\xe1\xff\x00\x00\x00\x00\x00\x00\xc5\xff\x00\x00\xc3\xff\x00\x00\xc9\xff\x00\x00\xe5\xff\x00\x00\xe2\xff\x00\x00\xe0\xff\xde\xff\xb9\xff\x00\x00\x00\x00\x00\x00\xd6\xff\xce\xff\xcf\xff\x00\x00\xe3\xff\xe4\xff\xe6\xff\xe7\xff\x00\x00\xcb\xff"#
happyCheck :: HappyAddr
happyCheck = HappyA# "\xff\xff\x02\x00\x00\x00\x01\x00\x00\x00\x03\x00\x03\x00\x10\x00\x02\x00\x0a\x00\x03\x00\x03\x00\x09\x00\x02\x00\x03\x00\x0d\x00\x0e\x00\x0b\x00\x0e\x00\x0d\x00\x0e\x00\x0a\x00\x14\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x07\x00\x1d\x00\x17\x00\x18\x00\x19\x00\x02\x00\x1b\x00\x1b\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x02\x00\x01\x00\x0b\x00\x13\x00\x0d\x00\x0e\x00\x05\x00\x05\x00\x0a\x00\x08\x00\x08\x00\x08\x00\x08\x00\x03\x00\x12\x00\x18\x00\x19\x00\x08\x00\x1b\x00\x09\x00\x18\x00\x15\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x09\x00\x08\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1d\x00\x1d\x00\x00\x00\x01\x00\x1b\x00\x03\x00\x00\x00\x01\x00\x0b\x00\x03\x00\x00\x00\x01\x00\x1b\x00\x03\x00\x1b\x00\x0d\x00\x0e\x00\x12\x00\x0b\x00\x0d\x00\x0e\x00\x18\x00\x14\x00\x0d\x00\x0e\x00\x0b\x00\x14\x00\x0f\x00\x00\x00\x01\x00\x14\x00\x03\x00\x0f\x00\x00\x00\x16\x00\x0a\x00\x1d\x00\x00\x00\x18\x00\x16\x00\x17\x00\x0d\x00\x0e\x00\x00\x00\x01\x00\x0a\x00\x03\x00\x12\x00\x14\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x18\x00\x13\x00\x0a\x00\x0d\x00\x0e\x00\x00\x00\x01\x00\x03\x00\x03\x00\x00\x00\x01\x00\x13\x00\x03\x00\x00\x00\x01\x00\x0b\x00\x03\x00\x0f\x00\x0d\x00\x0e\x00\x04\x00\x05\x00\x0d\x00\x0e\x00\x16\x00\x17\x00\x0d\x00\x0e\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x01\x00\x02\x00\x03\x00\x00\x00\x01\x00\x02\x00\x03\x00\x03\x00\x0d\x00\x0e\x00\x0b\x00\x0c\x00\x08\x00\x16\x00\x0b\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x00\x00\x01\x00\x02\x00\x03\x00\x18\x00\x0b\x00\x0c\x00\x0b\x00\x0c\x00\x1d\x00\x0f\x00\x03\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x16\x00\x17\x00\x0b\x00\x0b\x00\x0b\x00\x15\x00\x03\x00\x16\x00\x0c\x00\x11\x00\x03\x00\x13\x00\x13\x00\x1d\x00\x1b\x00\x08\x00\x1d\x00\x11\x00\x15\x00\x06\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x01\x00\x03\x00\x00\x00\x16\x00\x07\x00\x15\x00\x13\x00\x12\x00\x11\x00\x05\x00\x07\x00\x06\x00\x01\x00\x0c\x00\x01\x00\x07\x00\x10\x00\x03\x00\x0c\x00\x01\x00\xff\xff\x0b\x00\x01\x00\x01\x00\x04\x00\xff\xff\x02\x00\x0c\x00\x01\x00\xff\xff\x07\x00\x18\x00\x10\x00\x18\x00\x0f\x00\x07\x00\x18\x00\x04\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1b\x00\x14\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1d\x00\x1b\x00\xff\xff\xff\xff\x1d\x00\x1d\x00\x1b\x00\x13\x00\x1b\x00\x1d\x00\x1b\x00\x1d\x00\x17\x00\x1d\x00\x15\x00\x1d\x00\x1d\x00\x19\x00\x18\x00\x1d\x00\x1d\x00\x14\x00\x16\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
happyCheck = HappyA# "\xff\xff\x02\x00\x08\x00\x16\x00\x00\x00\x04\x00\x05\x00\x0f\x00\x02\x00\x0a\x00\x05\x00\x1e\x00\x05\x00\x08\x00\x16\x00\x08\x00\x0a\x00\x0b\x00\x0e\x00\x07\x00\x0e\x00\x0f\x00\x1c\x00\x08\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x02\x00\x1e\x00\x18\x00\x19\x00\x1a\x00\x1c\x00\x1c\x00\x1c\x00\x0a\x00\x0b\x00\x02\x00\x03\x00\x0e\x00\x0f\x00\x02\x00\x1c\x00\x10\x00\x1e\x00\x0a\x00\x12\x00\x0d\x00\x08\x00\x0a\x00\x19\x00\x1a\x00\x12\x00\x1c\x00\x14\x00\x0b\x00\x00\x00\x08\x00\x00\x00\x0b\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1c\x00\x19\x00\x1e\x00\x00\x00\x01\x00\x19\x00\x03\x00\x00\x00\x01\x00\x1c\x00\x03\x00\x00\x00\x01\x00\x03\x00\x03\x00\x00\x00\x0d\x00\x0e\x00\x08\x00\x03\x00\x0d\x00\x0e\x00\x0a\x00\x14\x00\x0d\x00\x0e\x00\x0a\x00\x14\x00\x03\x00\x00\x00\x01\x00\x14\x00\x03\x00\x00\x00\x01\x00\x13\x00\x03\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x03\x00\x0d\x00\x0e\x00\x13\x00\x03\x00\x0d\x00\x0e\x00\x0a\x00\x14\x00\x03\x00\x00\x00\x01\x00\x14\x00\x03\x00\x00\x00\x01\x00\x13\x00\x03\x00\x00\x00\x01\x00\x13\x00\x03\x00\x0f\x00\x0d\x00\x0e\x00\x13\x00\x16\x00\x0d\x00\x0e\x00\x16\x00\x17\x00\x0d\x00\x0e\x00\x00\x00\x01\x00\x16\x00\x03\x00\x00\x00\x01\x00\x03\x00\x03\x00\x00\x00\x01\x00\x02\x00\x03\x00\x09\x00\x0d\x00\x0e\x00\x15\x00\x03\x00\x0d\x00\x0e\x00\x0b\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x00\x00\x01\x00\x02\x00\x03\x00\x03\x00\x06\x00\x11\x00\x0b\x00\x0c\x00\x03\x00\x09\x00\x0b\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x00\x00\x01\x00\x02\x00\x03\x00\x13\x00\x13\x00\x0f\x00\x03\x00\x0c\x00\x0f\x00\x19\x00\x19\x00\x0c\x00\x16\x00\x17\x00\x03\x00\x16\x00\x17\x00\x19\x00\x03\x00\x08\x00\x03\x00\x07\x00\x1e\x00\x01\x00\x00\x00\x12\x00\x16\x00\x15\x00\x07\x00\x11\x00\x0c\x00\x06\x00\x10\x00\x05\x00\x03\x00\x16\x00\x03\x00\x03\x00\x0c\x00\x03\x00\x01\x00\x03\x00\x07\x00\x01\x00\x11\x00\x19\x00\x10\x00\x1c\x00\x19\x00\x0c\x00\x01\x00\x01\x00\x07\x00\x07\x00\x02\x00\x04\x00\x01\x00\x1c\x00\x04\x00\xff\xff\x1c\x00\xff\xff\x15\x00\xff\xff\xff\xff\x06\x00\xff\xff\xff\xff\x1c\x00\x07\x00\xff\xff\xff\xff\x1c\x00\x1e\x00\x09\x00\xff\xff\xff\xff\x1e\x00\x1e\x00\xff\xff\xff\xff\x1c\x00\xff\xff\xff\xff\xff\xff\x1c\x00\x1e\x00\xff\xff\x1e\x00\x1c\x00\x1e\x00\x18\x00\x14\x00\x1e\x00\x1e\x00\x1a\x00\x1e\x00\x14\x00\x1e\x00\x14\x00\x19\x00\x1e\x00\x1c\x00\x16\x00\x15\x00\x17\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
happyTable :: HappyAddr
happyTable = HappyA# "\x00\x00\x39\x00\x1b\x00\x1c\x00\x1b\x00\x1d\x00\x3b\x00\x8e\x00\x22\x00\x35\x00\x8e\x00\x51\x00\x58\x00\x39\x00\x83\x00\x1e\x00\x1f\x00\x23\x00\x2c\x00\x24\x00\x25\x00\x35\x00\x66\x00\x16\x00\x26\x00\x36\x00\x27\x00\x56\x00\xff\xff\x56\x00\x16\x00\x26\x00\x22\x00\x27\x00\x27\x00\x16\x00\x26\x00\x36\x00\x27\x00\x39\x00\x90\x00\x23\x00\x7c\x00\x24\x00\x25\x00\x8c\x00\x7e\x00\x35\x00\x3e\x00\x41\x00\x41\x00\x3e\x00\x3b\x00\xbd\xff\x16\x00\x26\x00\x3e\x00\x27\x00\x3c\x00\xbd\xff\x43\x00\x16\x00\x26\x00\x36\x00\x27\x00\x53\x00\x41\x00\x27\x00\x27\x00\x27\x00\x27\x00\xff\xff\xff\xff\x1b\x00\x1c\x00\x27\x00\x1d\x00\x1b\x00\x1c\x00\x85\x00\x1d\x00\x5c\x00\x1c\x00\x27\x00\x1d\x00\x27\x00\x1e\x00\x1f\x00\x7e\x00\x55\x00\x1e\x00\x1f\x00\x16\x00\x59\x00\x5d\x00\x1f\x00\x2e\x00\x5b\x00\x2b\x00\x1b\x00\x1c\x00\x5e\x00\x1d\x00\x16\x00\x7f\x00\x17\x00\x35\x00\xff\xff\x81\x00\x16\x00\x17\x00\x89\x00\x1e\x00\x1f\x00\x1b\x00\x1c\x00\x75\x00\x1d\x00\x63\x00\x20\x00\x16\x00\x26\x00\x36\x00\x27\x00\x16\x00\x3a\x00\x39\x00\x85\x00\x1f\x00\x1b\x00\x1c\x00\x88\x00\x1d\x00\x1b\x00\x1c\x00\x3a\x00\x1d\x00\x1b\x00\x1c\x00\x55\x00\x1d\x00\x16\x00\x86\x00\x1f\x00\x47\x00\x48\x00\x70\x00\x1f\x00\x17\x00\x64\x00\x73\x00\x1f\x00\x1b\x00\x1c\x00\x61\x00\x1d\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x3e\x00\x2e\x00\x1f\x00\x8a\x00\x37\x00\x57\x00\x65\x00\x60\x00\x37\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x16\x00\x55\x00\x84\x00\x36\x00\x37\x00\xff\xff\x16\x00\x89\x00\x53\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x17\x00\x18\x00\x55\x00\x55\x00\x55\x00\x43\x00\x72\x00\x6f\x00\x33\x00\x69\x00\x3e\x00\x60\x00\x60\x00\xff\xff\x27\x00\x3f\x00\xff\xff\x78\x00\x71\x00\x7a\x00\x4a\x00\x4c\x00\x4d\x00\x4f\x00\x51\x00\x5a\x00\x51\x00\x61\x00\x19\x00\x56\x00\x1a\x00\x27\x00\x28\x00\x29\x00\x45\x00\x41\x00\x43\x00\x8d\x00\x92\x00\x7c\x00\x81\x00\x2a\x00\x68\x00\x91\x00\x6d\x00\x00\x00\x55\x00\x6e\x00\x6f\x00\x78\x00\x00\x00\x7a\x00\x6b\x00\x4a\x00\x00\x00\x75\x00\x16\x00\x6a\x00\x16\x00\x6c\x00\x77\x00\x16\x00\x4c\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x45\x00\x00\x00\x51\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x27\x00\x00\x00\x00\x00\xff\xff\xff\xff\x27\x00\x64\x00\x27\x00\xff\xff\x27\x00\xff\xff\x56\x00\xff\xff\x43\x00\xff\xff\xff\xff\x26\x00\x16\x00\xff\xff\xbb\xff\x45\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
happyTable = HappyA# "\x00\x00\x3b\x00\x40\x00\x45\x00\x1b\x00\x49\x00\x4a\x00\x2d\x00\x22\x00\x37\x00\x8f\x00\xff\xff\x80\x00\x40\x00\x17\x00\x43\x00\x23\x00\x24\x00\x2e\x00\x56\x00\x25\x00\x26\x00\x28\x00\x43\x00\x16\x00\x27\x00\x38\x00\x28\x00\x22\x00\xff\xff\x56\x00\x16\x00\x27\x00\x28\x00\x28\x00\x28\x00\x23\x00\x24\x00\x3b\x00\x85\x00\x25\x00\x26\x00\x3b\x00\x28\x00\x90\x00\xff\xff\x37\x00\x80\x00\x6a\x00\x40\x00\x37\x00\x16\x00\x27\x00\x6b\x00\x28\x00\x61\x00\x86\x00\x81\x00\x43\x00\x83\x00\x30\x00\x16\x00\x27\x00\x38\x00\x28\x00\x16\x00\x27\x00\x38\x00\x28\x00\x28\x00\x16\x00\xff\xff\x1b\x00\x1c\x00\x16\x00\x1d\x00\x1b\x00\x1c\x00\x28\x00\x1d\x00\x1b\x00\x1c\x00\x40\x00\x1d\x00\x62\x00\x1e\x00\x1f\x00\x57\x00\x28\x00\x1e\x00\x1f\x00\x37\x00\x67\x00\x1e\x00\x1f\x00\x77\x00\x5a\x00\x28\x00\x5d\x00\x1c\x00\x5c\x00\x1d\x00\x1b\x00\x1c\x00\x3c\x00\x1d\x00\x16\x00\x27\x00\x38\x00\x28\x00\x28\x00\x5e\x00\x1f\x00\x7e\x00\x28\x00\x1e\x00\x1f\x00\x3b\x00\x5f\x00\x28\x00\x1b\x00\x1c\x00\x20\x00\x1d\x00\x1b\x00\x1c\x00\x3c\x00\x1d\x00\x1b\x00\x1c\x00\x6e\x00\x1d\x00\x16\x00\x86\x00\x1f\x00\x29\x00\x66\x00\x87\x00\x1f\x00\x17\x00\x8c\x00\x88\x00\x1f\x00\x1b\x00\x1c\x00\x72\x00\x1d\x00\x1b\x00\x1c\x00\x3d\x00\x1d\x00\x31\x00\x32\x00\x33\x00\x34\x00\x58\x00\x75\x00\x1f\x00\x73\x00\x74\x00\x30\x00\x1f\x00\x8d\x00\x39\x00\x31\x00\x32\x00\x33\x00\x34\x00\x31\x00\x32\x00\x33\x00\x34\x00\x3d\x00\x7c\x00\x7a\x00\x61\x00\x39\x00\x4c\x00\x3e\x00\x38\x00\x39\x00\x31\x00\x32\x00\x33\x00\x34\x00\x31\x00\x32\x00\x33\x00\x34\x00\xbb\xff\x64\x00\x16\x00\x4e\x00\x54\x00\x16\x00\xbb\xff\x16\x00\x35\x00\x17\x00\x65\x00\x40\x00\x17\x00\x18\x00\x16\x00\x4f\x00\x41\x00\x51\x00\x56\x00\xff\xff\x5b\x00\x62\x00\x2a\x00\x19\x00\x1a\x00\x43\x00\x2b\x00\x93\x00\x45\x00\x2c\x00\x47\x00\x8a\x00\x45\x00\x8b\x00\x8c\x00\x92\x00\x90\x00\x7e\x00\x69\x00\x83\x00\x70\x00\x6c\x00\x16\x00\x6e\x00\x28\x00\x16\x00\x6d\x00\x71\x00\x72\x00\x77\x00\x79\x00\x7c\x00\x7a\x00\x4c\x00\x28\x00\x4e\x00\x00\x00\x28\x00\x00\x00\x47\x00\x00\x00\x00\x00\x51\x00\x00\x00\x00\x00\x28\x00\x53\x00\x00\x00\x00\x00\x28\x00\xff\xff\x54\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x28\x00\xff\xff\x00\x00\xff\xff\x28\x00\xff\xff\x56\x00\x5a\x00\xff\xff\xff\xff\x27\x00\xff\xff\x61\x00\xff\xff\x65\x00\x16\x00\xb9\xff\x28\x00\x45\x00\x47\x00\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
happyReduceArr = array (20, 70) [
happyReduceArr = array (20, 72) [
(20 , happyReduce_20),
(21 , happyReduce_21),
(22 , happyReduce_22),
@@ -231,10 +231,12 @@ happyReduceArr = array (20, 70) [
(67 , happyReduce_67),
(68 , happyReduce_68),
(69 , happyReduce_69),
(70 , happyReduce_70)
(70 , happyReduce_70),
(71 , happyReduce_71),
(72 , happyReduce_72)
]
happy_n_terms = 30 :: Int
happy_n_terms = 31 :: Int
happy_n_nonterms = 24 :: Int
happyReduce_20 = happySpecReduce_1 0# happyReduction_20
@@ -265,9 +267,8 @@ happyReduction_23 happy_x_1
(CId (happy_var_1)
)}
happyReduce_24 = happyReduce 6# 4# happyReduction_24
happyReduction_24 (happy_x_6 `HappyStk`
happy_x_5 `HappyStk`
happyReduce_24 = happyReduce 5# 4# happyReduction_24
happyReduction_24 (happy_x_5 `HappyStk`
happy_x_4 `HappyStk`
happy_x_3 `HappyStk`
happy_x_2 `HappyStk`
@@ -290,12 +291,11 @@ happyReduction_25 (happy_x_5 `HappyStk`
= case happyOut26 happy_x_2 of { happy_var_2 ->
case happyOut42 happy_x_4 of { happy_var_4 ->
happyIn28
(Hdr happy_var_2 (reverse happy_var_4)
(Hdr happy_var_2 happy_var_4
) `HappyStk` happyRest}}
happyReduce_26 = happyReduce 5# 6# happyReduction_26
happyReduction_26 (happy_x_5 `HappyStk`
happy_x_4 `HappyStk`
happyReduce_26 = happyReduce 4# 6# happyReduction_26
happyReduction_26 (happy_x_4 `HappyStk`
happy_x_3 `HappyStk`
happy_x_2 `HappyStk`
happy_x_1 `HappyStk`
@@ -373,7 +373,7 @@ happyReduction_32 happy_x_3
= case happyOut42 happy_x_1 of { happy_var_1 ->
case happyOut26 happy_x_3 of { happy_var_3 ->
happyIn33
(Typ (reverse happy_var_1) happy_var_3
(Typ happy_var_1 happy_var_3
)}}
happyReduce_33 = happyReduce 4# 11# happyReduction_33
@@ -438,16 +438,17 @@ happyReduction_40 happy_x_3
(R happy_var_2
)}
happyReduce_41 = happyReduce 4# 13# happyReduction_41
happyReduction_41 (happy_x_4 `HappyStk`
happyReduce_41 = happyReduce 5# 13# happyReduction_41
happyReduction_41 (happy_x_5 `HappyStk`
happy_x_4 `HappyStk`
happy_x_3 `HappyStk`
happy_x_2 `HappyStk`
happy_x_1 `HappyStk`
happyRest)
= case happyOut36 happy_x_1 of { happy_var_1 ->
case happyOut36 happy_x_3 of { happy_var_3 ->
= case happyOut36 happy_x_2 of { happy_var_2 ->
case happyOut36 happy_x_4 of { happy_var_4 ->
happyIn36
(P happy_var_1 happy_var_3
(P happy_var_2 happy_var_4
) `HappyStk` happyRest}}
happyReduce_42 = happySpecReduce_3 13# happyReduction_42
@@ -523,15 +524,21 @@ happyReduction_49 (happy_x_5 `HappyStk`
(RP happy_var_2 happy_var_4
) `HappyStk` happyRest}}
happyReduce_50 = happySpecReduce_1 14# happyReduction_50
happyReduce_50 = happySpecReduce_1 13# happyReduction_50
happyReduction_50 happy_x_1
= happyIn36
(TM
)
happyReduce_51 = happySpecReduce_1 14# happyReduction_51
happyReduction_51 happy_x_1
= case happyOut23 happy_x_1 of { happy_var_1 ->
happyIn37
(KS happy_var_1
)}
happyReduce_51 = happyReduce 7# 14# happyReduction_51
happyReduction_51 (happy_x_7 `HappyStk`
happyReduce_52 = happyReduce 7# 14# happyReduction_52
happyReduction_52 (happy_x_7 `HappyStk`
happy_x_6 `HappyStk`
happy_x_5 `HappyStk`
happy_x_4 `HappyStk`
@@ -545,8 +552,8 @@ happyReduction_51 (happy_x_7 `HappyStk`
(KP (reverse happy_var_3) happy_var_5
) `HappyStk` happyRest}}
happyReduce_52 = happySpecReduce_3 15# happyReduction_52
happyReduction_52 happy_x_3
happyReduce_53 = happySpecReduce_3 15# happyReduction_53
happyReduction_53 happy_x_3
happy_x_2
happy_x_1
= case happyOut45 happy_x_1 of { happy_var_1 ->
@@ -555,13 +562,13 @@ happyReduction_52 happy_x_3
(Var (reverse happy_var_1) (reverse happy_var_3)
)}}
happyReduce_53 = happySpecReduce_0 16# happyReduction_53
happyReduction_53 = happyIn39
happyReduce_54 = happySpecReduce_0 16# happyReduction_54
happyReduction_54 = happyIn39
([]
)
happyReduce_54 = happySpecReduce_3 16# happyReduction_54
happyReduction_54 happy_x_3
happyReduce_55 = happySpecReduce_3 16# happyReduction_55
happyReduction_55 happy_x_3
happy_x_2
happy_x_1
= case happyOut39 happy_x_1 of { happy_var_1 ->
@@ -570,13 +577,13 @@ happyReduction_54 happy_x_3
(flip (:) happy_var_1 happy_var_2
)}}
happyReduce_55 = happySpecReduce_0 17# happyReduction_55
happyReduction_55 = happyIn40
happyReduce_56 = happySpecReduce_0 17# happyReduction_56
happyReduction_56 = happyIn40
([]
)
happyReduce_56 = happySpecReduce_3 17# happyReduction_56
happyReduction_56 happy_x_3
happyReduce_57 = happySpecReduce_3 17# happyReduction_57
happyReduction_57 happy_x_3
happy_x_2
happy_x_1
= case happyOut40 happy_x_1 of { happy_var_1 ->
@@ -585,13 +592,13 @@ happyReduction_56 happy_x_3
(flip (:) happy_var_1 happy_var_2
)}}
happyReduce_57 = happySpecReduce_0 18# happyReduction_57
happyReduction_57 = happyIn41
happyReduce_58 = happySpecReduce_0 18# happyReduction_58
happyReduction_58 = happyIn41
([]
)
happyReduce_58 = happySpecReduce_3 18# happyReduction_58
happyReduction_58 happy_x_3
happyReduce_59 = happySpecReduce_3 18# happyReduction_59
happyReduction_59 happy_x_3
happy_x_2
happy_x_1
= case happyOut41 happy_x_1 of { happy_var_1 ->
@@ -600,34 +607,42 @@ happyReduction_58 happy_x_3
(flip (:) happy_var_1 happy_var_2
)}}
happyReduce_59 = happySpecReduce_0 19# happyReduction_59
happyReduction_59 = happyIn42
happyReduce_60 = happySpecReduce_0 19# happyReduction_60
happyReduction_60 = happyIn42
([]
)
happyReduce_60 = happySpecReduce_2 19# happyReduction_60
happyReduction_60 happy_x_2
happy_x_1
= case happyOut42 happy_x_1 of { happy_var_1 ->
case happyOut26 happy_x_2 of { happy_var_2 ->
happyReduce_61 = happySpecReduce_1 19# happyReduction_61
happyReduction_61 happy_x_1
= case happyOut26 happy_x_1 of { happy_var_1 ->
happyIn42
(flip (:) happy_var_1 happy_var_2
((:[]) happy_var_1
)}
happyReduce_62 = happySpecReduce_3 19# happyReduction_62
happyReduction_62 happy_x_3
happy_x_2
happy_x_1
= case happyOut26 happy_x_1 of { happy_var_1 ->
case happyOut42 happy_x_3 of { happy_var_3 ->
happyIn42
((:) happy_var_1 happy_var_3
)}}
happyReduce_61 = happySpecReduce_0 20# happyReduction_61
happyReduction_61 = happyIn43
happyReduce_63 = happySpecReduce_0 20# happyReduction_63
happyReduction_63 = happyIn43
([]
)
happyReduce_62 = happySpecReduce_1 20# happyReduction_62
happyReduction_62 happy_x_1
happyReduce_64 = happySpecReduce_1 20# happyReduction_64
happyReduction_64 happy_x_1
= case happyOut36 happy_x_1 of { happy_var_1 ->
happyIn43
((:[]) happy_var_1
)}
happyReduce_63 = happySpecReduce_3 20# happyReduction_63
happyReduction_63 happy_x_3
happyReduce_65 = happySpecReduce_3 20# happyReduction_65
happyReduction_65 happy_x_3
happy_x_2
happy_x_1
= case happyOut36 happy_x_1 of { happy_var_1 ->
@@ -636,13 +651,13 @@ happyReduction_63 happy_x_3
((:) happy_var_1 happy_var_3
)}}
happyReduce_64 = happySpecReduce_0 21# happyReduction_64
happyReduction_64 = happyIn44
happyReduce_66 = happySpecReduce_0 21# happyReduction_66
happyReduction_66 = happyIn44
([]
)
happyReduce_65 = happySpecReduce_2 21# happyReduction_65
happyReduction_65 happy_x_2
happyReduce_67 = happySpecReduce_2 21# happyReduction_67
happyReduction_67 happy_x_2
happy_x_1
= case happyOut44 happy_x_1 of { happy_var_1 ->
case happyOut34 happy_x_2 of { happy_var_2 ->
@@ -650,13 +665,13 @@ happyReduction_65 happy_x_2
(flip (:) happy_var_1 happy_var_2
)}}
happyReduce_66 = happySpecReduce_0 22# happyReduction_66
happyReduction_66 = happyIn45
happyReduce_68 = happySpecReduce_0 22# happyReduction_68
happyReduction_68 = happyIn45
([]
)
happyReduce_67 = happySpecReduce_2 22# happyReduction_67
happyReduction_67 happy_x_2
happyReduce_69 = happySpecReduce_2 22# happyReduction_69
happyReduction_69 happy_x_2
happy_x_1
= case happyOut45 happy_x_1 of { happy_var_1 ->
case happyOut23 happy_x_2 of { happy_var_2 ->
@@ -664,20 +679,20 @@ happyReduction_67 happy_x_2
(flip (:) happy_var_1 happy_var_2
)}}
happyReduce_68 = happySpecReduce_0 23# happyReduction_68
happyReduction_68 = happyIn46
happyReduce_70 = happySpecReduce_0 23# happyReduction_70
happyReduction_70 = happyIn46
([]
)
happyReduce_69 = happySpecReduce_1 23# happyReduction_69
happyReduction_69 happy_x_1
happyReduce_71 = happySpecReduce_1 23# happyReduction_71
happyReduction_71 happy_x_1
= case happyOut38 happy_x_1 of { happy_var_1 ->
happyIn46
((:[]) happy_var_1
)}
happyReduce_70 = happySpecReduce_3 23# happyReduction_70
happyReduction_70 happy_x_3
happyReduce_72 = happySpecReduce_3 23# happyReduction_72
happyReduction_72 happy_x_3
happy_x_2
happy_x_1
= case happyOut38 happy_x_1 of { happy_var_1 ->
@@ -687,7 +702,7 @@ happyReduction_70 happy_x_3
)}}
happyNewToken action sts stk [] =
happyDoAction 29# (error "reading EOF!") action sts stk []
happyDoAction 30# (error "reading EOF!") action sts stk []
happyNewToken action sts stk (tk:tks) =
let cont i = happyDoAction i tk action sts stk tks in
@@ -704,22 +719,23 @@ happyNewToken action sts stk (tk:tks) =
PT _ (TS "?") -> cont 10#;
PT _ (TS "[") -> cont 11#;
PT _ (TS "]") -> cont 12#;
PT _ (TS "$") -> cont 13#;
PT _ (TS "[|") -> cont 14#;
PT _ (TS "|]") -> cont 15#;
PT _ (TS "+") -> cont 16#;
PT _ (TS "@") -> cont 17#;
PT _ (TS "/") -> cont 18#;
PT _ (TS ",") -> cont 19#;
PT _ (TS "abstract") -> cont 20#;
PT _ (TS "concrete") -> cont 21#;
PT _ (TS "grammar") -> cont 22#;
PT _ (TS "pre") -> cont 23#;
PT _ (TL happy_dollar_dollar) -> cont 24#;
PT _ (TI happy_dollar_dollar) -> cont 25#;
PT _ (TD happy_dollar_dollar) -> cont 26#;
PT _ (T_CId happy_dollar_dollar) -> cont 27#;
_ -> cont 28#;
PT _ (TS "!") -> cont 13#;
PT _ (TS "$") -> cont 14#;
PT _ (TS "[|") -> cont 15#;
PT _ (TS "|]") -> cont 16#;
PT _ (TS "+") -> cont 17#;
PT _ (TS "@") -> cont 18#;
PT _ (TS "/") -> cont 19#;
PT _ (TS ",") -> cont 20#;
PT _ (TS "abstract") -> cont 21#;
PT _ (TS "concrete") -> cont 22#;
PT _ (TS "grammar") -> cont 23#;
PT _ (TS "pre") -> cont 24#;
PT _ (TL happy_dollar_dollar) -> cont 25#;
PT _ (TI happy_dollar_dollar) -> cont 26#;
PT _ (TD happy_dollar_dollar) -> cont 27#;
PT _ (T_CId happy_dollar_dollar) -> cont 28#;
_ -> cont 29#;
_ -> happyError' (tk:tks)
}

View File

@@ -30,7 +30,7 @@ render d = rend 0 (map ($ "") $ d []) "" where
t :ts -> space t . rend i ts
_ -> id
new i = showChar '\n' . replicateS (2*i) (showChar ' ') . dropWhile isSpace
space t = showString t . (\s -> if null s then "" else (' ':s))
space t = showString t . id ----(\s -> if null s then "" else (' ':s))
parenth :: Doc -> Doc
parenth ss = doc (showChar '(') . ss . doc (showChar ')')
@@ -82,13 +82,14 @@ instance Print CId where
prt _ (CId i) = doc (showString i)
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 0 x , prt 0 xs])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
instance Print Grammar where
prt i e = case e of
Grm header abstract concretes -> prPrec i 0 (concatD [prt 0 header , doc (showString ";") , prt 0 abstract , doc (showString ";") , prt 0 concretes , doc (showString ";")])
Grm header abstract concretes -> prPrec i 0 (concatD [prt 0 header , doc (showString ";") , prt 0 abstract , doc (showString ";") , prt 0 concretes])
instance Print Header where
@@ -98,7 +99,7 @@ instance Print Header where
instance Print Abstract where
prt i e = case e of
Abs absdefs -> prPrec i 0 (concatD [doc (showString "abstract") , doc (showString "{") , prt 0 absdefs , doc (showString "}") , doc (showString ";")])
Abs absdefs -> prPrec i 0 (concatD [doc (showString "abstract") , doc (showString "{") , prt 0 absdefs , doc (showString "}")])
instance Print Concrete where
@@ -152,7 +153,7 @@ instance Print Atom where
instance Print Term where
prt i e = case e of
R terms -> prPrec i 0 (concatD [doc (showString "[") , prt 0 terms , doc (showString "]")])
P term0 term -> prPrec i 0 (concatD [prt 0 term0 , doc (showString "[") , prt 0 term , doc (showString "]")])
P term0 term -> prPrec i 0 (concatD [doc (showString "(") , prt 0 term0 , doc (showString "!") , prt 0 term , doc (showString ")")])
S terms -> prPrec i 0 (concatD [doc (showString "(") , prt 0 terms , doc (showString ")")])
K tokn -> prPrec i 0 (concatD [prt 0 tokn])
V n -> prPrec i 0 (concatD [doc (showString "$") , prt 0 n])
@@ -161,6 +162,7 @@ instance Print Term where
FV terms -> prPrec i 0 (concatD [doc (showString "[|") , prt 0 terms , doc (showString "|]")])
W str term -> prPrec i 0 (concatD [doc (showString "(") , prt 0 str , doc (showString "+") , prt 0 term , doc (showString ")")])
RP term0 term -> prPrec i 0 (concatD [doc (showString "(") , prt 0 term0 , doc (showString "@") , prt 0 term , doc (showString ")")])
TM -> prPrec i 0 (concatD [doc (showString "?")])
prtList es = case es of
[] -> (concatD [])

View File

@@ -77,6 +77,7 @@ transTerm x = case x of
FV terms -> failure x
W str term -> failure x
RP term0 term -> failure x
TM -> failure x
transTokn :: Tokn -> Result

View File

@@ -1,4 +1,13 @@
The GFCC Grammar Format
Aarne Ranta
October 3, 2006
Author's address:
[``http://www.cs.chalmers.se/~aarne`` http://www.cs.chalmers.se/~aarne]
% to compile: txt2tags -thtml --toc gfcc.txt
==What is GFCC==
GFCC is a low-level format for GF grammars. Its aim is to contain the minimum
that is needed to process GF grammars at runtime. This minimality has three
@@ -8,25 +17,43 @@ advantages:
- simple definition of interpreters
GFCC is aimed to replace GFC as the run-time grammar format. GFC is designed
to support separate compilation of grammars, to store the results of compiling
individual GF modules. But this means it has to contain extra information,
such as type information, which is only needed in compilation and not at
The idea is that all embedded GF applications are compiled to GFCC.
The GF system would be primarily used as a compiler and as a grammar
development tool.
Since GFCC is implemented in BNFC, a parser of the format is readily
available for C, C++, Haskell, Java, and OCaml. Also an XML
representation is generated in BNFC. A
[reference implementation ../]
of linearization and some other functions has been written in Haskell.
==GFCC vs. GFC==
GFCC is aimed to replace GFC as the run-time grammar format. GFC was designed
to be a run-time format, but also to
support separate compilation of grammars, i.e.
to store the results of compiling
individual GF modules. But this means that GFC has to contain extra information,
such as type annotations, which is only needed in compilation and not at
run-time. In particular, the pattern matching syntax and semantics of GFC is
complex and therefore difficult to implement in new platforms.
The main novelties of GFCC compared with GFC can be summarized as follows:
The main differences of GFCC compared with GFC can be summarized as follows:
- there are no modules, and therefore no qualified names
- a GFCC grammar is multilingual, and consists of a common abstract syntax
together with one concrete syntax per language
- there are no modules, and therefore no qualified names
- records and tables are replaced by arrays
- record labels and parameter values are replaced by integers
- record projection and table selection are replaced by array indexing
- there is (so far) no support for dependent types or higher-order abstract
syntax (which would be easy to add, but make interpreters much more difficult
to write)
Here is an example of a GF grammar, consisting of three modules,
as translated to GFCC.
as translated to GFCC. The representations are aligned, with the exceptions
due to the alphabetical sorting of GFCC grammars.
```
grammar Ex (Eng Swe);
@@ -75,3 +102,477 @@ concrete Swe of Ex = { concrete Swe {
} ;
} ;
```
==The syntax of GFCC files==
===Top level===
A grammar has a header telling the name of the abstract syntax
(often specifying an application domain), and the names of
the concrete languages. The abstract syntax and the concrete
syntaxes themselves follow.
```
Grammar ::= Header ";" Abstract ";" [Concrete] ";" ;
Header ::= "grammar" CId "(" [CId] ")" ;
Abstract ::= "abstract" "{" [AbsDef] "}" ";" ;
Concrete ::= "concrete" CId "{" [CncDef] "}" ;
```
Abstract syntax judgements give typings and semantic definitions.
Concrete syntax judgements give linearizations.
```
AbsDef ::= CId ":" Type "=" Exp ;
CncDef ::= CId "=" Term ;
```
Also flags are possible, local to each "module" (i.e. abstract and concretes).
```
AbsDef ::= "%" CId "=" String ;
CncDef ::= "%" CId "=" String ;
```
For the run-time system, the reference implementation in Haskell
uses a structure that gives efficient look-up:
```
data GFCC = GFCC {
absname :: CId ,
cncnames :: [CId] ,
abstract :: Abstr ,
concretes :: Map CId Concr
}
data Abstr = Abstr {
funs :: Map CId Type, -- find the type of a fun
cats :: Map CId [CId] -- find the funs giving a cat
}
type Concr = Map CId Term
```
===Abstract syntax===
Types are first-order function types built from
category symbols. Syntax trees (``Exp``) are
rose trees with the head (``Atom``) either a function
constant, a metavariable, or a string, integer, or float
literal.
```
Type ::= [CId] "->" CId ;
Exp ::= "(" Atom [Exp] ")" ;
Atom ::= CId ; -- function constant
Atom ::= "?" ; -- metavariable
Atom ::= String ; -- string literal
Atom ::= Integer ; -- integer literal
Atom ::= Double ; -- float literal
```
===Concrete syntax===
Linearization terms (``Term``) are built as follows.
```
Term ::= "[" [Term] "]" ; -- array
Term ::= Term "[" Term "]" ; -- access to indexed field
Term ::= "(" [Term] ")" ; -- sequence with ++
Term ::= Tokn ; -- token
Term ::= "$" Integer ; -- argument subtree
Term ::= Integer ; -- array index
Term ::= "[|" [Term] "|]" ; -- free variation
```
Tokens are strings or (maybe obsolescent) prefix-dependent
variant lists.
```
Tokn ::= String ;
Tokn ::= "[" "pre" [String] "[" [Variant] "]" "]" ;
Variant ::= [String] "/" [String] ;
```
Three special forms of terms are introduced by the compiler
as optimizations. They can in principle be eliminated, but
their presence makes grammars much more compact. Their semantics
will be explained in a later section.
```
Term ::= CId ; -- global constant
Term ::= "(" String "+" Term ")" ; -- prefix + suffix table
Term ::= "(" Term "@" Term ")"; -- record parameter alias
```
Identifiers are like ``Ident`` in GF and GFC, except that
the compiler produces constants prefixed with ``_`` in
the common subterm elimination optimization.
```
token CId (('_' | letter) (letter | digit | '\'' | '_')*) ;
```
==The semantics of concrete syntax terms==
===Linearization and realization===
The linearization algorithm is essentially the same as in
GFC: a tree is linearized by evaluating its linearization term
in the environment of the linearizations of the subtrees.
Literal atoms are linearized in the obvious way.
The function also needs to know the language (i.e. concrete syntax)
in which linearization is performed.
```
linExp :: GFCC -> CId -> Exp -> Term
linExp mcfg lang tree@(Tr at trees) = case at of
AC fun -> comp (Prelude.map lin trees) $ look fun
AS s -> R [kks (show s)] -- quoted
AI i -> R [kks (show i)]
AF d -> R [kks (show d)]
AM -> R [kks "?"] ---- TODO: proper lincat
where
lin = linExp mcfg lang
comp = compute mcfg lang
look = lookLin mcfg lang
```
The result of linearization is usually a record, which is realized as
a string using the following algorithm.
```
realize :: Term -> String
realize trm = case trm of
R (t:_) -> realize t
S ss -> unwords $ Prelude.map realize ss
K (KS s) -> s
K (KP s _) -> unwords s ---- prefix choice TODO
W s t -> s ++ realize t
FV (t:_) -> realize t
```
Since the order of record fields is not necessarily
the same as in GF source,
this realization does not work securely for
categories whose lincats more than one field.
===Term evaluation===
Evaluation follows call-by-value order, with two environments
needed:
- the grammar (a concrete syntax) to give the global constants
- an array of terms to give the subtree linearizations
The code is cleaned from debugging information present in the working
version.
```
compute :: GFCC -> CId -> [Term] -> Term -> Term
compute mcfg lang args = comp where
comp trm = case trm of
P r (FV ts) -> FV $ Prelude.map (comp . P r) ts
P r p -> case (comp r, comp p) of
-- for the suffix optimization
(W s (R ss), p') -> case comp $ idx ss (getIndex p') of
K (KS u) -> kks (s ++ u)
(r', p') -> comp $ (getFields r') !! (getIndex p')
RP i t -> RP (comp i) (comp t)
W s t -> W s (comp t)
R ts -> R $ Prelude.map comp ts
V i -> args !! (fromInteger i) -- already computed
S ts -> S $ Prelude.filter (/= S []) $ Prelude.map comp ts
F c -> comp $ lookLin mcfg lang -- not yet computed
FV ts -> FV $ Prelude.map comp ts
_ -> trm
getIndex t = case t of
C i -> fromInteger i
RP p _ -> getIndex p
getFields t = case t of
R rs -> rs
RP _ r -> getFields r
```
===The special term constructors===
The three forms introduced by the compiler may a need special
explanation.
Global constants
```
Term ::= CId ;
```
are shorthands for complex terms. They are produced by the
compiler by (iterated) common subexpression elimination.
They are often more powerful than hand-devised code sharing in the source
code. They could be computed off-line by replacing each identifier by
its definition.
Prefix-suffix tables
```
Term ::= "(" String "+" Term ")" ;
```
represent tables of word forms divided to the longest common prefix
and its array of suffixes. In the example grammar above, we have
```
Sleep = [("sleep" + ["s",""])]
```
which in fact is equal to the array of full forms
```
["sleeps", "sleep"]
```
The power of this construction comes from the fact that suffix sets
tend to be repeated in a language, and can therefore be collected
by common subexpression elimination. It is this technique that
explains the used syntax rather than the more accurate
```
"(" String "+" [String] ")"
```
since we want the suffix part to be a ``Term`` for the optimization to
take effect.
The most curious construct of GFCC is the parameter array alias,
```
Term ::= "(" Term "@" Term ")";
```
This form is used as the value of parameter records, such as the type
```
{n : Number ; p : Person}
```
The problem with parameter records is their double role.
They can be used like parameter values, as indices in selection,
```
VP.s ! {n = Sg ; p = P3}
```
but also as records, from which parameters can be projected:
```
{n = Sg ; p = P3}.n
```
Whichever use is selected as primary, a prohibitively complex
case expression must be generated at compilation to GFCC to get the
other use. The adopted
solution is to generate a pair containing both a parameter value index
and an array of indices of record fields. For instance, if we have
```
param Number = Sg | Pl ; Person = P1 | P2 | P3 ;
```
we get the encoding
```
{n = Sg ; p = P3} ---> (2 @ [0,2])
```
The GFCC computation rules are essentially
```
t [(i @ r)] = t[i]
(i @ r) [j] = r[j]
```
==Compiling to GFCC==
Compilation to GFCC is performed by the GF grammar compiler, and
GFCC interpreters need not know what it does. For grammar writers,
however, it might be interesting to know what happens to the grammars
in the process.
The compilation phases are the following
+ translate GF source to GFC, as always in GF
+ undo GFC back-end optimizations
+ perform the ``values`` optimization to normalize tables
+ create a symbol table mapping the GFC parameter and record types to
fixed-size arrays, and parameter values and record labels to integers
+ traverse the linearization rules replacing parameters and labels by integers
+ reorganize the created GFC grammar so that it has just one abstract syntax
and one concrete syntax per language
+ apply UTF8 encoding to the grammar, if not yet applied (this is told by the
``coding`` flag)
+ translate the GFC syntax tree to a GFCC syntax tree, using a simple
compositional mapping
+ perform the word-suffix optimization on GFCC linearization terms
+ perform subexpression elimination on each concrete syntax module
+ print out the GFCC code
Notice that a major part of the compilation is done within GFC, so that
GFC-related tasks (such as parser generation) could be performed by
using the old algorithms.
===Problems in GFCC compilation===
Two major problems had to be solved in compiling GFC to GFCC:
- consistent order of tables and records, to permit the array translation
- run-time variables in complex parameter values.
The current implementation is still experimental and may fail
to generate correct code. Any errors remaining are likely to be
related to the two problems just mentioned.
The order problem is solved in different ways for tables and records.
For tables, the ``values`` optimization of GFC already manages to
maintain a canonical order. But this order can be destroyed by the
``share`` optimization. To make sure that GFCC compilation works properly,
it is safest to recompile the GF grammar by using the ``values``
optimization flag.
Records can be canonically ordered by sorting them by labels.
In fact, this was done in connection of the GFCC work as a part
of the GFC generation, to guarantee consistency. This means that
e.g. the ``s`` field will in general no longer appear as the first
field, even if it does so in the GF source code. But relying on the
order of fields in a labelled record would be misplaced anyway.
The canonical form of records is further complicated by lock fields,
i.e. dummy fields of form ``lock_C = <>``, which are added to grammar
libraries to force intensionality of linearization types. The problem
is that the absence of a lock field only generates a warning, not
an error. Therefore a GFC grammar can contain objects of the same
type with and without a lock field. This problem was solved in GFCC
generation by just removing all lock fields (defined as fields whose
type is the empty record type). This has the further advantage of
(slightly) reducing the grammar size. More importantly, it is safe
to remove lock fields, because they are never used in computation,
and because intensional types are only needed in grammars reused
as libraries, not in grammars used at runtime.
While the order problem is rather bureaucratic in nature, run-time
variables are an interesting problem. They arise in the presence
of complex parameter values, created by argument-taking constructors
and parameter records. To give an example, consider the GF parameter
type system
```
Number = Sg | Pl ;
Person = P1 | P2 | P3 ;
Agr = Ag Number Person ;
```
The values can be translated to integers in the expected way,
```
Sg = 0, Pl = 1
P1 = 0, P2 = 1, P3 = 2
Ag Sg P1 = 0, Ag Sg P2 = 1, Ag Sg P3 = 2,
Ag Pl P1 = 3, Ag Pl P2 = 4, Ag Pl P3 = 5
```
However, an argument of ``Agr`` can be a run-time variable, as in
```
Ag np.n P3
```
This expression must first be translated to a case expression,
```
case np.n of {
0 => 2 ;
1 => 5
}
```
which can then be translated to the GFCC term
```
[2,5][$0[$1]]
```
assuming that the variable $np$ is the first argument and that its
$Number$ field is the second in the record.
This transformation of course has to be performed recursively, since
there can be several run-time variables in a parameter value:
```
Ag np.n np.p
```
A similar transformation would be possible to deal with the double
role of parameter records discussed above. Thus the type
```
RNP = {n : Number ; p : Person}
```
could be uniformly translated into the set ``{0,1,2,3,4,5}``
as ``Agr`` above. Selections would be simple instances of indexing.
But any projection from the record should be translated into
a case expression,
```
rnp.n ===>
case rnp of {
0 => 0 ;
1 => 0 ;
2 => 0 ;
3 => 1 ;
4 => 1 ;
5 => 1
}
```
To avoid the code bloat resulting from this, we chose the alias representation
which is easy enough to deal with in interpreters.
===Running the compiler and the GFCC interpreter===
GFCC generation is a part of the
[developers' version http://www.cs.chalmers.se/Cs/Research/Language-technology/darcs/GF/doc/darcs.html]
of GF since September 2006. To invoke the compiler, the flag
``-printer=gfcc`` to the command
``pm = print_multi`` is used. It is wise to recompile the grammar from
source, since previously compiled libraries may not obey the canonical
order of records. To ``strip`` the grammar before
GFCC translation removes unnecessary interface references.
Here is an example, performed in
[example/bronzeage ../../../../../examples/bronzeage].
```
i -src -path=.:prelude:resource-1.0/* -optimize=all_subs BronzeageEng.gf
i -src -path=.:prelude:resource-1.0/* -optimize=all_subs BronzeageGer.gf
strip
pm -printer=gfcc | wf bronze.gfcc
```
==The reference interpreter==
The reference interpreter written in Haskell consists of the following files:
```
-- source file for BNFC
GFCC.cf -- labelled BNF grammar of gfcc
-- files generated by BNFC
AbsGFCC.hs -- abstrac syntax of gfcc
ErrM.hs -- error monad used internally
LexGFCC.hs -- lexer of gfcc files
ParGFCC.hs -- parser of gfcc files and syntax trees
PrintGFCC.hs -- printer of gfcc files and syntax trees
-- hand-written files
DataGFCC.hs -- post-parser grammar creation, linearization and evaluation
GenGFCC.hs -- random and exhaustive generation, generate-and-test parsing
RunGFCC.hs -- main function - a simple command interpreter
```
It is included in the
[developers' version http://www.cs.chalmers.se/Cs/Research/Language-technology/darcs/GF/doc/darcs.html]
of GF, in the subdirectory [``GF/src/GF/Canon/GFCC`` ../].
To compile the interpreter, type
```
make gfcc
```
in ``GF/src``. To run it, type
```
./gfcc <GFCC-file>
```
The available commands are
- ``gr <Cat> <Int>``: generate a number of random trees in category.
and show their linearizations in all languages
- ``grt <Cat> <Int>``: generate a number of random trees in category.
and show the trees and their linearizations in all languages
- ``gt <Cat> <Int>``: generate a number of trees in category from smallest,
and show their linearizations in all languages
- ``gtt <Cat> <Int>``: generate a number of trees in category from smallest,
and show the trees and their linearizations in all languages
- ``p <Int> <Cat> <String>``: "parse", i.e. generate trees until match or
until the given number have been generated
- ``<Tree>``: linearize tree in all languages, also showing full records
- ``quit``: terminate the system cleanly
==Some things to do==
Interpreters in Java and C++.
Parsing via MCFG
- the FCFG format can possibly be simplified
- parser grammars should be saved in files to make interpreters easier
File compression of GFCC output.
Syntax editor based on GFCC.
Rewriting of resource libraries in order to exploit the
word-suffix sharing better (depth-one tables, as in FM).

View File

@@ -345,7 +345,6 @@ customMultiGrammarPrinter =
[
(strCI "gfcm", const MC.prCanon)
,(strCI "gfcc", const GFCC.prCanon2gfcc)
,(strCI "f_gfcc", const GFCC.prCanon2f_gfcc)
,(strCI "header", const (MC.prCanonMGr . unoptimizeCanon))
,(strCI "cfgm", prCanonAsCFGM)
,(strCI "graph", visualizeCanonGrammar)

View File

@@ -179,6 +179,7 @@ tools/$(GF_DOC_EXE): tools/GFDoc.hs
gfcc:
$(GHMAKE) $(GHCOPTFLAGS) -o gfcc GF/Canon/GFCC/RunGFCC.hs
strip gfcc
#
# Distribution