1
0
mirror of https://github.com/twiglet/cs2j.git synced 2025-01-18 13:15:17 +01:00

implement using statements and fix indentation

This commit is contained in:
Kevin Glynn 2010-12-20 22:05:25 +01:00
parent f1c9c5e6aa
commit 0940c53833
5 changed files with 189 additions and 88 deletions

View File

@ -86,6 +86,72 @@ scope TypeContext {
return root; return root;
} }
// for ["conn", "conn1", "conn2"] generate:
//
// if (conn != null)
// ((IDisposable)conn).Dispose();
//
//
// if (conn2 != null)
// ((IDisposable)conn2).Dispose();
//
//
// if (conn3 != null)
// ((IDisposable)conn3).Dispose();
// used in the finally block of the using translation
protected CommonTree addDisposeVars(IToken tok, List<string> vars) {
CommonTree root = (CommonTree)adaptor.Nil;
foreach (String var in vars) {
CommonTree root_1 = (CommonTree)adaptor.Nil;
root_1 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(IF, tok, "if"), root_1);
CommonTree root_2 = (CommonTree)adaptor.Nil;
root_2 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(NOT_EQUAL, tok, "!="), root_2);
adaptor.AddChild(root_2, (CommonTree)adaptor.Create(IDENTIFIER, tok, var));
adaptor.AddChild(root_2, (CommonTree)adaptor.Create(NULL, tok, "null"));
adaptor.AddChild(root_1, root_2);
adaptor.AddChild(root_1, (CommonTree)adaptor.Create(SEP, "SEP"));
root_2 = (CommonTree)adaptor.Nil;
root_2 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(APPLY, tok, "APPLY"), root_2);
CommonTree root_3 = (CommonTree)adaptor.Nil;
root_3 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(DOT, tok, "."), root_3);
CommonTree root_4 = (CommonTree)adaptor.Nil;
root_4 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(CAST_EXPR, tok, "CAST"), root_4);
CommonTree root_5 = (CommonTree)adaptor.Nil;
root_5 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(TYPE, tok, "TYPE"), root_5);
adaptor.AddChild(root_5, (CommonTree)adaptor.Create(IDENTIFIER, tok, "IDisposable"));
adaptor.AddChild(root_4, root_5);
adaptor.AddChild(root_4, (CommonTree)adaptor.Create(IDENTIFIER, tok, var));
adaptor.AddChild(root_3, root_4);
adaptor.AddChild(root_3, (CommonTree)adaptor.Create(IDENTIFIER, tok, "Dispose"));
adaptor.AddChild(root_2, root_3);
adaptor.AddChild(root_1, root_2);
adaptor.AddChild(root_1, (CommonTree)adaptor.Create(SEMI, tok, ";"));
adaptor.AddChild(root, root_1);
}
return (CommonTree)adaptor.RulePostProcessing(root);
}
// TODO: Read reserved words from a file so that they can be extended by customer // TODO: Read reserved words from a file so that they can be extended by customer
private readonly static string[] javaReserved = new string[] { "int", "protected", "package" }; private readonly static string[] javaReserved = new string[] { "int", "protected", "package" };
@ -121,6 +187,8 @@ scope TypeContext {
// counter to ensure that the catch vars we introduce are unique // counter to ensure that the catch vars we introduce are unique
protected int dummyCatchVarCtr = 0; protected int dummyCatchVarCtr = 0;
protected int newVarCtr = 0;
protected CommonTree dupTree(CommonTree t) { protected CommonTree dupTree(CommonTree t) {
return (CommonTree)adaptor.DupTree(t); return (CommonTree)adaptor.DupTree(t);
} }
@ -1255,16 +1323,19 @@ labeled_statement:
declaration_statement: declaration_statement:
(local_variable_declaration (local_variable_declaration
| local_constant_declaration) ';' ; | local_constant_declaration) ';' ;
local_variable_declaration: local_variable_declaration returns [List<String> variableNames]:
local_variable_type local_variable_declarators ; local_variable_type local_variable_declarators { $variableNames = $local_variable_declarators.variableNames; };
local_variable_type: local_variable_type:
('var') => 'var' ('var') => 'var'
| ('dynamic') => 'dynamic' | ('dynamic') => 'dynamic'
| type ; | type ;
local_variable_declarators: local_variable_declarators returns [List<String> variableNames]
local_variable_declarator (',' local_variable_declarator)* ; @init {
local_variable_declarator: $variableNames = new List<String>();
identifier ('=' local_variable_initializer)? ; }:
i1=local_variable_declarator { $variableNames.Add($i1.variableName); } (',' ip=local_variable_declarator { $variableNames.Add($ip.variableName); })* ;
local_variable_declarator returns [String variableName]:
identifier { $variableName = $identifier.text; } ('=' local_variable_initializer)? ;
local_variable_initializer: local_variable_initializer:
expression expression
| array_initializer | array_initializer
@ -1375,11 +1446,28 @@ unchecked_statement:
'unchecked' block ; 'unchecked' block ;
lock_statement: lock_statement:
'lock' '(' expression ')' embedded_statement ; 'lock' '(' expression ')' embedded_statement ;
using_statement: using_statement
'using' '(' resource_acquisition ')' embedded_statement ; @init {
resource_acquisition: CommonTree disposers = null;
(local_variable_declaration) => local_variable_declaration }:
| expression ; // see http://msdn.microsoft.com/en-us/library/yh598w02.aspx for translation
u='using' '(' resource_acquisition c=')' embedded_statement
{ disposers = addDisposeVars($c.token, $resource_acquisition.resourceNames); }
f=magicFinally[$c.token, disposers]
magicTry[$u.token, $embedded_statement.tree, null, $f.tree]
-> OPEN_BRACE[$u.token, "{"]
resource_acquisition SEMI[$c.token, ";"]
magicTry
CLOSE_BRACE[$u.token, "}"]
;
resource_acquisition returns [List<String> resourceNames]
@init {
$resourceNames = new List<String>();
}:
(local_variable_declaration) => local_variable_declaration { $resourceNames = $local_variable_declaration.variableNames; }
| expression { $resourceNames.Add("__newVar"+newVarCtr); } -> ^(TYPE[$expression.tree.Token, "TYPE"] IDENTIFIER[$expression.tree.Token, "IDisposable"])
IDENTIFIER[$expression.tree.Token, "__newVar"+newVarCtr++] ASSIGN[$expression.tree.Token, "="] expression //SEMI[$expression.tree.Token, ";"]
;
yield_statement: yield_statement:
'yield' ('return' expression ';' 'yield' ('return' expression ';'
| 'break' ';') ; | 'break' ';') ;
@ -1534,3 +1622,19 @@ magicMainWrapper[bool isOn, IToken tok, CommonTree body]:
EXCEPTION[tok, "Throwable"]) EXCEPTION[tok, "Throwable"])
-> ->
; ;
magicTry[IToken tok, CommonTree body, CommonTree catches, CommonTree fin]:
->
^(TRY[tok, "try"] { dupTree(body) } { dupTree(catches) } { dupTree(fin) })
;
magicDispose[IToken tok, String var]:
-> ^(IF[tok, "if"] ^(NOT_EQUAL[tok, "!="] IDENTIFIER[tok, var] NULL[tok, "null"]) SEP
^(APPLY[tok, "APPLY"] ^(DOT[tok, "."] ^(CAST_EXPR[tok, "CAST"] ^(TYPE[tok, "TYPE"] IDENTIFIER[tok, "IDisposable"]) IDENTIFIER[tok, var]) IDENTIFIER[tok, "Dispose"])) SEMI[tok, ";"])
;
magicFinally[IToken tok, CommonTree statement_list]:
->
^(FINALLY[tok, "finally"] OPEN_BRACE[tok, "{"] { dupTree(statement_list) } CLOSE_BRACE[tok, "}"])
;

