options { UNICODE_INPUT = true; ERROR_REPORTING = true; USER_CHAR_STREAM = true; STATIC = false; JDK_VERSION = "1.5"; FORCE_LA_CHECK = true; } PARSER_BEGIN(XampilParser) package org.codecover.instrumentation.xampil.parser; public class XampilParser { private InstrumentableItemCounter counter = new InstrumentableItemCounter(); static interface IntegerContainer { public void set(int value); public int get(); } static class RealIntegerContainer implements IntegerContainer { int value = 0; public void set(int value) { this.value = value; } public int get() { return this.value; } } static class DummyIntegerContainer implements IntegerContainer { public void set(int value) {} public int get() { return 0; } } static final DummyIntegerContainer DUMMY_CONTAINER = new DummyIntegerContainer(); } PARSER_END(XampilParser) /* * TOKENS */ SPECIAL_TOKEN : { < SPACE_CHAR: " " | "\t" | "\f" > } SPECIAL_TOKEN : { < SINGLE_LINE_COMMENT: "//" (~["\n", "\r"])* ("\n" | "\r" | "\n\r")? > } TOKEN : { < EOL: ("\n" | "\r" | "\n\r") ("\n" | "\r" | "\n\r" | " " | "\t" | "\f")* > } TOKEN : { < DECLARATION: "DECLARATION" > | < PROGRAM: "PROGRAM" > | < ENDPROGRAM: "ENDPROGRAM" > | < BOOLEAN: "BOOLEAN" > | < INTEGER: "INTEGER" > | < STRING: "STRING" > | < IF: "IF" > | < THEN: "THEN" > | < ELSE: "ELSE" > | < ENDIF: "ENDIF" > | < WHILE: "WHILE" > | < DO: "DO" > | < ENDWHILE: "ENDWHILE" > | < SWITCH: "SWITCH" > | < CASE: "CASE" > | < CASE_DEFAULT: "DEFAULT" > | < ENDCASE: "ENDCASE" > | < ENDSWITCH: "ENDSWITCH" > | < FILE: "FILE" > | < OVERWRITE: "OVERWRITE" > | < APPEND: "APPEND" > | < AND: "AND" > | < OR: "OR" > | < NOT: "NOT" > | < TRUE: "TRUE" > | < FALSE: "FALSE" > } TOKEN : { < LPAREN: "(" > | < RPAREN: ")" > | < COLON: ":" > | < ASSIGN: ":=" > | < EQ: "=" > | < NEQ: "<>" > | < LT: "<" > | < GT: ">" > | < LE: "<=" > | < GE: ">=" > | < PLUS: "+" > | < MINUS: "-" > | < STAR: "*" > | < SLASH: "/" > } TOKEN : { < IDENTIFIER: ( ["a"-"z"] | ["A"-"Z"] ) ( ["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | "_" )* > } TOKEN : { < INTEGER_LITERAL: ( ( )? ["1"-"9"] (["0"-"9"])* ) | "0" > | < STRING_LITERAL: "\"" ( ( ~["\"","\\","\n","\r"] ) | ( "\\" ["n", "t", "b", "r", "f", "\\", "'", "\""] ) )* "\"" > } /* * SYNTAX */ void CompilationUnit(InstrumentableItemCounter counter): { this.counter = counter; } { Declaration() Program() ( )? { // finished this parsing -> create a new counter // to avoid incrementing of the old counter // at the next parsing this.counter = new InstrumentableItemCounter(); } } void Declaration(): {} { ( SimpleDeclaration() )* } void SimpleDeclaration(): {} { ( | | ) ( ( | | | ) ) ? } void Program(): {} { ( Statement() )* } void Statement(): { // found a statement this.counter.incrementStatementCount(); } { AssignmentStatement() | IfStatement() | WhileStatement() | SwitchStatement() | FileStatement() } void AssignmentStatement(): {} { Expression(DUMMY_CONTAINER) } void IfStatement(): { RealIntegerContainer basicBooleanCounter = new RealIntegerContainer(); } { Expression(basicBooleanCounter) { this.counter.incrementConditionCount(basicBooleanCounter.get()); } { // found a branch this.counter.incrementBranchCount(); } ( Statement() )* ( { // found another branch this.counter.incrementBranchCount(); } ( Statement() )* )? } void WhileStatement(): { this.counter.incrementLoopCount(); RealIntegerContainer basicBooleanCounter = new RealIntegerContainer(); } { Expression(basicBooleanCounter) { this.counter.incrementConditionCount(basicBooleanCounter.get()); } ( Statement() )* } void SwitchStatement(): {} { ( Expression(DUMMY_CONTAINER) ( )? { // found a branch this.counter.incrementBranchCount(); } ( Statement() )* )+ ( ( )? { // found a branch this.counter.incrementBranchCount(); } ( Statement() )* )? } void FileStatement(): {} { ( | ) ( | ) Expression(DUMMY_CONTAINER) } void Expression(IntegerContainer basicBooleanCounter): {} { OrExpression(basicBooleanCounter) } void OrExpression(IntegerContainer basicBooleanCounter): {} { AndExpression(basicBooleanCounter) ( AndExpression(basicBooleanCounter) )* } void AndExpression(IntegerContainer basicBooleanCounter): {} { NotExpression(basicBooleanCounter) ( NotExpression(basicBooleanCounter) )* } void NotExpression(IntegerContainer basicBooleanCounter): {} { ( )? EqualityExpression(basicBooleanCounter) } void EqualityExpression(IntegerContainer basicBooleanCounter): { int basicBooleanCountBefore = basicBooleanCounter.get(); } { RelationalExpression(basicBooleanCounter) ( ( | ) RelationalExpression(basicBooleanCounter) { basicBooleanCounter.set(basicBooleanCountBefore + 1); } ) ? } void RelationalExpression(IntegerContainer basicBooleanCounter): { int basicBooleanCountBefore = basicBooleanCounter.get(); } { AdditiveExpression(basicBooleanCounter) ( ( | | | ) AdditiveExpression(basicBooleanCounter) { basicBooleanCounter.set(basicBooleanCountBefore + 1); } )? } void AdditiveExpression(IntegerContainer basicBooleanCounter): { int basicBooleanCountBefore = basicBooleanCounter.get(); } { MultiplicativeExpression(basicBooleanCounter) ( ( | ) MultiplicativeExpression(basicBooleanCounter) { basicBooleanCounter.set(basicBooleanCountBefore + 1); } )* } void MultiplicativeExpression(IntegerContainer basicBooleanCounter): { int basicBooleanCountBefore = basicBooleanCounter.get(); } { BasicExpression(basicBooleanCounter) ( ( | ) BasicExpression(basicBooleanCounter) { basicBooleanCounter.set(basicBooleanCountBefore + 1); } )* } void BasicExpression(IntegerContainer basicBooleanCounter): {} { { basicBooleanCounter.set(basicBooleanCounter.get() + 1); } | | | | | Expression(basicBooleanCounter) }