File: Test.g

package info (click to toggle)
frown 0.6.1-14
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 9,956 kB
  • ctags: 271
  • sloc: haskell: 35,132; makefile: 228; csh: 35; yacc: 23
file content (73 lines) | stat: -rw-r--r-- 2,213 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{-

The standard example: arithmetic expressions (see dragon book p222).

	frown --debug Test.g

Try
	expr (lexer "a+b*c+d") :: [Expr]

Tracing the parse:

	frown --debug --trace Expr.g

Try
	expr (lexer "a+b*c+d")

-}

module Test
where
import Char

data AddOp                    =  Plus  | Minus
                                 deriving (Show)
data MulOp                    =  Times | Divide
                                 deriving (Show)

data Expr                     =  Add Expr AddOp Expr
                              |  Mul Expr MulOp Expr
                              |  Id String
                                 deriving (Show)

type Result                   =  []

%{

Terminal                      =  IDENT {String}
                              |  ADDOP {AddOp}
                              |  MULOP {MulOp}
                              |  LPAR
                              |  RPAR
                              | *EOF;

Nonterminal                   = *expr {Expr}
                              |  term {Expr}
                              |  factor {Expr};

expr   {Add e1 op e2}         :  expr {e1}, ADDOP {op}, term {e2};
       {e}                    |  term {e};
term   {Mul e1 op e2}         :  term {e1}, MULOP {op}, factor {e2};
       {e}                    |  factor {e};
factor {e}                    :  LPAR, expr {e}, RPAR;
       {Id s}                 |  IDENT {s};

}%

frown ts                      =  fail "syntax error"

data Terminal                 =  IDENT String | ADDOP AddOp | MULOP MulOp | LPAR | RPAR | EOF
                                 deriving (Show)

lexer                         :: String -> [Terminal]
lexer []                      =  [EOF]
lexer ('+' : cs)              =  ADDOP Plus   : lexer cs
lexer ('-' : cs)              =  ADDOP Minus  : lexer cs
lexer ('*' : cs)              =  MULOP Times  : lexer cs
lexer ('/' : cs)              =  MULOP Divide : lexer cs
lexer ('(' : cs)              =  LPAR : lexer cs
lexer (')' : cs)              =  RPAR : lexer cs
lexer (c : cs)
    | isAlpha c               =  let (n, cs') = span isAlphaNum cs
                                 in  IDENT (c : n) : lexer cs'
    | otherwise               =  lexer cs