xref: /aosp_15_r20/external/antlr/runtime/Cpp/tests/t018llstar.g (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1grammar t018llstar;
2
3options {
4    language =Cpp;
5}
6
7@lexer::includes
8{
9#include "UserTestTraits.hpp"
10}
11@lexer::namespace
12{ Antlr3Test }
13
14@parser::includes {
15#include "UserTestTraits.hpp"
16}
17@parser::namespace
18{ Antlr3Test }
19
20@header {
21from io import StringIO
22}
23
24@init {
25self.output = StringIO()
26}
27
28program
29    :   declaration+
30    ;
31
32/** In this rule, the functionHeader left prefix on the last two
33 *  alternatives is not LL(k) for a fixed k.  However, it is
34 *  LL(*).  The LL(*) algorithm simply scans ahead until it sees
35 *  either the ';' or the '{' of the block and then it picks
36 *  the appropriate alternative.  Lookhead can be arbitrarily
37 *  long in theory, but is <=10 in most cases.  Works great.
38 *  Use ANTLRWorks to see the lookahead use (step by Location)
39 *  and look for blue tokens in the input window pane. :)
40 */
41declaration
42    :   variable
43    |   functionHeader ';'
44	{self.output.write($functionHeader.name+" is a declaration\n")}
45    |   functionHeader block
46	{self.output.write($functionHeader.name+" is a definition\n")}
47    ;
48
49variable
50    :   type declarator ';'
51    ;
52
53declarator
54    :   ID
55    ;
56
57functionHeader returns [name]
58    :   type ID '(' ( formalParameter ( ',' formalParameter )* )? ')'
59	{$name = $ID.text}
60    ;
61
62formalParameter
63    :   type declarator
64    ;
65
66type
67    :   'int'
68    |   'char'
69    |   'void'
70    |   ID
71    ;
72
73block
74    :   '{'
75            variable*
76            stat*
77        '}'
78    ;
79
80stat: forStat
81    | expr ';'
82    | block
83    | assignStat ';'
84    | ';'
85    ;
86
87forStat
88    :   'for' '(' assignStat ';' expr ';' assignStat ')' block
89    ;
90
91assignStat
92    :   ID '=' expr
93    ;
94
95expr:   condExpr
96    ;
97
98condExpr
99    :   aexpr ( ('==' | '<') aexpr )?
100    ;
101
102aexpr
103    :   atom ( '+' atom )*
104    ;
105
106atom
107    : ID
108    | INT
109    | '(' expr ')'
110    ;
111
112ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
113    ;
114
115INT :	('0'..'9')+
116    ;
117
118WS  :   (   ' '
119        |   '\t'
120        |   '\r'
121        |   '\n'
122        )+
123        {$channel=HIDDEN}
124    ;
125