v 0.2
Instructions
> ghci Main.hs
> main
Sample input
a = b + c
b = 1 * 2 + 3 * 4
c = 5 - 6 - 7
Sample output
Success (Node Definition
+-- Leaf (TSymbol "a")
+-- Leaf (TKeyword "=")
`-- Node FunCall
+-- Leaf (TSymbol "+")
+-- Leaf (TSymbol "b")
`-- Leaf (TSymbol "c")
,[])
`-- Success (Node Definition
+-- Leaf (TSymbol "b")
+-- Leaf (TKeyword "=")
`-- Node FunCall
+-- Leaf (TSymbol "+")
+-- Node FunCall
| +-- Leaf (TSymbol "*")
| +-- Leaf (TValue (VInt 1))
| `-- Leaf (TValue (VInt 2))
`-- Node FunCall
+-- Leaf (TSymbol "*")
+-- Leaf (TValue (VInt 3))
`-- Leaf (TValue (VInt 4))
,[])
Success (Node Definition
+-- Leaf (TSymbol "c")
+-- Leaf (TKeyword "=")
`-- Node FunCall
+-- Leaf (TSymbol "-")
+-- Node FunCall
| +-- Leaf (TSymbol "-")
| +-- Leaf (TValue (VInt 5))
| `-- Leaf (TValue (VInt 6))
`-- Leaf (TValue (VInt 7))
,[])
Parser definition exerpt
pDefinition :: FunParser
pDefinition [] = Failure "Nothing to parse"
pDefinition toks = p_seq Definition [pSymbol, pKeyword "=", pExpr] toks
pSymbol :: FunParser
pSymbol (t:ts) = case t of
TSymbol _ -> Success (leaf t, ts)
otherwise -> Failure "Symbol expected."
pKeyword :: String -> FunParser
pKeyword key (t:ts) = case t of
TKeyword k | k == key -> Success (leaf t, ts)
otherwise -> Failure (key ++ " expected instead of " ++ show t)
...
Remarks
- spaces are important, they delimit the tokens
- things like "@%*!" are valid symbols (try it!)
- the tokenizer is fairly advanced
- the parser looses source location information
- straightforward to add new operators and priorities, efficient parsing ...but the code is a bit tricky