/** Simple statically-typed programming language with functions and variables
* taken from "Language Implementation Patterns" book.
*/
grammar Cymbol;
file: (functionDecl | varDecl)+ ;
varDecl
: type ID ('=' expr)? ';'
{/* System.out.print("var "+$ID.text+":"+$type.text+ " at line: " + $ID.line +";"); */}
{/* System.out.println(" at pos: " + $ID.pos +";"); */}
{/* System.out.println(" start: " + $start.getText() +";"); */ }
{/* System.out.println(" stop: " + $stop.getText() +";"); */ }
;
type: 'float' | 'int' | 'void' ; // user-defined types
functionDecl
: type ID '(' formalParameters? ')' block // "void f(int x) {...}"
{ System.out.print("function: "+$type.text+" "+ $ID.text + " ( "+$formalParameters.text + " )" ) ; }
{System.out.println(" block: " + $block.text +" ");}
{/* System.out.print(" start: "+$type.text+" "+ $ID.text + " ( "+$start.getText() + " )" ) ;*/}
{/* System.out.print(" at line: " + $ID.line +";");*/}
{/*System.out.println(" at pos: " + $ID.pos +";");*/}
;
formalParameters
: formalParameter (',' formalParameter)*
{ System.out.println(" -> formalParameter: " +" " + $formalParameter.text +";"); }
;
formalParameter
: type ID
{ System.out.print(" formalParameter: "+$type.text+" "+ $ID.text + "\n") ; }
;
block: '{' stat* '}' ; // possibly empty statement block
stat: block
| varDecl
| 'if' expr 'then' stat ('else' stat)?
| 'return' expr? ';'
| expr '=' expr ';' // assignment
| expr ';' // func call
;
expr: ID '(' exprList? ')' // func call like f(), f(x), f(1,2)
| ID '[' expr ']' // array index like a[i], a[i][j]
| '-' expr // unary minus
| '!' expr // boolean not
| expr '*' expr
| expr ('+'|'-') expr
| expr '==' expr // equality comparison (lowest priority op)
| ID // variable reference
| INT
| '(' expr ')'
;
exprList : expr (',' expr)* ; // arg list
ID : LETTER (LETTER | [0-9])* ;
fragment
LETTER : [a-zA-Z] ;
INT : [0-9]+ ;
WS : [ \t\n\r]+ -> skip ;
SL_COMMENT
: '//' .*? '\n' -> skip
;
The output is not according to expectations. It concatenates int and x giving intx. How to fix this.