mirror of
https://github.com/twiglet/cs2j.git
synced 2025-01-18 13:15:17 +01:00
add precedence table
This commit is contained in:
parent
41c4479473
commit
75ffb63350
@ -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 ;
|
||||
|
@ -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<precedence.Length; i++) {
|
||||
// anything but these operators binds super tight
|
||||
// for example METHOD_CALL binds tighter than PLUS
|
||||
precedence[i] = int.MaxValue;
|
||||
}
|
||||
precedence[ASSIGN] = 1;
|
||||
precedence[PLUS_ASSIGN] = 1;
|
||||
precedence[MINUS_ASSIGN] = 1;
|
||||
precedence[STAR_ASSIGN] = 1;
|
||||
precedence[DIV_ASSIGN] = 1;
|
||||
precedence[MOD_ASSIGN] = 1;
|
||||
precedence[RIGHT_SHIFT_ASSIGN] = 1;
|
||||
precedence[LEFT_SHIFT_ASSIGN] = 1;
|
||||
precedence[UNSIGNED_RIGHT_SHIFT_ASSIGN] = 1;
|
||||
precedence[BIT_AND_ASSIGN] =1;
|
||||
precedence[BIT_XOR_ASSIGN] = 1;
|
||||
precedence[BIT_OR_ASSIGN] = 1;
|
||||
|
||||
precedence[COND_EXPR] = 2;
|
||||
|
||||
precedence[LOG_OR] = 3;
|
||||
|
||||
precedence[LOG_AND] = 4;
|
||||
|
||||
precedence[BIT_OR] = 5;
|
||||
|
||||
precedence[BIT_XOR] = 6;
|
||||
|
||||
precedence[BIT_AND] = 7;
|
||||
|
||||
precedence[NOT_EQUAL] = 8;
|
||||
precedence[EQUAL] = 8;
|
||||
|
||||
precedence[LTHAN] = 9;
|
||||
precedence[GT] = 9;
|
||||
precedence[LTE] = 9;
|
||||
precedence[GTE] = 9;
|
||||
precedence[INSTANCEOF] = 9;
|
||||
|
||||
precedence[LEFT_SHIFT] = 10;
|
||||
precedence[RIGHT_SHIFT] = 10;
|
||||
precedence[UNSIGNED_RIGHT_SHIFT] = 10;
|
||||
|
||||
precedence[PLUS] = 11;
|
||||
precedence[MINUS] = 11;
|
||||
|
||||
precedence[DIV] = 12;
|
||||
precedence[MOD] = 12;
|
||||
precedence[STAR] = 12;
|
||||
|
||||
precedence[CAST_EXPR] = 13;
|
||||
precedence[NEW] = 13;
|
||||
|
||||
precedence[PREINC] = 14;
|
||||
precedence[PREDEC] = 14;
|
||||
precedence[MONONOT] = 14;
|
||||
precedence[MONOTWIDDLE] = 14;
|
||||
precedence[MONOMINUS] = 14;
|
||||
precedence[MONOPLUS] = 14;
|
||||
|
||||
precedence[POSTINC] = 15;
|
||||
precedence[POSTDEC] = 15;
|
||||
precedence[APPLY] = 15;
|
||||
precedence[INDEX] = 15;
|
||||
precedence[DOT] = 15;
|
||||
|
||||
IsPrecedenceInitted = true;
|
||||
}
|
||||
|
||||
|
||||
// Compares precedence of op1 and op2.
|
||||
// Returns -1 if op2 < op1
|
||||
// 0 if op1 == op2
|
||||
// 1 if op2 > 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<String> 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<string> 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<string> 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:
|
||||
|
@ -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 ;
|
||||
|
@ -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; // (<x> ? <y> : <z>)
|
||||
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;
|
||||
|
@ -119,6 +119,13 @@ type_parameter_list(items) ::= <<
|
||||
extends(types) ::= "<if(types)>extends <types; separator=\",\"><endif>"
|
||||
imps(types) ::= "<if(types)>implements <types; separator=\",\"><endif>"
|
||||
|
||||
// ******* STATEMENTS *******
|
||||
if(cond,then,else) ::= <<
|
||||
if (<cond>)
|
||||
<then>
|
||||
<else>
|
||||
>>
|
||||
|
||||
// ******* EXPRESSIONS *******
|
||||
|
||||
cast_expr(type, exp) ::= "(<type>)<exp>"
|
||||
|
Loading…
x
Reference in New Issue
Block a user