View File

@ -400,10 +400,19 @@ argument_name:
argument_name_unsupported -> unsupported(reason={ "named parameters are not yet supported"}, text = { $argument_name_unsupported.st } ); argument_name_unsupported -> unsupported(reason={ "named parameters are not yet supported"}, text = { $argument_name_unsupported.st } );
argument_name_unsupported: argument_name_unsupported:
identifier ':' -> op(pre={$identifier.st}, op={":"}); identifier ':' -> op(pre={$identifier.st}, op={":"});
argument_value: argument_value
@init {
StringTemplate someText = null;
}:
expression -> { $expression.st } expression -> { $expression.st }
| ref_variable_reference | ref_variable_reference
| 'out' variable_reference ; | 'out' variable_reference
{ someText = %op();
%{someText}.op = "out";
%{someText}.post = $variable_reference.st;
%{someText}.space = " ";
} -> unsupported(reason = {"out arguments are not yet supported"}, text = { someText } )
;
ref_variable_reference: ref_variable_reference:
'ref' 'ref'
(('(' type ')') => '(' type ')' (ref_variable_reference | variable_reference) // SomeFunc(ref (int) ref foo) (('(' type ')') => '(' type ')' (ref_variable_reference | variable_reference) // SomeFunc(ref (int) ref foo)
@ -411,7 +420,7 @@ ref_variable_reference:
| variable_reference); // SomeFunc(ref foo) | variable_reference); // SomeFunc(ref foo)
// lvalue // lvalue
variable_reference: variable_reference:
expression; expression -> { $expression.st };
rank_specifiers: rank_specifiers:
rs+=rank_specifier+ -> rank_specifiers(rs={$rs}); rs+=rank_specifier+ -> rank_specifiers(rs={$rs});
rank_specifier: rank_specifier:
@ -630,8 +639,8 @@ block returns [bool isSemi]
@init { @init {
$isSemi = false; $isSemi = false;
}: }:
';' { $isSemi = true; } -> ';' { $isSemi = true; } -> string(payload = { " ;" })
| '{' s+=statement* '}' -> statement_list(statements = { $s }); | '{' s+=statement* '}' -> braceblock(statements = { $s });
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// Expression Section // Expression Section
@ -1169,28 +1178,28 @@ statement_plus:
(identifier ':') => labeled_statement -> statement(statement = { $labeled_statement.st }) (identifier ':') => labeled_statement -> statement(statement = { $labeled_statement.st })
| embedded_statement -> statement(statement = { $embedded_statement.st }) | embedded_statement -> statement(statement = { $embedded_statement.st })
; ;
embedded_statement returns [bool isSemi, bool isBraces, bool isIf] embedded_statement returns [bool isSemi, bool isIf, bool indent]
@init { @init {
StringTemplate someText = null; StringTemplate someText = null;
$isBraces = false; $isSemi = false;
$isIf = false; $isIf = false;
$indent = true;
List<String> preComments = null; List<String> preComments = null;
}: }:
block { $isSemi = $block.isSemi; $isBraces = !$block.isSemi;} -> { $block.st } block { $isSemi = $block.isSemi; $indent = false; } -> { $block.st }
| ^(IF boolean_expression { preComments = CollectedComments; } SEP t=embedded_statement e=else_statement?) { $isIf = true; } | ^(IF boolean_expression { preComments = CollectedComments; } SEP t=embedded_statement e=else_statement?) { $isIf = true; }
-> if_template(comments = { preComments }, cond= { $boolean_expression.st }, -> if_template(comments = { preComments }, cond= { $boolean_expression.st },
then = { $t.st }, thensemi = { $t.isSemi }, thenbraces = { $t.isBraces }, then = { $t.st }, thenindent = { $t.indent },
else = { $e.st }, elsesemi = { $e.isSemi }, elsebraces = { $e.isBraces }, elseisif = { $e.isIf }) else = { $e.st }, elseisif = { $e.isIf }, elseindent = { $e.indent})
| ^('switch' expression { preComments = CollectedComments; } s+=switch_section*) -> switch(comments = { preComments }, scrutinee = { $expression.st }, sections = { $s }) | ^('switch' expression { preComments = CollectedComments; } s+=switch_section*) -> switch(comments = { preComments }, scrutinee = { $expression.st }, sections = { $s })
| iteration_statement -> { $iteration_statement.st } // 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' { preComments = CollectedComments; } b=block catch_clauses? finally_clause?) | ^('try' { preComments = CollectedComments; } b=block catch_clauses? finally_clause?)
-> try(comments = { preComments }, block = {$b.st}, blocksemi = {$b.isSemi}, blockbraces = { !$b.isSemi }, -> try(comments = { preComments }, block = {$b.st}, blockindent = { $b.isSemi },
catches = { $catch_clauses.st }, fin = { $finally_clause.st } ) catches = { $catch_clauses.st }, fin = { $finally_clause.st } )
| checked_statement -> { $checked_statement.st } | checked_statement -> { $checked_statement.st }
| unchecked_statement -> { $unchecked_statement.st } | unchecked_statement -> { $unchecked_statement.st }
| lock_statement -> { $lock_statement.st } | lock_statement -> { $lock_statement.st }
| using_statement
| yield_statement | yield_statement
| ^('unsafe' { preComments = CollectedComments; } block { someText = %op(); %{someText}.op="unsafe"; %{someText}.post = $block.st; }) | ^('unsafe' { preComments = CollectedComments; } block { someText = %op(); %{someText}.op="unsafe"; %{someText}.post = $block.st; })
-> unsupported(comments = { preComments }, reason = {"unsafe blocks are not supported"}, text = { someText } ) -> unsupported(comments = { preComments }, reason = {"unsafe blocks are not supported"}, text = { someText } )
@ -1246,8 +1255,8 @@ if_statement:
// else goes with closest if // else goes with closest if
; ;
else_statement returns [bool isSemi, bool isBraces, bool isIf]: else_statement returns [bool isSemi, bool isIf, bool indent]:
'else' s=embedded_statement { $isSemi = $s.isSemi; $isBraces = $s.isBraces; $isIf = $s.isIf; } -> { $embedded_statement.st } ; 'else' s=embedded_statement { $isSemi = $s.isSemi; $isIf = $s.isIf; $indent = $s.indent; } -> { $embedded_statement.st } ;
switch_section: switch_section:
^(SWITCH_SECTION lab+=switch_label+ stat+=statement+) -> switch_section(labels = { $lab }, statements = { $stat }); ^(SWITCH_SECTION lab+=switch_label+ stat+=statement+) -> switch_section(labels = { $lab }, statements = { $stat });
switch_label: switch_label:
@ -1255,14 +1264,14 @@ switch_label:
| 'default' -> default_template() ; | 'default' -> default_template() ;
iteration_statement: iteration_statement:
^('while' boolean_expression SEP embedded_statement) ^('while' boolean_expression SEP embedded_statement)
-> while(cond = { $boolean_expression.st }, block = { $embedded_statement.st }, blocksemi = { $embedded_statement.isSemi }, blockbraces = { $embedded_statement.isBraces }) -> while(cond = { $boolean_expression.st }, block = { $embedded_statement.st }, blockindent = { $embedded_statement.indent })
| do_statement -> { $do_statement.st } | do_statement -> { $do_statement.st }
| ^('for' for_initializer? SEP expression? SEP for_iterator? SEP embedded_statement) | ^('for' for_initializer? SEP expression? SEP for_iterator? SEP embedded_statement)
-> for(init = { $for_initializer.st }, cond = { $expression.st }, iter = { $for_iterator.st }, -> for(init = { $for_initializer.st }, cond = { $expression.st }, iter = { $for_iterator.st },
block = { $embedded_statement.st }, blocksemi = { $embedded_statement.isSemi }, blockbraces = { $embedded_statement.isBraces }) block = { $embedded_statement.st }, blockindent = { $embedded_statement.indent })
| ^('foreach' local_variable_type identifier expression SEP embedded_statement) | ^('foreach' local_variable_type identifier expression SEP embedded_statement)
-> foreach(type = { $local_variable_type.st }, loopid = { $identifier.st }, fromexp = { $expression.st }, -> foreach(type = { $local_variable_type.st }, loopid = { $identifier.st }, fromexp = { $expression.st },
block = { $embedded_statement.st }, blocksemi = { $embedded_statement.isSemi }, blockbraces = { $embedded_statement.isBraces }); block = { $embedded_statement.st }, blockindent = { $embedded_statement.indent });
do_statement: do_statement:
'do' embedded_statement 'while' '(' boolean_expression ')' ';' ; 'do' embedded_statement 'while' '(' boolean_expression ')' ';' ;
for_initializer: for_initializer:
@ -1286,9 +1295,9 @@ goto_statement:
catch_clauses: catch_clauses:
c+=catch_clause+ -> seplist(items={ $c }, sep = { "\n" }) ; c+=catch_clause+ -> seplist(items={ $c }, sep = { "\n" }) ;
catch_clause: catch_clause:
^('catch' type identifier block) -> catch_template(type = { $type.st }, id = { $identifier.st }, block = {$block.st}, blocksemi = { $block.isSemi }, blockbraces = { !$block.isSemi } ); ^('catch' type identifier block) -> catch_template(type = { $type.st }, id = { $identifier.st }, block = {$block.st}, blockindent = { $block.isSemi } );
finally_clause: finally_clause:
^('finally' block) -> fin(block = {$block.st}, blocksemi = { $block.isSemi }, blockbraces = { !$block.isSemi }); ^('finally' block) -> fin(block = {$block.st}, blockindent = { $block.isSemi });
checked_statement checked_statement
@init { @init {
StringTemplate someText = null; StringTemplate someText = null;
@ -1297,8 +1306,7 @@ checked_statement
{ someText = %keyword_block(); { someText = %keyword_block();
%{someText}.keyword = "checked"; %{someText}.keyword = "checked";
%{someText}.block = $block.st; %{someText}.block = $block.st;
%{someText}.blocksemi = $block.isSemi; %{someText}.indent = $block.isSemi; } -> unsupported(reason = {"checked statements are not supported"}, text = { someText } )
%{someText}.blockbraces = !$block.isSemi; } -> unsupported(reason = {"checked statements are not supported"}, text = { someText } )
; ;
unchecked_statement unchecked_statement
@init { @init {
@ -1308,8 +1316,7 @@ unchecked_statement
{ someText = %keyword_block(); { someText = %keyword_block();
%{someText}.keyword = "unchecked"; %{someText}.keyword = "unchecked";
%{someText}.block = $block.st; %{someText}.block = $block.st;
%{someText}.blocksemi = $block.isSemi; %{someText}.indent = $block.isSemi; } -> unsupported(reason = {"checked statements are not supported"}, text = { someText } )
%{someText}.blockbraces = !$block.isSemi; } -> unsupported(reason = {"checked statements are not supported"}, text = { someText } )
; ;
lock_statement lock_statement
@init { @init {
@ -1319,14 +1326,8 @@ lock_statement
{ someText = %lock(); { someText = %lock();
%{someText}.exp = $expression.st; %{someText}.exp = $expression.st;
%{someText}.block = $embedded_statement.st; %{someText}.block = $embedded_statement.st;
%{someText}.blocksemi = $embedded_statement.isSemi; %{someText}.indent = $embedded_statement.indent; } -> unsupported(reason = {"lock() statements are not supported"}, text = { someText } )
%{someText}.blockbraces = $embedded_statement.isBraces; } -> unsupported(reason = {"lock() statements are not supported"}, text = { someText } )
; ;
using_statement:
'using' '(' resource_acquisition ')' embedded_statement ;
resource_acquisition:
(local_variable_declaration) => local_variable_declaration
| expression ;
yield_statement: yield_statement:
'yield' ('return' expression ';' 'yield' ('return' expression ';'
| 'break' ';') ; | 'break' ';') ;

View File

@ -847,7 +847,6 @@ block
| checked_statement | checked_statement
| unchecked_statement | unchecked_statement
| lock_statement | lock_statement
| using_statement
| yield_statement | yield_statement
| ^('unsafe' block) | ^('unsafe' block)
| fixed_statement | fixed_statement
@ -942,11 +941,6 @@ unchecked_statement:
'unchecked' block ; 'unchecked' block ;
lock_statement: lock_statement:
'lock' '(' expression ')' embedded_statement ; 'lock' '(' expression ')' embedded_statement ;
using_statement:
'using' '(' resource_acquisition ')' embedded_statement ;
resource_acquisition:
(local_variable_declaration) => local_variable_declaration
| expression ;
yield_statement: yield_statement:
'yield' ('return' expression ';' 'yield' ('return' expression ';'
| 'break' ';') ; | 'break' ';') ;

View File

@ -55,6 +55,7 @@ tokens {
PRIVATE = 'private'; PRIVATE = 'private';
TRY = 'try'; TRY = 'try';
CATCH = 'catch'; CATCH = 'catch';
FINALLY = 'finally';
THROW = 'throw'; THROW = 'throw';
OPEN_BRACKET='['; OPEN_BRACKET='[';

View File

@ -53,18 +53,20 @@ class_member(comments, member) ::= <<
<member> <member>
>> >>
constructor(modifiers, name, params, exception="Throwable", bodyIsSemi, body) ::= << constructor(modifiers, name, params, exception="Throwable", body, bodyIsSemi) ::= <<
<modifiers(modifiers)><name>(<params; separator=", ">) throws <exception><if(!bodyIsSemi)> {<else>;<endif> <modifiers(modifiers)><name>(<params; separator=", ">) throws <exception> <if(bodyIsSemi)>;
<body> <else>
<if(!bodyIsSemi)>}<endif> <body>
<endif>
<\n>
>> >>
method(modifiers, typeparams, type, name, params, exceptions, bodyIsSemi, body) ::= << method(modifiers, typeparams, type, name, params, exceptions, body, bodyIsSemi) ::= <<
<modifiers(modifiers)><typeparams> <type> <name>(<params; separator=", ">)<if(exceptions)> throws <exceptions; separator=", "><endif><if(!bodyIsSemi)> {<else>;<endif> <modifiers(modifiers)><typeparams> <type> <name>(<params; separator=", ">)<if(exceptions)> throws <exceptions; separator=", "><endif> <if(bodyIsSemi)>;
<body> <else>
<if(!bodyIsSemi)>}<endif> <body>
<endif>
<\n>
>> >>
field(modifiers, type, field, comments, init) ::= "<comments><modifiers(modifiers)><type> <field>;" field(modifiers, type, field, comments, init) ::= "<comments><modifiers(modifiers)><type> <field>;"
@ -133,52 +135,52 @@ 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 ******* // ******* STATEMENTS *******
if_template(comments, cond,then,thensemi, thenbraces,else, elseisif, elsesemi,elsebraces) ::= << if_template(comments, cond, then, thenindent, else, elseindent, elseisif) ::= <<
<comments; separator="\n"> <comments; separator="\n">
if (<cond>) if (<cond>)
<block(statements = then, issemi = thensemi, isbraces = thenbraces)> <block(statements = then, indent = thenindent)>
<if(else)> <if(else)>
else<if(elseisif)> <block(statements = else, issemi = elsesemi, isbraces = elsebraces)><else> else<if(elseisif)> <block(statements = else)><else>
<block(statements = else, issemi = elsesemi, isbraces = elsebraces)> <block(statements = else, indent = elseindent)>
<endif> <endif>
<endif> <endif>
>> >>
while(comments,cond,block,blocksemi, blockbraces) ::= << while(comments,cond,block) ::= <<
<comments; separator="\n"> <comments; separator="\n">
while (<cond>) while (<cond>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)> <block(statements = block)>
>> >>
for(comments,init,cond,iter,block,blocksemi, blockbraces) ::= << for(comments,init,cond,iter,block,blockindent) ::= <<
<comments; separator="\n"> <comments; separator="\n">
for (<init>;<cond>;<iter>) for (<init>;<cond>;<iter>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)> <block(statements = block, indent=blockindent)>
>> >>
foreach(comments,type,loopid,fromexp,block,blocksemi, blockbraces) ::= << foreach(comments,type,loopid,fromexp,block,blockindent) ::= <<
<comments; separator="\n"> <comments; separator="\n">
for (<type> <loopid> : <fromexp>) for (<type> <loopid> : <fromexp>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)> <block(statements = block,indent=blockindent)>
>> >>
try(comments,block,blocksemi, blockbraces, catches, fin) ::= << try(comments,block, blockindent, catches, fin) ::= <<
<comments; separator="\n"> <comments; separator="\n">
try try
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)> <block(statements = block, indent=blockindent)>
<catches> <catches>
<fin> <fin>
>> >>
catch_template(type, id, block,blocksemi, blockbraces) ::= << catch_template(type, id, block, blockindent) ::= <<
catch (<type> <id>) catch (<type> <id>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)> <block(statements = block, indent = blockindent)>
>> >>
fin(block,blocksemi, blockbraces) ::= << fin(block, blockindent) ::= <<
finally finally
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)> <block(statements = block, indent = blockindent)>
>> >>
@ -204,31 +206,30 @@ default_template() ::= <<
default: default:
>> >>
lock(comments,exp,block,blocksemi, blockbraces) ::= << lock(comments,exp,block, indent) ::= <<
<comments; separator="\n"> <comments; separator="\n">
lock(<exp>) lock(<exp>)
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)> <block(statements = block, indent = indent)>
>> >>
keyword_block(comments,keyword,block,blocksemi, blockbraces) ::= << keyword_block(comments,keyword,block, indent) ::= <<
<comments; separator="\n"> <comments; separator="\n">
<keyword> <keyword>
<block(statements = block, issemi = blocksemi, isbraces = blockbraces)> <block(statements = block, indent = indent)>
>> >>
block(statements,issemi,isbraces) ::= << block(statements, indent) ::= <<
<if(issemi)> <if(indent)>
;
<else>
<if(isbraces)>
{
<endif>
<statements> <statements>
<if(isbraces)> <else>
<statements>
<endif>
>>
braceblock(statements) ::= <<
{
<statements; separator="\n">
} }
<endif>
<endif>
>> >>
// ******* EXPRESSIONS ******* // ******* EXPRESSIONS *******