grammar oberon2; options { language = Java; output = AST; ASTLabelType = CommonTree; //memoize = true; } @lexer::header { package ru.msu.cmc.sp.oberon2; } @header { package ru.msu.cmc.sp.oberon2; import java.io.*; import org.antlr.runtime.*; import java.util.Map; import java.util.TreeMap; } @members { public static void main(String[] args) throws Exception { oberon2Lexer lex = new oberon2Lexer(new ANTLRInputStream(System.in)); CommonTokenStream tokens = new CommonTokenStream(lex); oberon2Parser parser = new oberon2Parser(tokens); try { parser.module(); } catch (RecognitionException e) { e.printStackTrace(); System.exit(1); } } } STAR : '*' ; DOT : '.' ; EQUAL : '=' ; COMMA : ',' ; SEMICOLON : ';' ; LPAREN : '(' ; RPAREN : ')' ; COLON : ':' ; DOTDOT : '..' ; LBR : '[' ; RBR : ']' ; REF : '^' ; LBRACE : '{' ; RBRACE : '}' ; NEQUAL : '#' ; LESS : '<' ; LEQ : '<=' ; GREATER : '>' ; GEQ : '>=' ; PLUS : '+' ; MINUS : '-' ; SLASH : '/' ; AMP : '&' ; TILDE : '~' ; STROKE : '|' ; ASSIGN : ':=' ; IDENT : LETTER (LETTER | DIGIT)* ; WHITESPACE: (' ' | '\t' )+ { skip(); }; SINGLE_COMMENT: '//' ~('\r' | '\n')* NEWLINE { skip(); }; NEWLINE: ('\r'? '\n')+ { skip(); }; ML_COMMENT options { greedy = false; } : '/*' .* '*/' NEWLINE? { skip(); }; DIGIT : '0' .. '9' ; fragment LETTER : 'A' .. 'Z' | 'a' .. 'z' | '_' ; STRING: ('"' (options { greedy = false; } : ~('"'))* '"') | ('\'' (options { greedy = false; } : ~('\''))* '\'') ; fragment HEXDIGIT : ('0' .. '9' | 'A'..'F' | 'a' .. 'f') ; fragment INTNUM options { backtrack = true; } : DIGIT+ | (DIGIT HEXDIGIT* 'H') ; fragment NUM_FLOAT : DIGIT+ DOT (DIGIT)* F_ORDER?; F_ORDER: ('E' | 'D') (PLUS | MINUS)? DIGIT+; NUMBER options { backtrack = true; } : INTNUM | NUM_FLOAT; CharConstant : DIGIT (HEXDIGIT)* 'X'; module : 'MODULE' IDENT SEMICOLON (importList)? declarationSequence ('BEGIN' statementSequence)? 'END' IDENT DOT ; identdef : IDENT (STAR | MINUS)? ; qualident options { backtrack = true; }: (IDENT DOT)? IDENT; constantDeclaration : identdef EQUAL constExpression; constExpression : expression; typeDeclaration : identdef EQUAL type; type : qualident | arrayType | recordType | pointerType | procedureType; arrayType : 'ARRAY' length (COMMA length)* 'OF' type; length : constExpression; recordType : 'RECORD' (LPAREN baseType RPAREN)? fieldListSequence 'END'; baseType : qualident; fieldListSequence : fieldList (SEMICOLON fieldList)*; fieldList : (identList COLON type)?; identList : identdef (COMMA identdef)*; pointerType : 'POINTER' 'TO' type; procedureType : 'PROCEDURE' (formalParameters)?; variableDeclaration : identList COLON type; designator : qualident (DOT IDENT | LBR expList RBR | LPAREN qualident RPAREN | REF )*; expList : expression (COMMA expression)*; expression : simpleExpression (relation simpleExpression)?; relation : EQUAL | NEQUAL | LESS | LEQ | GREATER | GEQ | 'IN' | 'IS'; simpleExpression : (PLUS|MINUS)? term (addOperator term)*; addOperator : PLUS | MINUS | 'OR' ; term : factor (mulOperator factor)*; mulOperator : STAR | SLASH | 'DIV' | 'MOD' | AMP ; factor : NUMBER | CharConstant | STRING | 'NIL' | set | designator (actualParameters)? | LPAREN expression RPAREN | TILDE factor; set : LBRACE (element (COMMA element)*)? RBRACE; element : expression (DOTDOT expression)?; actualParameters : LPAREN (expList)? RPAREN ; statement options { backtrack=true; } : (assignmentOrProcedureCall | forStatement | ifStatement | caseStatement | whileStatement | repeatStatement | loopStatement | withStatement | 'EXIT' | 'RETURN' (expression)? )?; assignmentOrProcedureCall : designator (ASSIGN expression | (actualParameters)?); assignment : designator ASSIGN expression; procedureCall : designator (actualParameters)?; statementSequence : statement (SEMICOLON statement)*; ifStatement : 'IF' expression 'THEN' statementSequence ('ELSIF' expression 'THEN' statementSequence)* ('ELSE' statementSequence)? 'END'; obcase : (caseLabelList COLON statementSequence)?; caseLabelList : caseLabels (COMMA caseLabels)*; caseStatement : 'CASE' expression 'OF' obcase (STROKE obcase)* ('ELSE' statementSequence)? 'END'; caseLabels : constExpression (DOTDOT constExpression)?; whileStatement : 'WHILE' expression 'DO' statementSequence 'END'; repeatStatement : 'REPEAT' statementSequence 'UNTIL' expression; loopStatement : 'LOOP' statementSequence 'END'; withStatement : 'WITH' qualident COLON qualident 'DO' statementSequence 'END' ; forStatement : 'FOR' designator ASSIGN expression 'TO' expression ('BY' expression)? 'DO' statementSequence 'END' ; procedureDeclaration : procedureHeading SEMICOLON procedureBody IDENT; procedureHeading : 'PROCEDURE' (STAR)? identdef (formalParameters)?; procedureBody : declarationSequence ('BEGIN' statementSequence)? 'END'; forwardDeclaration : 'PROCEDURE' REF IDENT (STAR)? (formalParameters)?; declarationSequence : ('CONST' (constantDeclaration SEMICOLON)* | 'TYPE' (typeDeclaration SEMICOLON)* | 'VAR' (variableDeclaration SEMICOLON)*)* (procedureDeclaration SEMICOLON | forwardDeclaration SEMICOLON)*; formalParameters : LPAREN (fPSection (SEMICOLON fPSection)*)? RPAREN (COLON qualident)?; fPSection : ('VAR')? IDENT (COMMA IDENT)* COLON formalType; formalType : ('ARRAY' 'OF')* (qualident | procedureType); importList : 'IMPORT' obimport (COMMA obimport)* SEMICOLON ; obimport : IDENT (ASSIGN IDENT)?;