/* 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'; RETURN = 'return'; CONST = 'const'; TRUE = 'true'; FALSE = 'false'; BASE = 'base'; THIS = 'this'; METHOD = 'method'; FIELD = 'field'; CONSTRUCTOR = 'constructor'; DESTRUCTOR = 'destructor'; LOCAL = 'local'; EXTENDS = 'extends'; IMPLEMENTS = 'implements'; NEWARR = 'newarr'; FI = 'fi'; PRINT = 'print'; READ = 'read'; SET = 'set'; //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~'; } 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 -> ^(METHOD type_qualifier IDENTIFIER parameter_list) ; class_mod_list : access_modifier STATIC? 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_decl | constructor_decl | destructor_decl | field_decl | (METHOD abstract_mod_list) => abstract_method_decl ; literal_value : NUMBER | STRING | CHAR | TRUE | FALSE ; field_decl : FIELD mod=field_mod_list qualifier IDENTIFIER SEMICOLON -> ^(FIELD ^(MODIFIERS $mod) qualifier IDENTIFIER) ; method_decl : METHOD 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 : METHOD mod=abstract_mod_list type_qualifier IDENTIFIER LPAREN parameter_list RPAREN SEMICOLON -> ^(METHOD ^(MODIFIERS $mod) type_qualifier IDENTIFIER parameter_list) ; constructor_decl : CONSTRUCTOR 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) ; destructor_decl : DESTRUCTOR LPAREN RPAREN block_expression -> ^(DESTRUCTOR block_expression) ; statement : expression SEMICOLON! | declaration_statement SEMICOLON! | SEMICOLON! | control_statement ; control_statement : while_statement ; while_statement : WHILE LPAREN scope_expr RPAREN do_=block_expression -> ^(WHILE scope_expr $do_) ; scope_expr : statement+ -> ^(SCOPEEXPR statement+) ; declaration_statement : LOCAL type_=qualifier name_=IDENTIFIER -> ^(LOCAL $type_ $name_) ; object_creation_expression : NEW qualifier LPAREN argument_list RPAREN -> ^(NEW qualifier argument_list?) ; invocation_or_load_expression : operand (DCOLON^ IDENTIFIER (LPAREN! argument_list RPAREN!)?)* ; array_creation_expression : NEWARR qualifier LBRACKET expression RBRACKET -> ^(NEWARR qualifier expression) ; expression : assignment_expression ; assignment_expression : ternary_expression (BECOMES^ ternary_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 : primary_expression ((LE^ | LEQ^ | GE^ | GEQ^ | EQ^ | NEQ^) primary_expression)* ; primary_expression : secundary_expression ((PLUS^ | MINUS^) secundary_expression)* ; secundary_expression : statement_expression ((MULTIPLY^ | DIVISION^ | MOD^) statement_expression )* ; statement_expression : logicnotoperator_expression ; logicnotoperator_expression : (NOT^)* inv_expression ; inv_expression : invocation_or_load_expression ; operand : qualifier -> ^(USAGE qualifier) | NUMBER | STRING | CHAR | TRUE | FALSE | THIS | object_creation_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)* ; qualifier : full_qualifier ; type_qualifier : VOID | qualifier ; full_qualifier : (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+ ; 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 ;