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