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