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:
|
primary_expression_start:
|
||||||
predefined_type
|
predefined_type
|
||||||
| (identifier generic_argument_list) => identifier generic_argument_list
|
| (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'
|
| 'this'
|
||||||
| 'base'
|
| 'base'
|
||||||
| paren_expression
|
| paren_expression
|
||||||
@ -263,7 +263,7 @@ brackets [CommonTree lhs]:
|
|||||||
'[' expression_list? ']' -> ^(INDEX { (CommonTree)adaptor.DupTree($lhs) } expression_list?);
|
'[' expression_list? ']' -> ^(INDEX { (CommonTree)adaptor.DupTree($lhs) } expression_list?);
|
||||||
// keving: TODO: drop this.
|
// keving: TODO: drop this.
|
||||||
paren_expression:
|
paren_expression:
|
||||||
'(' expression ')' -> ^(TEMPPARENS expression);
|
'(' expression ')' -> ^(PARENS expression);
|
||||||
arguments [CommonTree lhs]:
|
arguments [CommonTree lhs]:
|
||||||
'(' argument_list? ')' -> ^(APPLY { (CommonTree)adaptor.DupTree($lhs) } argument_list?);
|
'(' argument_list? ')' -> ^(APPLY { (CommonTree)adaptor.DupTree($lhs) } argument_list?);
|
||||||
argument_list:
|
argument_list:
|
||||||
@ -524,7 +524,7 @@ cast_expression:
|
|||||||
// //'(' type ')' unary_expression ;
|
// //'(' type ')' unary_expression ;
|
||||||
l='(' type ')' unary_expression -> ^(CAST_EXPR[$l.token, "CAST"] type unary_expression);
|
l='(' type ')' unary_expression -> ^(CAST_EXPR[$l.token, "CAST"] type unary_expression);
|
||||||
assignment_operator:
|
assignment_operator:
|
||||||
'=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>' '>=' ;
|
'=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | r='>' '>=' -> RIGHT_SHIFT_ASSIGN[$r.token, ">>="] ;
|
||||||
pre_increment_expression:
|
pre_increment_expression:
|
||||||
s='++' unary_expression -> ^(PREINC[$s.token, "PRE++"] unary_expression) ;
|
s='++' unary_expression -> ^(PREINC[$s.token, "PRE++"] unary_expression) ;
|
||||||
pre_decrement_expression:
|
pre_decrement_expression:
|
||||||
@ -552,7 +552,7 @@ additive_expression:
|
|||||||
// >> check needed (no whitespace)
|
// >> check needed (no whitespace)
|
||||||
shift_expression:
|
shift_expression:
|
||||||
(a1=additive_expression -> $a1) ((so='<<' a3=additive_expression -> ^($so $shift_expression $a3))
|
(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:
|
relational_expression:
|
||||||
(s1=shift_expression -> $s1)
|
(s1=shift_expression -> $s1)
|
||||||
@ -1138,8 +1138,8 @@ selection_statement:
|
|||||||
| switch_statement ;
|
| switch_statement ;
|
||||||
if_statement:
|
if_statement:
|
||||||
// else goes with closest if
|
// else goes with closest if
|
||||||
// i='if' '(' boolean_expression ')' embedded_statement (('else') => else_statement)? -> ^(IF[$i.Token] boolean_expression embedded_statement 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)?
|
// 'if' '(' boolean_expression ')' embedded_statement (('else') => else_statement)?
|
||||||
;
|
;
|
||||||
else_statement:
|
else_statement:
|
||||||
'else' embedded_statement ;
|
'else' embedded_statement ;
|
||||||
|
@ -112,9 +112,112 @@ options {
|
|||||||
}
|
}
|
||||||
return rets;
|
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
|
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 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)},
|
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)
|
| m='readonly' | m='volatile' | m='extern' | m='virtual' | m='override' | m=FINAL)
|
||||||
-> string(payload={$m.text});
|
-> string(payload={$m.text});
|
||||||
|
|
||||||
class_member_declaration:
|
class_member_declaration returns [List<String> preComments]:
|
||||||
^(CONST attributes? modifiers? type constant_declarators)
|
^(CONST attributes? modifiers? type constant_declarators)
|
||||||
| ^(EVENT attributes? modifiers? event_declaration)
|
| ^(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(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})
|
// | ^(METHOD attributes? modifiers? type method_declaration) -> method(modifiers={$modifiers.st}, type={$type.st}, method={$method_declaration.st})
|
||||||
| ^(INTERFACE attributes? modifiers? interface_declaration[$modifiers.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 } )
|
| primary_expression_extalias -> unsupported(reason = {"external aliases are not yet supported"}, text= { $primary_expression_extalias.st } )
|
||||||
| 'this'
|
| 'this'
|
||||||
| 'base'
|
| 'base'
|
||||||
| ^(TEMPPARENS expression) -> parens(e={$expression.st})
|
|
||||||
| typeof_expression // typeof(Foo).Name
|
| typeof_expression // typeof(Foo).Name
|
||||||
| literal -> { $literal.st }
|
| literal -> { $literal.st }
|
||||||
;
|
;
|
||||||
@ -509,6 +612,10 @@ unary_expression:
|
|||||||
| ^(PREDEC u6=unary_expression) -> op(op={"--"}, post={$u6.st})
|
| ^(PREDEC u6=unary_expression) -> op(op={"--"}, post={$u6.st})
|
||||||
| ^(MONOSTAR unary_expression)
|
| ^(MONOSTAR unary_expression)
|
||||||
| ^(ADDRESSOF 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
|
// (cast_expression) => cast_expression
|
||||||
@ -678,9 +785,9 @@ class_declaration[StringTemplate modifiersST]
|
|||||||
@init {
|
@init {
|
||||||
List<string> preComments = null;
|
List<string> preComments = null;
|
||||||
}:
|
}:
|
||||||
^(c=CLASS { preComments = CollectedComments; }
|
^(c=CLASS
|
||||||
identifier type_parameter_constraints_clauses? type_parameter_list[$type_parameter_constraints_clauses.tpConstraints]?
|
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 },
|
-> 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}) ;
|
extends = { $class_extends.st }, imps = { $class_implements.st }, body={$class_body.st}) ;
|
||||||
|
|
||||||
@ -703,11 +810,8 @@ interface_type_list:
|
|||||||
|
|
||||||
class_body:
|
class_body:
|
||||||
'{' cs+=class_member_declaration_aux* '}' -> class_body(entries={$cs}) ;
|
'{' cs+=class_member_declaration_aux* '}' -> class_body(entries={$cs}) ;
|
||||||
class_member_declaration_aux
|
class_member_declaration_aux:
|
||||||
@init{
|
member=class_member_declaration -> class_member(comments={ $member.preComments }, member={ $member.st }) ;
|
||||||
List<string> preComments = null;
|
|
||||||
}:
|
|
||||||
{ preComments = CollectedComments; } member=class_member_declaration -> class_member(comments={ preComments }, member={ $member.st }) ;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
@ -1025,10 +1129,10 @@ statement_plus:
|
|||||||
;
|
;
|
||||||
embedded_statement:
|
embedded_statement:
|
||||||
block -> { $block.st }
|
block -> { $block.st }
|
||||||
| selection_statement // if, switch
|
| selection_statement -> { $selection_statement.st } // if, switch
|
||||||
| iteration_statement // while, do, for, foreach
|
| iteration_statement -> { $iteration_statement.st } // while, do, for, foreach
|
||||||
| jump_statement -> { $jump_statement.st } // break, continue, goto, return, throw
|
| jump_statement -> { $jump_statement.st } // break, continue, goto, return, throw
|
||||||
| try_statement
|
| try_statement -> { $try_statement.st }
|
||||||
| checked_statement
|
| checked_statement
|
||||||
| unchecked_statement
|
| unchecked_statement
|
||||||
| lock_statement
|
| lock_statement
|
||||||
@ -1082,14 +1186,14 @@ statement_expression:
|
|||||||
expression
|
expression
|
||||||
;
|
;
|
||||||
selection_statement:
|
selection_statement:
|
||||||
if_statement
|
if_statement -> { $if_statement.st }
|
||||||
| switch_statement ;
|
| switch_statement -> { $switch_statement.st };
|
||||||
if_statement:
|
if_statement:
|
||||||
// else goes with closest if
|
// 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_statement:
|
||||||
'else' embedded_statement ;
|
'else' embedded_statement -> { $embedded_statement.st } ;
|
||||||
switch_statement:
|
switch_statement:
|
||||||
'switch' '(' expression ')' switch_block ;
|
'switch' '(' expression ')' switch_block ;
|
||||||
switch_block:
|
switch_block:
|
||||||
|
@ -108,10 +108,10 @@ primary_expression:
|
|||||||
primary_expression_start:
|
primary_expression_start:
|
||||||
predefined_type
|
predefined_type
|
||||||
| (identifier generic_argument_list) => identifier generic_argument_list
|
| (identifier generic_argument_list) => identifier generic_argument_list
|
||||||
| identifier ('::' identifier)?
|
| identifier
|
||||||
|
| ^('::' identifier identifier)
|
||||||
| 'this'
|
| 'this'
|
||||||
| 'base'
|
| 'base'
|
||||||
| ^(TEMPPARENS expression)
|
|
||||||
| typeof_expression // typeof(Foo).Name
|
| typeof_expression // typeof(Foo).Name
|
||||||
| literal
|
| literal
|
||||||
;
|
;
|
||||||
@ -362,6 +362,7 @@ unary_expression:
|
|||||||
| ^(PREDEC unary_expression)
|
| ^(PREDEC unary_expression)
|
||||||
| ^(MONOSTAR unary_expression)
|
| ^(MONOSTAR unary_expression)
|
||||||
| ^(ADDRESSOF unary_expression)
|
| ^(ADDRESSOF unary_expression)
|
||||||
|
| ^(PARENS expression)
|
||||||
;
|
;
|
||||||
//cast_expression:
|
//cast_expression:
|
||||||
// '(' type ')' non_assignment_expression ;
|
// '(' type ')' non_assignment_expression ;
|
||||||
@ -930,7 +931,8 @@ selection_statement:
|
|||||||
| switch_statement ;
|
| switch_statement ;
|
||||||
if_statement:
|
if_statement:
|
||||||
// else goes with closest if
|
// 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_statement:
|
||||||
'else' embedded_statement ;
|
'else' embedded_statement ;
|
||||||
|
@ -32,15 +32,15 @@ tokens {
|
|||||||
|
|
||||||
MONOPLUS;
|
MONOPLUS;
|
||||||
MONOMINUS;
|
MONOMINUS;
|
||||||
MONONOT;
|
MONONOT = '!';
|
||||||
MONOTWIDDLE;
|
MONOTWIDDLE = '~';
|
||||||
MONOSTAR;
|
MONOSTAR;
|
||||||
ADDRESSOF;
|
ADDRESSOF;
|
||||||
PREINC;
|
PREINC;
|
||||||
PREDEC;
|
PREDEC;
|
||||||
POSTINC;
|
POSTINC;
|
||||||
POSTDEC;
|
POSTDEC;
|
||||||
TEMPPARENS;
|
PARENS;
|
||||||
INDEX;
|
INDEX;
|
||||||
APPLY;
|
APPLY;
|
||||||
ARGS;
|
ARGS;
|
||||||
@ -52,10 +52,51 @@ tokens {
|
|||||||
NULL_COALESCE='??';
|
NULL_COALESCE='??';
|
||||||
IF='if';
|
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>)
|
COND_EXPR; // (<x> ? <y> : <z>)
|
||||||
RIGHT_SHIFT;
|
RIGHT_SHIFT;
|
||||||
INSTANCEOF;
|
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;
|
TYPE;
|
||||||
ENUM_BODY;
|
ENUM_BODY;
|
||||||
TYPE_PARAM_CONSTRAINT;
|
TYPE_PARAM_CONSTRAINT;
|
||||||
|
@ -119,6 +119,13 @@ type_parameter_list(items) ::= <<
|
|||||||
extends(types) ::= "<if(types)>extends <types; separator=\",\"><endif>"
|
extends(types) ::= "<if(types)>extends <types; separator=\",\"><endif>"
|
||||||
imps(types) ::= "<if(types)>implements <types; separator=\",\"><endif>"
|
imps(types) ::= "<if(types)>implements <types; separator=\",\"><endif>"
|
||||||
|
|
||||||
|
// ******* STATEMENTS *******
|
||||||
|
if(cond,then,else) ::= <<
|
||||||
|
if (<cond>)
|
||||||
|
<then>
|
||||||
|
<else>
|
||||||
|
>>
|
||||||
|
|
||||||
// ******* EXPRESSIONS *******
|
// ******* EXPRESSIONS *******
|
||||||
|
|
||||||
cast_expr(type, exp) ::= "(<type>)<exp>"
|
cast_expr(type, exp) ::= "(<type>)<exp>"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user