From 75ffb63350769b877b3565d0bbc97819a6b79d7e Mon Sep 17 00:00:00 2001 From: Kevin Glynn Date: Wed, 8 Dec 2010 13:47:04 +0100 Subject: [PATCH] add precedence table --- .../antlr3/src/cs2j/CSharp/JavaMaker.g | 12 +- .../antlr3/src/cs2j/CSharp/JavaPrettyPrint.g | 138 +++++++++++++++--- .../antlr3/src/cs2j/CSharp/NetMaker.g | 8 +- CSharpTranslator/antlr3/src/cs2j/CSharp/cs.g | 47 +++++- .../src/cs2j/bin/Debug/templates/java.stg | 7 + 5 files changed, 183 insertions(+), 29 deletions(-) diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g index 1dbeecb..6ecbef0 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaMaker.g @@ -239,7 +239,7 @@ primary_expression: primary_expression_start: predefined_type | (identifier generic_argument_list) => identifier generic_argument_list - | identifier ((c='::' identifier { Warning($c.line, "[UNSUPPORTED] external aliases are not yet supported"); })?)! + | identifier ((c='::'^ identifier { Warning($c.line, "[UNSUPPORTED] external aliases are not yet supported"); })?)! | 'this' | 'base' | paren_expression @@ -263,7 +263,7 @@ brackets [CommonTree lhs]: '[' expression_list? ']' -> ^(INDEX { (CommonTree)adaptor.DupTree($lhs) } expression_list?); // keving: TODO: drop this. paren_expression: - '(' expression ')' -> ^(TEMPPARENS expression); + '(' expression ')' -> ^(PARENS expression); arguments [CommonTree lhs]: '(' argument_list? ')' -> ^(APPLY { (CommonTree)adaptor.DupTree($lhs) } argument_list?); argument_list: @@ -524,7 +524,7 @@ cast_expression: // //'(' type ')' unary_expression ; l='(' type ')' unary_expression -> ^(CAST_EXPR[$l.token, "CAST"] type unary_expression); assignment_operator: - '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>' '>=' ; + '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | r='>' '>=' -> RIGHT_SHIFT_ASSIGN[$r.token, ">>="] ; pre_increment_expression: s='++' unary_expression -> ^(PREINC[$s.token, "PRE++"] unary_expression) ; pre_decrement_expression: @@ -552,7 +552,7 @@ additive_expression: // >> check needed (no whitespace) shift_expression: (a1=additive_expression -> $a1) ((so='<<' a3=additive_expression -> ^($so $shift_expression $a3)) - | ('>' '>' a2=additive_expression -> ^(RIGHT_SHIFT $shift_expression $a2)) + | (r='>' '>' a2=additive_expression -> ^(RIGHT_SHIFT[$r.token, ">>"] $shift_expression $a2)) )* ; relational_expression: (s1=shift_expression -> $s1) @@ -1138,8 +1138,8 @@ selection_statement: | switch_statement ; if_statement: // else goes with closest if - // i='if' '(' boolean_expression ')' embedded_statement (('else') => else_statement)? -> ^(IF[$i.Token] boolean_expression embedded_statement else_statement?) - 'if' '(' boolean_expression ')' embedded_statement (('else') => else_statement)? + i='if' '(' boolean_expression ')' embedded_statement (('else') => else_statement)? -> ^(IF[$i.Token] boolean_expression SEP embedded_statement else_statement?) +// 'if' '(' boolean_expression ')' embedded_statement (('else') => else_statement)? ; else_statement: 'else' embedded_statement ; diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaPrettyPrint.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaPrettyPrint.g index bb9df90..3c01b07 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaPrettyPrint.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/JavaPrettyPrint.g @@ -112,9 +112,112 @@ options { } return rets; } + + // keving: Found this precedence table on the ANTLR site. + + /** Encodes precedence of various operators; indexed by token type. + * If precedence[op1] > precedence[op2] then op1 should happen + * before op2; + * table from http://www.cs.princeton.edu/introcs/11precedence/ + */ + private int[] precedence = new int[tokenNames.Length]; + private bool precedenceInitted = false; + protected bool IsPrecedenceInitted { + get { return precedenceInitted; } + set { precedenceInitted = value; } + } + private void initPrecedence() + { + if (IsPrecedenceInitted) + return; + + for (int i=0; i op1 + public int comparePrecedence(IToken op1, IToken op2) { + return Math.Sign(precedence[op2.Type]-precedence[op1.Type]); + } } compilation_unit +@init{ + initPrecedence(); + // Print all tokens + //for (int i = 0; i < TokenNames.Length; i++) { + // Console.Out.WriteLine("{0} -> {1}", TokenNames[i], i); + //} +} : ^(PACKAGE nm=PAYLOAD modifiers? type_declaration[$modifiers.st] { if (IsLast) collectComments(); }) -> package(now = {DateTime.Now}, includeDate = {true}, packageName = {($nm.text != null && $nm.text.Length > 0 ? $nm.text : null)}, @@ -141,10 +244,11 @@ modifier | m='readonly' | m='volatile' | m='extern' | m='virtual' | m='override' | m=FINAL) -> string(payload={$m.text}); -class_member_declaration: +class_member_declaration returns [List preComments]: ^(CONST attributes? modifiers? type constant_declarators) | ^(EVENT attributes? modifiers? event_declaration) - | ^(METHOD attributes? modifiers? type member_name type_parameter_constraints_clauses? type_parameter_list[$type_parameter_constraints_clauses.tpConstraints]? formal_parameter_list? method_body) + | ^(METHOD attributes? modifiers? type member_name type_parameter_constraints_clauses? type_parameter_list[$type_parameter_constraints_clauses.tpConstraints]? formal_parameter_list? + { $preComments = CollectedComments; } method_body) -> method(modifiers={$modifiers.st}, type={$type.st}, name={ $member_name.st }, typeparams = { $type_parameter_list.st }, params={ $formal_parameter_list.st }, bodyIsSemi = { $method_body.isSemi }, body={ $method_body.st }) // | ^(METHOD attributes? modifiers? type method_declaration) -> method(modifiers={$modifiers.st}, type={$type.st}, method={$method_declaration.st}) | ^(INTERFACE attributes? modifiers? interface_declaration[$modifiers.st]) @@ -238,7 +342,6 @@ primary_expression_start: | primary_expression_extalias -> unsupported(reason = {"external aliases are not yet supported"}, text= { $primary_expression_extalias.st } ) | 'this' | 'base' - | ^(TEMPPARENS expression) -> parens(e={$expression.st}) | typeof_expression // typeof(Foo).Name | literal -> { $literal.st } ; @@ -509,6 +612,10 @@ unary_expression: | ^(PREDEC u6=unary_expression) -> op(op={"--"}, post={$u6.st}) | ^(MONOSTAR unary_expression) | ^(ADDRESSOF unary_expression) + // PARENS is not stictly necessary because we insert parens where necessary. However + // we maintin parens inserted by original programmer since tey presumably thought + // it would improve understandability + | ^(PARENS expression) -> parens(e={$expression.st}) ; // (cast_expression) => cast_expression @@ -678,9 +785,9 @@ class_declaration[StringTemplate modifiersST] @init { List preComments = null; }: - ^(c=CLASS { preComments = CollectedComments; } + ^(c=CLASS identifier type_parameter_constraints_clauses? type_parameter_list[$type_parameter_constraints_clauses.tpConstraints]? - class_extends? class_implements? class_body ) + class_extends? class_implements? { preComments = CollectedComments; } class_body ) -> class(modifiers = {modifiersST}, name={ $identifier.st }, typeparams= {$type_parameter_list.st}, comments = { preComments }, extends = { $class_extends.st }, imps = { $class_implements.st }, body={$class_body.st}) ; @@ -703,11 +810,8 @@ interface_type_list: class_body: '{' cs+=class_member_declaration_aux* '}' -> class_body(entries={$cs}) ; -class_member_declaration_aux -@init{ - List preComments = null; -}: - { preComments = CollectedComments; } member=class_member_declaration -> class_member(comments={ preComments }, member={ $member.st }) ; +class_member_declaration_aux: + member=class_member_declaration -> class_member(comments={ $member.preComments }, member={ $member.st }) ; /////////////////////////////////////////////////////// @@ -1025,10 +1129,10 @@ statement_plus: ; embedded_statement: block -> { $block.st } - | selection_statement // if, switch - | iteration_statement // while, do, for, foreach + | selection_statement -> { $selection_statement.st } // if, switch + | iteration_statement -> { $iteration_statement.st } // while, do, for, foreach | jump_statement -> { $jump_statement.st } // break, continue, goto, return, throw - | try_statement + | try_statement -> { $try_statement.st } | checked_statement | unchecked_statement | lock_statement @@ -1082,14 +1186,14 @@ statement_expression: expression ; selection_statement: - if_statement - | switch_statement ; + if_statement -> { $if_statement.st } + | switch_statement -> { $switch_statement.st }; if_statement: // else goes with closest if - 'if' '(' boolean_expression ')' embedded_statement (('else') => else_statement)? + ^(IF boolean_expression SEP embedded_statement else_statement?) -> if(cond= { $boolean_expression.st }, then = { $embedded_statement.st }, else = { $else_statement.st }) ; else_statement: - 'else' embedded_statement ; + 'else' embedded_statement -> { $embedded_statement.st } ; switch_statement: 'switch' '(' expression ')' switch_block ; switch_block: diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g index 5c63b63..f4b9904 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/NetMaker.g @@ -108,10 +108,10 @@ primary_expression: primary_expression_start: predefined_type | (identifier generic_argument_list) => identifier generic_argument_list - | identifier ('::' identifier)? + | identifier + | ^('::' identifier identifier) | 'this' | 'base' - | ^(TEMPPARENS expression) | typeof_expression // typeof(Foo).Name | literal ; @@ -362,6 +362,7 @@ unary_expression: | ^(PREDEC unary_expression) | ^(MONOSTAR unary_expression) | ^(ADDRESSOF unary_expression) + | ^(PARENS expression) ; //cast_expression: // '(' type ')' non_assignment_expression ; @@ -930,7 +931,8 @@ selection_statement: | switch_statement ; if_statement: // else goes with closest if - 'if' '(' boolean_expression ')' embedded_statement (('else') => else_statement)? + // 'if' '(' boolean_expression ')' embedded_statement (('else') => else_statement)? + ^(IF boolean_expression SEP embedded_statement else_statement?) ; else_statement: 'else' embedded_statement ; diff --git a/CSharpTranslator/antlr3/src/cs2j/CSharp/cs.g b/CSharpTranslator/antlr3/src/cs2j/CSharp/cs.g index 7df53f5..9d4ff71 100644 --- a/CSharpTranslator/antlr3/src/cs2j/CSharp/cs.g +++ b/CSharpTranslator/antlr3/src/cs2j/CSharp/cs.g @@ -32,15 +32,15 @@ tokens { MONOPLUS; MONOMINUS; - MONONOT; - MONOTWIDDLE; + MONONOT = '!'; + MONOTWIDDLE = '~'; MONOSTAR; ADDRESSOF; PREINC; PREDEC; POSTINC; POSTDEC; - TEMPPARENS; + PARENS; INDEX; APPLY; ARGS; @@ -52,10 +52,51 @@ tokens { NULL_COALESCE='??'; IF='if'; + ASSIGN = '='; + + PLUS_ASSIGN = '+='; + MINUS_ASSIGN = '-='; + STAR_ASSIGN = '*='; + DIV_ASSIGN = '/='; + MOD_ASSIGN = '%='; + + BIT_AND_ASSIGN = '&='; + BIT_OR_ASSIGN = '|='; + BIT_XOR_ASSIGN = '^='; + + LEFT_SHIFT_ASSIGN = '<<='; + RIGHT_SHIFT_ASSIGN; + + UNSIGNED_RIGHT_SHIFT_ASSIGN; /* not in C#: >>>= */ + COND_EXPR; // ( ? : ) RIGHT_SHIFT; INSTANCEOF; + LOG_OR = '||'; + LOG_AND = '&&'; + BIT_OR = '|'; + BIT_XOR = '^'; + BIT_AND = '&'; + + NOT_EQUAL = '!='; + EQUAL = '=='; + + LTHAN = '<'; + LTE = '<='; + GTE = '>='; + + LEFT_SHIFT = '<<'; + RIGHT_SHIFT; + UNSIGNED_RIGHT_SHIFT; /* not in C#: >>> */ + + PLUS = '+'; + + + DIV = '/'; + MOD = '%'; + STAR = '*'; + TYPE; ENUM_BODY; TYPE_PARAM_CONSTRAINT; diff --git a/CSharpTranslator/antlr3/src/cs2j/bin/Debug/templates/java.stg b/CSharpTranslator/antlr3/src/cs2j/bin/Debug/templates/java.stg index 3b90c61..f10e3f9 100644 --- a/CSharpTranslator/antlr3/src/cs2j/bin/Debug/templates/java.stg +++ b/CSharpTranslator/antlr3/src/cs2j/bin/Debug/templates/java.stg @@ -119,6 +119,13 @@ type_parameter_list(items) ::= << extends(types) ::= "extends " imps(types) ::= "implements " +// ******* STATEMENTS ******* +if(cond,then,else) ::= << +if () + + +>> + // ******* EXPRESSIONS ******* cast_expr(type, exp) ::= "()"