grammar SampleC; options{ output = AST; ASTLabelType = CommonTree; } tokens{ PROGRAM; FUNC; FUNCPAR; PARDEF; VARDEF; BLOCK; ASSIGN; CALL; NOT; NEGATE; ARG; NUM; VAR; PREFIX; NOP; CLEAR; ALU_ADD; ALU_SUB; ALU_MUL; ALU_DIV; ALU_LT; ALU_GT; ALU_LE; ALU_GE; ALU_EQ; ALU_NE; ALU_AND; ALU_OR; ALU_XOR; INT; VOID; IF; WHILE; EXPR; } program : ( d=definition { if ($d.tree != null) System.out.println($d.tree.toStringTree());} )+ -> ^(PROGRAM definition+ ^(CALL {adaptor.create(IDENTIFIER,"main")} ^(ARG))) ; definition : functionDefintion -> functionDefintion | declaration -> declaration ; functionDefintion : funcType IDENTIFIER '(' parameterList ')' parameterDeclarations compoundStatement -> ^(FUNC funcType IDENTIFIER ^(FUNCPAR parameterList) parameterDeclarations compoundStatement) ; funcType : type -> type | -> INT ; parameterList : (IDENTIFIER (',' IDENTIFIER)*)? -> IDENTIFIER* ; parameterDeclarations : parameterDeclaration* -> ^(PARDEF parameterDeclaration*) ; parameterDeclaration : (t=type id=IDENTIFIER -> ^(VARDEF $t $id) ) (',' (id=IDENTIFIER) -> $parameterDeclaration ^(VARDEF $t $id) )* ';' ; compoundStatement : '{' declarations statements '}' -> ^(BLOCK declarations statements) ; declarations : declaration* ; declaration : (t=type id=IDENTIFIER -> ^(VARDEF $t $id) ) (',' (id=IDENTIFIER) -> $declaration ^(VARDEF $t $id) )* ';' ; statements : statement* ; statement options { backtrack=true; } : e=expression ';' -> ^(EXPR $e CLEAR) | ';' -> NOP | BREAK -> BREAK | CONTINUE -> CONTINUE | RETURN ';' -> RETURN | RETURN e=expression ';' -> ^(RETURN $e) | c=compoundStatement -> $c | ifstm -> ifstm | 'while' '(' e=expression ')' s=statement -> ^(WHILE $e $s) ; ifstm options{ backtrack=true; } : 'if' '(' e=expression ')' s1=statement ELSE s2=statement -> ^(IF $e $s1 $s2) | 'if' '(' e=expression ')' s1=statement -> ^(IF $e $s1 NOP) ; expression : binary -> binary ; binary : i=IDENTIFIER '=' e=expression -> ^(ASSIGN $i $e) | IDENTIFIER PE e=expression -> ^(ASSIGN IDENTIFIER ^(ALU_ADD IDENTIFIER $e)) | IDENTIFIER ME e=expression -> ^(ASSIGN IDENTIFIER ^(ALU_SUB IDENTIFIER $e)) | IDENTIFIER TE e=expression -> ^(ASSIGN IDENTIFIER ^(ALU_MUL IDENTIFIER $e)) | IDENTIFIER DE e=expression -> ^(ASSIGN IDENTIFIER ^(ALU_DIV IDENTIFIER $e)) | equalityExpr -> equalityExpr ; equalityExpr : comparisonExpr (eqOp^ comparisonExpr)* ; eqOp : '==' -> ALU_EQ | ('!=' | '<>') -> ALU_NE ; comparisonExpr : additiveExpr (compOp^ additiveExpr)* ; compOp : '>' -> ALU_GT | '<' -> ALU_LT | '<=' -> ALU_LE | '>=' -> ALU_GE ; additiveExpr : multiplicativeExpr (addOp^ multiplicativeExpr)* ; addOp : '+' -> ALU_ADD | '-' -> ALU_SUB ; multiplicativeExpr : bitExpr (mulOp^ bitExpr)* ; mulOp : '*' -> ALU_MUL | '/' -> ALU_DIV ; bitExpr : notExpr (bitOp^ notExpr)* ; bitOp : '&' -> ALU_AND | '|' -> ALU_OR | '^' -> ALU_XOR ; notExpr : op='!'? negationExpr -> {$op != null}? ^(NOT negationExpr) -> negationExpr ; negationExpr : op='-'? primary -> {$op != null}? ^(NEGATE primary) -> primary ; primary : atom | '('! expression ')'! ; atom : IDENTIFIER -> IDENTIFIER | PP IDENTIFIER -> ^(PREFIX IDENTIFIER PP) | MM IDENTIFIER -> ^(PREFIX IDENTIFIER MM) | CONSTANT -> CONSTANT | IDENTIFIER '(' a=argumentList ')' -> ^(CALL IDENTIFIER $a) ; argumentList : (expression (',' expression)*)? -> ^(ARG expression*) ; type : 'int' -> INT ; BREAK : 'break' ; CONTINUE : 'continue' ; RETURN : 'return' ; ELSE : 'else' ; PP : '++' ; MM : '--' ; PE : '+=' ; ME : '-=' ; TE : '*=' ; DE : '/=' ; IDENTIFIER : ('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z'|'0'..'9')* ; CONSTANT : '0'..'9'+ ; WS : (' '|'\t'|'\r'|'\n')+ {skip();} ;