1grammar SimpleC;
2options {
3    output=AST;
4    language=ObjC;
5}
6
7tokens {
8    VAR_DEF;
9    ARG_DEF;
10    FUNC_HDR;
11    FUNC_DECL;
12    FUNC_DEF;
13    BLOCK;
14}
15
16program
17    :   declaration+
18    ;
19
20declaration
21    :   variable
22    |   functionHeader K_SEMICOLON -> ^(FUNC_DECL functionHeader)
23    |   functionHeader block -> ^(FUNC_DEF functionHeader block)
24    ;
25
26variable
27    :   type declarator K_SEMICOLON -> ^(VAR_DEF type declarator)
28    ;
29
30declarator
31    :   K_ID
32    ;
33
34functionHeader
35    :   type K_ID K_LCURVE ( formalParameter ( K_COMMA formalParameter )* )? K_RCURVE
36        -> ^(FUNC_HDR type K_ID formalParameter+)
37    ;
38
39formalParameter
40    :   type declarator -> ^(ARG_DEF type declarator)
41    ;
42
43type
44    :   K_INT_TYPE
45    |   K_CHAR
46    |   K_VOID
47    |   K_ID
48    ;
49
50block
51    :   lc=K_LCURLY
52            variable*
53            stat*
54        K_RCURLY
55        -> ^(BLOCK[$lc,@"BLOCK"] variable* stat*)
56    ;
57
58stat: forStat
59    | expr K_SEMICOLON!
60    | block
61    | assignStat K_SEMICOLON!
62    | K_SEMICOLON!
63    ;
64
65forStat
66    :   K_FOR K_LCURVE start=assignStat K_SEMICOLON expr K_SEMICOLON next=assignStat K_RCURVE block
67        -> ^(K_FOR $start expr $next block)
68    ;
69
70assignStat
71    :   K_ID K_EQ expr -> ^(K_EQ K_ID expr)
72    ;
73
74expr:   condExpr
75    ;
76
77condExpr
78    :   aexpr ( (K_EQEQ^ | K_LT^) aexpr )?
79    ;
80
81aexpr
82    :   atom ( K_PLUS^ atom )*
83    ;
84
85atom
86    : K_ID
87    | K_INT
88    | K_LCURVE expr K_RCURVE -> expr
89    ;
90
91K_FOR : 'for' ;
92K_CHAR: 'char';
93K_INT_TYPE : 'int' ;
94K_VOID: 'void';
95
96K_ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
97    ;
98
99K_INT :	anInt+=('0'..'9')+ {NSLog(@"\%@", $anInt);}
100    ;
101
102K_LCURVE : '(';
103K_RCURVE : ')';
104K_PLUS : '+' ;
105K_COMMA : ',';
106K_SEMICOLON : ';';
107K_LT   : '<' ;
108K_EQ   : '=' ;
109K_EQEQ : '==' ;
110K_LCURLY : '{';
111K_RCURLY : '}';
112
113WS  :   (   ' '
114        |   '\t'
115        |   '\r'
116        |   '\n'
117        )+
118        { $channel=HIDDEN; }
119    ;
120