/* ANTLR v3 Grammar for Objective Modula-2, status: October 4, 2009 * * Copyright (C) 2009 Benjamin Kowarsch. All rights reserved. * * License: * * Permission is hereby granted to review and test this software for the sole * purpose of supporting the effort by the licensor to define and develop the * Objective Modula-2 language. It is not permissible under any circumstances * to use the software for the purpose of creating derivative languages or * dialects. This permission is valid until 31 December 2009, 24:00h GMT. * * Future licensing: * * The licensor undertakes to eventually release this software under a proper * open source license AFTER the Objective Modula-2 language definition has * been finalised and a conforming and working reference compiler completed. * * More information about Objective Modula-2: * * http://objective.modula2.net * */ grammar objm2; // Objective Modula-2 // Note: An empty semantic action {} is used in lists of alternative terminals // in order to make ANTLRworks display the alternatives as separate branches. // A trailing comment /* extension */ is used within rules to indicate rules // or lines which represent Objective Modula-2 specific language extensions. options { // *** strict LL(1) *** backtrack = no; k = 1; } tokens { // *** Base Language Reserved Words, 42 tokens *** AND = 'AND'; ARRAY = 'ARRAY'; BEGIN = 'BEGIN'; BY = 'BY'; CASE = 'CASE'; CONST = 'CONST'; DEFINITION = 'DEFINITION'; DIV = 'DIV'; DO = 'DO'; ELSE = 'ELSE'; ELSIF = 'ELSIF'; END = 'END'; ENUM = 'ENUM'; EXIT = 'EXIT'; FOR = 'FOR'; FROM = 'FROM'; IF = 'IF'; IMMUTABLE = 'IMMUTABLE'; IMPLEMENTATION = 'IMPLEMENTATION'; IMPORT = 'IMPORT'; IN = 'IN'; IS = 'IS'; LOOP = 'LOOP'; MOD = 'MOD'; MODULE = 'MODULE'; NOT = 'NOT'; OF = 'OF'; OPAQUE = 'OPAQUE'; OR = 'OR'; POINTER = 'POINTER'; PROCEDURE = 'PROCEDURE'; RECORD = 'RECORD'; REPEAT = 'REPEAT'; RETURN = 'RETURN'; SET = 'SET'; THEN = 'THEN'; TO = 'TO'; TYPE = 'TYPE'; UNTIL = 'UNTIL'; VAR = 'VAR'; VARIADIC = 'VARIADIC'; WHILE = 'WHILE'; // *** Objective Modula-2 Reserved Words, 16 tokens *** BYCOPY = 'BYCOPY'; BYREF = 'BYREF'; CLASS = 'CLASS'; CONTINUE = 'CONTINUE'; CRITICAL = 'CRITICAL'; INOUT = 'INOUT'; METHOD = 'METHOD'; ON = 'ON'; OPTIONAL = 'OPTIONAL'; OUT = 'OUT'; PRIVATE = 'PRIVATE'; PROTECTED = 'PROTECTED'; PROTOCOL = 'PROTOCOL'; PUBLIC = 'PUBLIC'; SUPER = 'SUPER'; TRY = 'TRY'; // *** Base Language Defined Pragma Identifiers, 10 tokens *** IF = 'IF'; ELSIF = 'ELSIF'; ELSE = 'ELSE'; ENDIF = 'ENDIF'; INFO = 'INFO'; WARN = 'WARN'; ERROR = 'ERROR'; FATAL = 'FATAL'; INLINE = 'INLINE'; NOINLINE = 'NOINLINE'; // *** Objective Modula-2 Defined Pragma Identifiers, 4 tokens *** FRAMEWORK = 'FRAMEWORK'; IBACTION = 'IBAction'; IBOUTLET = 'IBOutlet'; QUALIFIED = 'QUALIFIED'; // *** Special Characters, 3 tokens *** BACKSLASH = '\\'; SINGLE_QUOTE = '\''; DOUBLE_QUOTE = '\"'; // *** Ignore Characters, 3 tokens *** ASCII_TAB = '\t'; ASCII_LF = '\n'; ASCII_CR = '\r'; } // --------------------------------------------------------------------------- // N O N - T E R M I N A L S Y M B O L S // --------------------------------------------------------------------------- // 72 productions, 22 aliases // *** Compilation Units *** // production #1 compilationUnit : programModule | definitionOfModule | implementationOfModule | protocolModule /* extension */ ; // production #2 programModule : MODULE moduleId ( '[' priority ']' )? ';' importList* block moduleId '.' ; // production #3 definitionOfModule : DEFINITION MODULE moduleId ';' importList* definition* END moduleId '.' ; // production #4 implementationOfModule : IMPLEMENTATION programModule ; // production #5 protocolModule : /* extension */ PROTOCOL protocolId ( '(' adoptedProtocols ')' )? ';' importList* ( OPTIONAL? methodHeader ';' )* END protocolId '.' ; // alias moduleId : ident ; // alias priority : constExpression ; // alias protocolId : ident ; // alias adoptedProtocols : identList ; // *** Import Lists, Blocks, Declarations, Definitions *** // production #6 importList : ( FROM moduleId IMPORT ( identList | '*' ) | IMPORT identList ) ';' ; // production #7 block : declaration* ( BEGIN statementSequence )? END ; // production #8 declaration : CONST ( constantDeclaration ';' )* | TYPE ( typeDeclaration ';' )* | VAR ( variableDeclaration ';' )* | procedureDeclaration ';' | methodDeclaration ';' /* extension */ ; // production #9 definition : CONST ( constantDeclaration ';' )* | TYPE ( ident ( '=' ( type | OPAQUE ) | IS namedType ) ';' )* | VAR ( variableDeclaration ';' )* | procedureHeader ';' | methodHeader ';' /* extension */ ; // *** Constant Declarations *** // production #10 constantDeclaration : ident '=' ( constExpression | structuredValue ) ; // *** Type Declarations *** // production #11 typeDeclaration : ident ( '=' type | IS namedType ) ; // production #12 type : namedType | anonymousType | enumerationType | setType | classType /* extension */ ; // alias namedType : qualident ; // production #13 anonymousType : arrayType | recordType | pointerType | procedureType ; // production #14 enumerationType : ENUM ( '(' baseType ')' )? identList? END | '(' identList ')' // simple notation ; // alias baseType : qualident ; // production #15 arrayType : ARRAY arrayIndex ( ',' arrayIndex )* OF ( namedType | recordType | procedureType ) ; // alias arrayIndex : ordinalConstExpression ; // alias ordinalConstExpression : constExpression ; // production #16 recordType : RECORD ( '(' baseType ')' )? fieldListSequence? END ; // production #17 fieldListSequence : fieldList ( ';' fieldList )* ; // production #18 fieldList : identList ':' ( namedType | arrayType | recordType | procedureType ) ; // production #19 classType : /* extension */ '<*QUALIFIED*>'? CLASS '(' superClass ( ',' adoptedProtocols )? ')' ( ( PUBLIC | MODULE | PROTECTED | PRIVATE {})? fieldListSequence )* END ; // alias superClass : qualident ; // production #20 setType : SET OF ( namedType | '(' identList ')' ) ; // production #21 pointerType : POINTER TO IMMUTABLE? namedType ; // production #22 procedureType : PROCEDURE ( '(' formalTypeList ')' )? ( ':' returnedType )? ; // production #23 formalTypeList : attributedFormalType ( ',' attributedFormalType )* ; // production #24 attributedFormalType : IMMUTABLE? VAR? formalType ; // production #25 formalType : ( ARRAY OF )? namedType ; // alias returnedType : namedType ; // *** Variable Declarations *** // production #26 variableDeclaration : ident ( '[' machineAddress ']' | ',' identList )? ':' ( namedType | anonymousType ) ; // alias machineAddress : constExpression ; // *** Procedure Declarations *** // production #27 procedureDeclaration : procedureHeader ';' block ident ; // production #28 procedureHeader : PROCEDURE ( '(' ident ':' receiverType ')' )? ident ( '(' formalParamList ')' )? ( ':' returnedType )? ; // alias receiverType : ident ; // production #29 formalParamList : formalParams ( ';' ( formalParams | variadicParams ) )* ; // production #30 formalParams : IMMUTABLE? VAR? identList ':' formalType ; // production 31 variadicParams : VARIADIC handle ( '[' indexParam ']' )? OF IMMUTABLE? VAR? ident ( ( '.' ident )* | ( ',' ident )* ':' formalType ) ; // alias handle : ident ; // alias indexParam : ident ; // *** Method Declarations *** // production #32 methodDeclaration : /* extension */ methodHeader ';' block ident ; // production #33 methodHeader : /* extension */ CLASS? METHOD '(' ident ':' ( receiverClass | '*' ) ')' ( ident | methodArg ) methodArg* ( ':' returnedType )? ; // alias receiverClass : qualident ; // production #34 methodArg : /* extension */ colonIdent '(' IMMUTABLE? VAR? ident ':' formalType ')' ; // *** Statements *** // production #35 statement : ( assignmentOrProcedureCall | methodInvocation | /* extension */ ifStatement | caseStatement | whileStatement | repeatStatement | loopStatement | forStatement | tryStatement | /* extension */ criticalStatement | /* extension */ RETURN expression? | EXIT )? ; // production #36 statementSequence : statement ( ';' statement )* ; // production #37 methodInvocation : /* extension */ '[' receiver message ']' ; // production #38 receiver : /* extension */ ident | methodInvocation ; // production #39 message : /* extension */ ident ( colonIdent expression )* | ( colonIdent expression )+ ; // production #40 assignmentOrProcedureCall : designator ( ':=' ( expression | structuredValue ) | '++' | '--' | actualParameters )? ; // production #41 ifStatement : IF expression THEN statementSequence ( ELSIF expression THEN statementSequence )* ( ELSE statementSequence )? END ; // production #42 caseStatement : CASE expression OF case ( '|' case )* ( ELSE statementSequence )? END ; // production #43 case : caseLabelList ':' statementSequence ; // production #44 caseLabelList : caseLabels ( ',' caseLabels )* ; // production #45 caseLabels : constExpression ( '..' constExpression )? ; // production #46 whileStatement : WHILE expression DO statementSequence END ; // production #47 repeatStatement : REPEAT statementSequence UNTIL expression ; // production #48 loopStatement : LOOP statementSequence END ; // production #49 forStatement : FOR ident ':=' expression TO expression ( BY constExpression )? DO statementSequence END ; // production #50 tryStatement : /* extension */ TRY statementSequence ON ident /* NSException */ DO statementSequence CONTINUE statementSequence END ; // production #51 criticalStatement : /* extension */ CRITICAL '(' classInstance ')' statementSequence END ; // alias classInstance : qualident ; // *** Expressions *** // production #52 constExpression : simpleConstExpr ( relation simpleConstExpr | '::' namedType )? ; // production #53 relation : '=' | '#' | '<' | '<=' | '>' | '>=' | IN | IS {} // make ANTLRworks display separate branches ; // production #54 simpleConstExpr : ( '+' | '-' {})? constTerm ( addOperator constTerm )* ; // production #55 addOperator : '+' | '-' | OR {} // make ANTLRworks display separate branches ; // production #56 constTerm : constFactor ( mulOperator constFactor )* ; // production #57 mulOperator : '*' | '/' | DIV | MOD | AND | '&' {} // make ANTLRworks display separate branches ; // production #58 constFactor : number | string | qualident | '(' constExpression ')' | ( NOT | '~' {}) constFactor ; // production #59 designator : qualident ( designatorTail )? ; // production #60 designatorTail : ( ( '[' expressionList ']' | '^' ) ( '.' ident )* )+ ; // production #61 expressionList : expression ( ',' expression )* ; // production #62 expression : simpleExpression ( relation simpleExpression | '::' namedType )? ; // production #63 simpleExpression : ( '+' | '-' {})? term ( addOperator term )* ; // production #64 term : factor ( mulOperator factor )* ; // production #65 factor : number | string | designatorOrProcedureCall | '(' expression ')' | ( NOT | '~' {}) factor | methodInvocation /* extension */ ; // production #66 designatorOrProcedureCall : qualident designatorTail? actualParameters? ; // production #67 actualParameters : '(' expressionList? ')' ; // *** Value Constructors *** // production #68 structuredValue : '{' ( valueComponent ( ',' valueComponent )* )? '}' ; // production #69 valueComponent : constExpression ( ( BY | '..' {}) constExpression )? | structuredValue ; // *** Identifiers *** // production #70 qualident : ident ( '.' ident )* ; // production #71 identList : ident ( ',' ident )* ; // alias ident : IDENT ; // alias colonIdent : COLON_IDENT ; // *** Literals *** // alias number : NUMBER ; // alias string : STRING ; // *** Pragmas *** // production #72 pragma : '<*' ( // conditional compilation pragmas ( IF | ELSIF {}) constExpression | ELSE | ENDIF | // console message pragmas ( INFO | WARN | ERROR | FATAL {}) compileTimeMessage | // other language defined pragmas INLINE | NOINLINE | // Objective Modula-2 specific pragmas FRAMEWORK | IBACTION | IBOUTLET | QUALIFIED |/* extension */ // implementation defined pragmas implementationDefinedPragma ( '+' | '-' | '=' ( ident | number ) )? ) '*>' ; // alias compileTimeMessage : string ; // alias implementationDefinedPragma : ident ; // --------------------------------------------------------------------------- // T E R M I N A L S Y M B O L S // --------------------------------------------------------------------------- // 10 productions // production #1 IDENT : ( '_' | '$' | LETTER ) ( '_' | '$' | LETTER | DIGIT )* ; // production #2 COLON_IDENT : /* extension */ IDENT ':' ; // production #3 NUMBER : // Decimal integer DIGIT+ | // Binary integer BINARY_DIGIT+ 'B' | // Sedecimal integer DIGIT SEDECIMAL_DIGIT* ( 'C' | 'H' {}) | // Real number DIGIT+ '.' DIGIT+ ( 'E' ( '+' | '-' {})? DIGIT+ )? ; // production #4 STRING : // Proper EBNF for STRING SINGLE_QUOTE ( CHARACTER | DOUBLE_QUOTE )* SINGLE_QUOTE | DOUBLE_QUOTE ( CHARACTER | SINGLE_QUOTE )* DOUBLE_QUOTE // // Alternative EBNF to make ANTLRworks display the diagram properly // SINGLE_QUOTE ( CHARACTER | DOUBLE_QUOTE | )+ SINGLE_QUOTE | // DOUBLE_QUOTE ( CHARACTER | SINGLE_QUOTE | )+ DOUBLE_QUOTE ; // production #5 fragment LETTER : 'A' .. 'Z' | 'a' .. 'z' {} // make ANTLRworks display separate branches ; // production #6 fragment DIGIT : BINARY_DIGIT | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' {} // make ANTLRworks display separate branches ; // production #7 fragment BINARY_DIGIT : '0' | '1' {} // make ANTLRworks display separate branches ; // production #8 fragment SEDECIMAL_DIGIT : DIGIT | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' {} // make ANTLRworks display separate branches ; // production #9 fragment CHARACTER : DIGIT | LETTER | // any printable characters other than single and double quote ' ' | '!' | '#' | '$' | '%' | '&' | '(' | ')' | '*' | '+' | ',' | '-' | '.' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | '[' | ']' | '^' | '_' | '`' | '{' | '|' | '}' | '~' | ESCAPE_SEQUENCE ; // production #10 fragment ESCAPE_SEQUENCE : BACKSLASH ( '0' | 'n' | 'r' | 't' | BACKSLASH | SINGLE_QUOTE | DOUBLE_QUOTE {}) ; // --------------------------------------------------------------------------- // I G N O R E S Y M B O L S // --------------------------------------------------------------------------- // 6 productions // *** Whitespace *** // production #1 WHITESPACE : ' ' | ASCII_TAB {} // make ANTLRworks display separate branches { $channel = HIDDEN; } // ignore ; // *** Comments *** // production #2 COMMENT : NESTABLE_COMMENT | NON_NESTABLE_COMMENT | SINGLE_LINE_COMMENT { $channel = HIDDEN; } // ignore ; // production #3 fragment NESTABLE_COMMENT : '(*' ( options { greedy=false; }: . )* // anything other than '(*' or '*)' NESTABLE_COMMENT* '*)' ; // production #4 fragment NON_NESTABLE_COMMENT : '/*' ( options { greedy=false; }: . )* // anything other than '*/' '*/' ; // production #5 fragment SINGLE_LINE_COMMENT : '//' ( options { greedy=false; }: . )* // anything other than EOL END_OF_LINE ; // production #6 fragment END_OF_LINE : ASCII_LF ASCII_CR? | ASCII_CR ASCII_LF? ; // END OF FILE