summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhallgren <hallgren@chalmers.se>2013-11-11 16:50:43 +0000
committerhallgren <hallgren@chalmers.se>2013-11-11 16:50:43 +0000
commitb111b476a75577a5b21d1d498975cbb2eeed9324 (patch)
tree07c26d17b01843854dc5d48a10e86d99a1bf8e3b
parent47e04656fb11c39ec9cbbfd7c860cd992d4855d2 (diff)
Fix Issue 41: "," in context-free rules causes parsing failure
The CF parser in GF.Grammar.CF assigns function names to the rules, but they are not always unique, causing rules to be dropped in the follwing CF->GF conversion. So a pass has been added before the CF->GF conversion, to make sure that function names are unique. A comment says "rules have an amazingly easy parser", but the parser looks like quick hack. It is very sloppy and silently ignores many errors, e.g. - Explicitly given function names should end with '.', but if the do not, the last character in the function name is silently dropped. - Everything following a ';' is silently dropped.
-rw-r--r--src/compiler/GF/Grammar/CF.hs18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/compiler/GF/Grammar/CF.hs b/src/compiler/GF/Grammar/CF.hs
index 123d843bf..fe76d7af8 100644
--- a/src/compiler/GF/Grammar/CF.hs
+++ b/src/compiler/GF/Grammar/CF.hs
@@ -23,12 +23,13 @@ import GF.Infra.UseIO
import GF.Data.Operations
import GF.Data.Utilities (nub')
+import qualified Data.Set as S
import Data.Char
import Data.List
--import System.FilePath
getCF :: FilePath -> String -> Err SourceGrammar
-getCF fpath = fmap (cf2gf fpath) . pCF
+getCF fpath = fmap (cf2gf fpath . uniqueFuns) . pCF
---------------------
-- the parser -------
@@ -77,6 +78,21 @@ type CFItem = Either CFCat String
type CFCat = String
type CFFun = String
+
+--------------------------------
+-- make function names unique --
+--------------------------------
+
+uniqueFuns :: CF -> CF
+uniqueFuns = snd . mapAccumL uniqueFun S.empty
+ where
+ uniqueFun funs (L l (fun,rule)) = (S.insert fun' funs,L l (fun',rule))
+ where
+ fun' = head [fun'|suffix<-"":map show ([2..]::[Int]),
+ let fun'=fun++suffix,
+ not (fun' `S.member` funs)]
+
+
--------------------------
-- the compiler ----------
--------------------------