git @ Cat's Eye Technologies Fountain / 8513318
Parse locals. Needs tests. Chris Pressey 1 year, 10 months ago
6 changed file(s) with 23 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
8787
8888 So our "space" production looks something like:
8989
90 Space ::= <. local n = 0 .> { " " <. n += 1 .> } <. n > 0 .>
90 Space ::= local n: <. n = 0 .> { " " <. n += 1 .> } <. n > 0 .>
9191
9292 ### Implementation
9393
1515 grammar describe the concrete structure of tokens.
1616
1717 Grammar ::= {Production}.
18 Production ::= NonTerminal "::=" {Expr0}.
18 Production ::= NonTerminal "::=" {"local" Variable ":"} {Expr0}.
1919 Expr0 ::= Expr1 {"|" Expr1}.
2020 Expr1 ::= Term {Term}.
2121 Term ::= "{" Expr0 "}"
1717 Sequence.
1818
1919 Goal ::= "f" "o" "o";
20 ===> Grammar [("Goal",Alt [Seq [Terminal 'f',Terminal 'o',Terminal 'o']])]
20 ===> Grammar [("Goal",[],Alt [Seq [Terminal 'f',Terminal 'o',Terminal 'o']])]
2121
2222 Multi-character terminal.
2323
2424 Goal ::= "foo";
25 ===> Grammar [("Goal",Alt [Seq [Seq [Terminal 'f',Terminal 'o',Terminal 'o']]])]
25 ===> Grammar [("Goal",[],Alt [Seq [Seq [Terminal 'f',Terminal 'o',Terminal 'o']]])]
2626
2727 Alternation and recursion.
2828
2929 Goal ::= "(" Goal ")" | "0";
30 ===> Grammar [("Goal",Alt [Seq [Terminal '(',NonTerminal "Goal",Terminal ')'],Seq [Terminal '0']])]
30 ===> Grammar [("Goal",[],Alt [Seq [Terminal '(',NonTerminal "Goal",Terminal ')'],Seq [Terminal '0']])]
3131
3232 Repetition.
3333
3434 Goal ::= "(" {"0"} ")";
35 ===> Grammar [("Goal",Alt [Seq [Terminal '(',Loop (Alt [Seq [Terminal '0']]) [],Terminal ')']])]
35 ===> Grammar [("Goal",[],Alt [Seq [Terminal '(',Loop (Alt [Seq [Terminal '0']]) [],Terminal ')']])]
3636
3737 Constraints.
3838
4141 <. b = 0 .> { "b" <. b += 1 .> } <. b = n .>
4242 <. c = 0 .> { "c" <. c += 1 .> } <. c = n .>
4343 ;
44 ===> Grammar [("Goal",Alt [Seq [Constraint (Arb (Var "n")),Constraint (UnifyConst (Var "a") 0),Loop (Alt [Seq [Terminal 'a',Constraint (Inc (Var "a") 1)]]) [],Constraint (UnifyVar (Var "a") (Var "n")),Constraint (UnifyConst (Var "b") 0),Loop (Alt [Seq [Terminal 'b',Constraint (Inc (Var "b") 1)]]) [],Constraint (UnifyVar (Var "b") (Var "n")),Constraint (UnifyConst (Var "c") 0),Loop (Alt [Seq [Terminal 'c',Constraint (Inc (Var "c") 1)]]) [],Constraint (UnifyVar (Var "c") (Var "n"))]])]
44 ===> Grammar [("Goal",[],Alt [Seq [Constraint (Arb (Var "n")),Constraint (UnifyConst (Var "a") 0),Loop (Alt [Seq [Terminal 'a',Constraint (Inc (Var "a") 1)]]) [],Constraint (UnifyVar (Var "a") (Var "n")),Constraint (UnifyConst (Var "b") 0),Loop (Alt [Seq [Terminal 'b',Constraint (Inc (Var "b") 1)]]) [],Constraint (UnifyVar (Var "b") (Var "n")),Constraint (UnifyConst (Var "c") 0),Loop (Alt [Seq [Terminal 'c',Constraint (Inc (Var "c") 1)]]) [],Constraint (UnifyVar (Var "c") (Var "n"))]])]
4545
4646 ### Preprocessing
4747
5050 Sequence.
5151
5252 Goal ::= "f" "o" "o";
53 ===> Grammar [("Goal",Alt [Seq [Terminal 'f',Terminal 'o',Terminal 'o']])]
53 ===> Grammar [("Goal",[],Alt [Seq [Terminal 'f',Terminal 'o',Terminal 'o']])]
5454
5555 Alternation and recursion.
5656
5757 Goal ::= "(" Goal ")" | "0";
58 ===> Grammar [("Goal",Alt [Seq [Terminal '(',NonTerminal "Goal",Terminal ')'],Seq [Terminal '0']])]
58 ===> Grammar [("Goal",[],Alt [Seq [Terminal '(',NonTerminal "Goal",Terminal ')'],Seq [Terminal '0']])]
5959
6060 Repetition.
6161
6262 Goal ::= "(" {"0"} ")";
63 ===> Grammar [("Goal",Alt [Seq [Terminal '(',Loop (Alt [Seq [Terminal '0']]) [],Terminal ')']])]
63 ===> Grammar [("Goal",[],Alt [Seq [Terminal '(',Loop (Alt [Seq [Terminal '0']]) [],Terminal ')']])]
6464
6565 Goal ::= <. arb n .>
6666 <. a = 0 .> { "a" <. a += 1 .> } <. a = n .>
6767 <. b = 0 .> { "b" <. b += 1 .> } <. b = n .>
6868 <. c = 0 .> { "c" <. c += 1 .> } <. c = n .>
6969 ;
70 ===> Grammar [("Goal",Alt [Seq [Constraint (Arb (Var "n")),Constraint (UnifyConst (Var "a") 0),Loop (Alt [Seq [Terminal 'a',Constraint (Inc (Var "a") 1)]]) [UnifyVar (Var "a") (Var "n"),UnifyConst (Var "b") 0],Loop (Alt [Seq [Terminal 'b',Constraint (Inc (Var "b") 1)]]) [UnifyVar (Var "b") (Var "n"),UnifyConst (Var "c") 0],Loop (Alt [Seq [Terminal 'c',Constraint (Inc (Var "c") 1)]]) [UnifyVar (Var "c") (Var "n")]]])]
70 ===> Grammar [("Goal",[],Alt [Seq [Constraint (Arb (Var "n")),Constraint (UnifyConst (Var "a") 0),Loop (Alt [Seq [Terminal 'a',Constraint (Inc (Var "a") 1)]]) [UnifyVar (Var "a") (Var "n"),UnifyConst (Var "b") 0],Loop (Alt [Seq [Terminal 'b',Constraint (Inc (Var "b") 1)]]) [UnifyVar (Var "b") (Var "n"),UnifyConst (Var "c") 0],Loop (Alt [Seq [Terminal 'c',Constraint (Inc (Var "c") 1)]]) [UnifyVar (Var "c") (Var "n")]]])]
1818 deriving (Show, Ord, Eq)
1919
2020
21 data Grammar = Grammar [(NTName, Expr)]
21 data Grammar = Grammar [(NTName, [Variable], Expr)]
2222 deriving (Show, Ord, Eq)
2323
24 startSymbol (Grammar ((term, _) : _)) = term
24 startSymbol (Grammar ((term, _, _) : _)) = term
2525
26 production nt (Grammar ((term, expr) : rest)) =
26 production nt (Grammar ((term, locals, expr) : rest)) =
2727 if term == nt then expr else production nt (Grammar rest)
1313 prod = do
1414 nt <- capWord
1515 keyword "::="
16 l <- many local
1617 e <- expr0
1718 keyword ";"
18 return (nt, e)
19 return (nt, l, e)
20
21 local = do
22 keyword "local"
23 v <- variable
24 keyword ":"
25 return v
1926
2027 expr0 = do
2128 es <- sepBy (expr1) (keyword "|")
88 preprocessGrammar :: Grammar -> Grammar
99 preprocessGrammar (Grammar productions) =
1010 let
11 productions' = map (\(term, expr) -> (term, preprocessExpr expr)) productions
11 productions' = map (\(term, locals, expr) -> (term, locals, preprocessExpr expr)) productions
1212 in
1313 Grammar productions'
1414