/* Grammar voor vertalerbouw */ grammar Vnvd; options { k = 1; language = CSharp2; output = AST; } tokens { COLON = ':'; SEMICOLON = ';'; LPAREN = '('; RPAREN = ')'; COMMA = ','; PERIOD = '.'; LCURLYBRACE = '{'; RCURLYBRACE = '}'; LBRACKET = '['; RBRACKET = ']'; QUESTION = '?'; TILDE = '~'; DCOLON = '::'; BECOMES = '='; PLUS = '+'; MINUS = '-'; MULTIPLY = '*'; DIVISION = '/'; LE = '<'; LEQ = '<='; GE = '>'; GEQ = '>='; EQ = '=='; NEQ = '!='; AND = '&&'; OR = '||'; XOR = '^'; NOT = '!'; MOD = '%'; USING = 'import'; NAMESPACE = 'namespace'; CLASS = 'class'; INTERFACE = 'interface'; NEW = 'new'; STATIC = 'static'; VOID = 'void'; IF = 'if'; THEN = 'then'; ELSE = 'else'; WHILE = 'while'; FOR = 'for'; IN = 'in'; RETURN = 'return'; CONST = 'const'; TRUE = 'true'; FALSE = 'false'; BASE = 'base'; THIS = 'this'; METHOD = '~method~'; IMETHOD = '~imethod~'; FIELD = '~field~'; CONSTRUCTOR = '~constructor~'; DESTRUCTOR = '~destructor~'; LOCAL = '~local~'; EXTENDS = 'extends'; IMPLEMENTS = 'implements'; NEWARR = 'newarr'; FI = 'fi'; PRINT = 'print'; READ = 'read'; SET = 'set'; NULL = 'null'; AS = 'as'; TRY = 'try'; CATCH = 'catch'; CAREBOX = 'carebox'; FINALLY = 'finally'; THROW = 'throw'; // functions READ = 'read'; WRITE = 'write'; //modifiers PRIVATE = 'private'; PUBLIC = 'public'; PROTECTED = 'protected'; INTERNAL = 'internal'; ABSTRACT = 'abstract'; STATIC = 'static'; VIRTUAL = 'virtual'; OVERRIDE = 'override'; //imaginary tokens PROGRAM = '~program~'; VARDECL = '~vardecl~'; PARAMETER = '~par~'; ARGUMENT = '~arg~'; SLIST = '~slist~'; EOLIST = '~endoflist~'; EOSTRUCT = '~endofstructure~'; EODECL = '~endofdeclaration~'; CALL = '~call~'; LOAD = '~load~'; FQUALIFIER = '~fqualifier~'; EQUALIFIER = '~equalifier~'; MODIFIERS = '~modifiers~'; EXPRBLOCK = '~expression~'; USAGE = '~usage~'; SCOPEEXPR = '~scopeepxr~'; CAST = '~cast~'; ARRAY = '~array~'; READVOID = '~readvoid~'; WRITEVOID = '~writevoid~'; } @namespace { Vnvd.Antlr } @lexer::namespace { Vnvd.Antlr } program : import_stat* namespace_decl* EOF -> ^(PROGRAM import_stat* namespace_decl*) ; import_stat : USING qualifier SEMICOLON -> ^(USING qualifier) ; namespace_decl : NAMESPACE qualifier LCURLYBRACE namespace_body RCURLYBRACE -> ^(NAMESPACE qualifier namespace_body?) ; namespace_body : (namespace_decl | class_decl | interface_decl)* ; class_decl : CLASS mod=class_mod_list name=qualifier (EXTENDS base_=qualifier)? (IMPLEMENTS interface_=type_list)? class_body -> ^(CLASS ^(MODIFIERS $mod) $name ^(EXTENDS $base_)? ^(IMPLEMENTS $interface_)? class_body) ; interface_decl : INTERFACE mod=class_mod_list name=qualifier (EXTENDS base_=qualifier)? interface_body -> ^(INTERFACE ^(MODIFIERS $mod) $name ^(EXTENDS $base_)? interface_body) ; interface_body : LCURLYBRACE interface_method* RCURLYBRACE -> interface_method* ; interface_method : type_qualifier IDENTIFIER LPAREN parameter_list RPAREN SEMICOLON -> ^(IMETHOD type_qualifier IDENTIFIER parameter_list) ; class_mod_list : access_modifier (ABSTRACT)? ; method_mod_list : access_modifier (STATIC | virtual_modifier)? ; field_mod_list : access_modifier STATIC? ; constructor_mod_list : access_modifier ; abstract_mod_list : access_modifier ABSTRACT ; type_list : qualifier (COMMA! qualifier)* ; class_body : LCURLYBRACE! class_element* RCURLYBRACE! ; class_element : (method_mod_list type_qualifier IDENTIFIER LPAREN) => method_decl | (constructor_mod_list IDENTIFIER LPAREN) => constructor_decl | (abstract_mod_list) => abstract_method_decl | field_decl ; literal_value : NUMBER | STRING | CHAR | TRUE | FALSE | NULL ; field_decl : mod=field_mod_list qual=qualifier IDENTIFIER (COMMA IDENTIFIER)* SEMICOLON -> ^(FIELD ^(MODIFIERS $mod) $qual IDENTIFIER)+ ; method_decl : mod=method_mod_list type_qualifier IDENTIFIER LPAREN parameter_list RPAREN block_expression -> ^(METHOD ^(MODIFIERS $mod) type_qualifier IDENTIFIER parameter_list block_expression) ; abstract_method_decl : mod=abstract_mod_list type_qualifier IDENTIFIER LPAREN parameter_list RPAREN SEMICOLON -> ^(METHOD ^(MODIFIERS $mod) type_qualifier IDENTIFIER parameter_list) ; constructor_decl : mod=constructor_mod_list IDENTIFIER LPAREN parameter_list RPAREN (COLON BASE LPAREN argument_list RPAREN)? block_expression -> ^(CONSTRUCTOR ^(MODIFIERS $mod) IDENTIFIER parameter_list ^(BASE argument_list?)? block_expression) ; statement : (qualifier IDENTIFIER) => declaration_statement SEMICOLON! | const_decl_statement SEMICOLON! | expression SEMICOLON! | SEMICOLON! | control_statement ; control_statement : while_statement | for_statement | try_statement | throw_statement ; throw_statement : THROW expression SEMICOLON -> ^(THROW expression) ; try_statement : TRY block_expression (finally_block | (catch_block+ finally_block?)) -> ^(TRY block_expression catch_block* finally_block?) ; catch_block : (CATCH | CAREBOX) LPAREN qualifier IDENTIFIER RPAREN block_expression -> ^(CATCH ^(LOCAL qualifier IDENTIFIER) block_expression) ; finally_block : FINALLY block_expression -> ^(FINALLY block_expression) ; while_statement : WHILE LPAREN scope_expr RPAREN do_=block_expression -> ^(WHILE scope_expr $do_) ; for_statement : FOR LPAREN type_=qualifier IDENTIFIER IN expression RPAREN do_=block_expression -> ^(FOR ^(LOCAL $type_ IDENTIFIER) expression $do_) ; scope_expr : statement+ -> ^(SCOPEEXPR statement+) ; declaration_statement : type_=qualifier IDENTIFIER (COMMA IDENTIFIER)* -> ^(LOCAL $type_ IDENTIFIER)+ ; const_decl_statement : CONST qualifier IDENTIFIER BECOMES literal_value (COMMA IDENTIFIER BECOMES literal_value)* -> ^(CONST qualifier IDENTIFIER literal_value)+ ; object_creation_expression : NEW qualifier LPAREN argument_list RPAREN -> ^(NEW qualifier argument_list?) ; array_creation_expression : NEW qualifier LBRACKET expression RBRACKET -> ^(NEWARR qualifier expression) ; expression : assignment_expression ; assignment_expression : (t1=ternary_expression | NULL) (b=BECOMES^ t2=assignment_expression)? ; ternary_expression : IF LPAREN scope_expr RPAREN THEN expression (ELSE expression)? FI -> ^(IF scope_expr expression expression?) | logicoroperator_expression ; logicoroperator_expression : logicandoperator_expression (OR^ logicandoperator_expression)* ; logicandoperator_expression : logic_expression (AND^ logic_expression)* ; logic_expression : cast_as_expression ((LE^ | LEQ^ | GE^ | GEQ^ | EQ^ | NEQ^) cast_as_expression)* ; cast_as_expression : primary_expression (AS^ qualifier)* ; primary_expression : secundary_expression ((PLUS^ | MINUS^) secundary_expression)* ; secundary_expression : logicnotoperator_expression ((MULTIPLY^ | DIVISION^ | MOD^) logicnotoperator_expression )* ; logicnotoperator_expression : (NOT^ | PLUS^ | MINUS^)* cast_expression ; cast_expression : (LPAREN qualifier RPAREN cast_expression) => (LPAREN qualifier RPAREN cast_expression) -> ^(CAST qualifier cast_expression) | invocation_or_load_expression ; invocation_or_load_expression : operand ((DCOLON^ IDENTIFIER (LPAREN! argument_list RPAREN!)?) | (LBRACKET^ expression RBRACKET!))* ; operand : qualifier -> ^(USAGE qualifier) | NUMBER | FLOAT | STRING | CHAR | TRUE | FALSE | THIS | BASE | (NEW qualifier LPAREN) => object_creation_expression | (NEW qualifier LBRACKET) => array_creation_expression | (READ LPAREN IDENTIFIER RPAREN) => READ LPAREN IDENTIFIER RPAREN -> ^(READ IDENTIFIER) | READ LPAREN IDENTIFIER (COMMA IDENTIFIER)+ RPAREN -> ^(READVOID IDENTIFIER)+ | (WRITE LPAREN expression RPAREN) => WRITE LPAREN expression RPAREN -> ^(WRITE expression) | WRITE LPAREN expression (COMMA expression)+ RPAREN -> ^(WRITEVOID expression)+ | LPAREN expression RPAREN -> ^(EXPRBLOCK expression) | block_expression ; block_expression : LCURLYBRACE statement* RCURLYBRACE -> ^(SLIST statement*) ; parameter_list : (qualifier IDENTIFIER (COMMA qualifier IDENTIFIER)*)? -> ^(PARAMETER (qualifier IDENTIFIER)*) ; argument_list : (expression (COMMA expression)*)? -> ^(ARGUMENT expression)* ; type_qualifier : VOID | qualifier ; qualifier : (IDENTIFIER (PERIOD IDENTIFIER)* (LBRACKET RBRACKET)) => (IDENTIFIER (PERIOD IDENTIFIER)* (LBRACKET RBRACKET)) -> ^(FQUALIFIER IDENTIFIER+ ARRAY) | IDENTIFIER (PERIOD IDENTIFIER)* -> ^(FQUALIFIER IDENTIFIER+) ; access_modifier : PRIVATE | PUBLIC | PROTECTED | INTERNAL ; virtual_modifier : VIRTUAL | OVERRIDE ; // LEXER IDENTIFIER : (LETTER | '_') (LETTER | DIGIT | '_')* ; STRING : ('"' ('\\"' | ~'"')* '"') ; CHAR : '\'' (LETTER | DIGIT) '\'' ; NUMBER : (MINUS | PLUS)? DIGIT+ ; FLOAT : (MINUS | PLUS)? DIGIT+ '.' DIGIT+ ; COMMENT : '//' .* '\n' { $channel=HIDDEN; } | '/*' .* '*/' { $channel=HIDDEN; } ; WS : (' ' | '\t' | '\f' | '\r' | '\n')+ { $channel=HIDDEN; } ; fragment DIGIT : ('0'..'9') ; fragment LOWER : ('a'..'z') ; fragment UPPER : ('A'..'Z') ; fragment LETTER : LOWER | UPPER ;