File: build/parser.mly (return to index)



Statistics:  
kind coverage
binding 1 / 1 (100 %)
sequence 0 / 8 (0 %)
for 0 / 0 (- %)
if/then 0 / 0 (- %)
try 0 / 0 (- %)
while 0 / 0 (- %)
match/function 3 / 5 (60 %)
kind coverage
class expression 0 / 0 (- %)
class initializer 0 / 0 (- %)
class method 0 / 0 (- %)
class value 0 / 0 (- %)
toplevel expression 0 / 0 (- %)
lazy operator 0 / 0 (- %)



Source:

fold all unfold all
000001| %{
000002|     
000003| (** 
000004|
000005| This program is free software; you can redistribute it and / or modify
000006| it under the terms of the GNU General Public License as published by
000007| the Free Software Foundation; version 3 of the License.
000008|
000009| This program is distributed in the hope that it will be useful,
000010| but WITHOUT ANY WARRANTY; without even the implied warranty of
000011| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
000012| GNU General Public License for more details.
000013|
000014| Jtemplate parser
000015| expression parsing adapted from ECMA-262 
000016| http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf 
000017|
000018| @author Tony BenBrahim < tony.benbrahim at gmail.com >
000019|
000020| *)
000021|
000022| open Ast
000023|
000024| let parse_error s =
000025|     let pos = Parsing.symbol_start_pos() in
000026|     print_string ("in file " ^ (Filename.basename pos.Lexing.pos_fname) ^ ": "^ s^" at line ");
000027|     print_int pos.Lexing.pos_lnum;
000028|     print_string " at columns ";
000029|     print_int (Parsing.symbol_start() - pos.Lexing.pos_bol);
000030|     print_string("-");
000031|     print_int (Parsing.symbol_end() - pos.Lexing.pos_bol);
000032|     print_string "\n";
000033|     flush stdout
000034|         
000035| let get_env ()= 
000036|     let pos=Parsing.symbol_start_pos() in
000037|     (pos.Lexing.pos_fname,pos.Lexing.pos_lnum)
000038|
000039|         
000040| let resolve_import (filename, library, (inp_file, _))=
000041|     Filename_util.resolve_filename (Filename.dirname inp_file) filename
000042|         
000043| let extract_stmt_list=function
000044|     | StatementBlock(lst) -> lst
000045|     | _ -> raise ( RuntimeError.InternalError "expected statement block" )
000046| %}
000047|
000048| %token<string> ID
000049| %toke(*[0]*)n <int> INT
000050| %token <string> STRING
000051| %token <(*[0]*)float> REAL
000052| %token <bool> BOOLEAN
000053| %token <string> TEXT
000054| %token <Ast.comparator> COMPOP
000055| %token (*[0]*)<bool> IMPORT
000056|
000057| %token FOREACH WHIL(*[0]*)E IF  FOR ELSE TEMPLATE INSTRUCTIO(*[0]*)NS FUNCTION CONTINUE BREAK
000058| %token RETURN IN ONCE WHEN VAR EOF(*[0]*) LBRACE RBRACE LPAREN RP(*[0]*)AREN LBRACKET RBRACKET
000059| %token COMMA SEMICOLON COLON DOTDOTD(*[0]*)OT DOT EQUALS NOT QUESTI(*[0]*)ON PLUS MINUS TIMES
000060| %token DIVIDE MODULO AND (*[1386]*)OR VOID SWITCH CASE DEFAULT PLUSEQUALS MINUS(*[1386]*)EQUALS
000061| %token TIMESEQUALS DIVEQUALS MODEQUALS PLUSPLUS MINUSMINUS AT TRY CATCH THROW
000062| %token FINALLY PROTOTYPE OUT(*[18]*)OFRANGENUMBER
000063|
000064|
000065| %start program
000066| %type <Ast.statement> program
000067|
000068| /* resolve shift/reduce conflict for ELSE */
000069| %nonassoc LOWER_THAN_ELSE (*[346]*)
000070| %nonassoc ELSE (*[0]*)
000071|
000072| /* resolve shift/reduce conflict for {} (map) and {} (empty block) */
000073| %nonassoc MAP
000074| %nonassoc EMPTYBLOCK
000075|
000076| %right PLUSEQUALS MINUSEQUALS 
000077| %right TIMESEQUALS DIVEQUALS MODEQUALS
000078| %right EQUALS
000079| %right COLON
000080| %right QUESTION
000081| %left OR
000082| %left AND 
000083| %left COMPOP
000084| %left PLUS MINUS
000085| %left TIMES DIVIDE MODULO
000086| %right NOT
000087| %right UMINUS
000088| %right PREFIX_INCDEC  
000089| %left POSTFIX_INCDEC
000090| %left ARR_INDEX
000091|
000092| %%
000093| program:
000094|     | opt_statements EOF { Program($1) }
000095| ;
000096| statements:                           
000097|     | statement   { [$1] }
000098|     | statement statements  { $1::$2 }
000099| ;
000100| opt_statements:
000101|     | statements  { $1 }
000102|     | /*nothing*/ { [] }
000103| ;
000104| statement_block:                      
000105|     | LBRACE statements RBRACE  { StatementBlock($2) }
000106|     | empty_statement_block     { $1 } 
000107| ;
000108| empty_statement_block:
000109|     | LBRACE RBRACE  { StatementBlock([]) }
000110| ; 
000111| else_clause:                         
000112|     | ELSE statement { $2 }
000113|     | %prec LOWER_THAN_ELSE { Noop }
000114| ;
000115| statement:                                    
000116|     | IF LPAREN expression RPAREN statement else_clause { If($3,$5,$6,get_env()) }
000117|     | expression SEMICOLON { ExpressionStatement($1, get_env()) }
000118|     | SEMICOLON  { Noop }
000119|     | statement_block { $1 }
000120|     | FOREACH LPAREN ID IN expression RPAREN statement { ForEach($3,$5,$7,get_env()) }
000121|     | WHILE LPAREN expression RPAREN statement { For(Value(Void),$3,Value(Void),$5,get_env()) }
000122|     | CONTINUE SEMICOLON                      { Continue(get_env())}
000123|     | BREAK SEMICOLON                         { Break(get_env())}
000124|     | RETURN opt_expression SEMICOLON         { Return($2,get_env()) }
000125|     | IMPORT STRING SEMICOLON                 { Import(resolve_import($2,$1,get_env()),get_env()) }
000126|     | TEMPLATE ID LBRACE template_specs RBRACE { TemplateDef($2, $4,get_env()) }
000127|     | INSTRUCTIONS FOR ID LPAREN arglist RPAREN LBRACE instruction_specs RBRACE
000128|                                               { Instructions($3,$5,$8,get_env()) }
000129|     | SWITCH LPAREN expression RPAREN LBRACE switch_statements RBRACE
000130|                                               { Switch($3,$6, get_env()) }      
000131|     | FOR LPAREN opt_expression SEMICOLON 
000132|                  opt_expression SEMICOLON 
000133|                  opt_expression RPAREN statement { For($3,$5,$7,$9,get_env()) }     
000134|     | TRY statement_block CATCH LPAREN ID RPAREN statement_block { TryCatch($2,$5,$7, get_env()) }
000135|     | TRY statement_block FINALLY statement_block { TryFinally($2,$4,get_env()) }                       
000136|     | THROW expression SEMICOLON              { Throw($2, get_env()) }
000137| ;
000138| switch_statement:
000139|     | CASE expression COLON                   { Case(Some $2,get_env()) }
000140|     | DEFAULT COLON                           { Case(None,get_env()) }
000141|     | statement                               { $1 }
000142| ;
000143| switch_statements:
000144|     | switch_statement                        { [$1] }
000145|     | switch_statement switch_statements      { $1::$2 }
000146| ;
000147| opt_expression:
000148|     | expression                              { $1 }
000149|     | empty_expression                        { Value(Void) }
000150| ;
000151| empty_expression:
000152|     | /*nothing */                            { Value(Void) }
000153| ;
000154| atom_expr:
000155|     | INT                                     { Value(IntegerValue($1)) }
000156|     | REAL                                    { Value(FloatValue($1)) }
000157|     | STRING                                  { Value(StringValue($1)) }
000158|     | BOOLEAN                                 { Value(BooleanValue($1)) }
000159|     | VOID                                    { Value(Void) }
000160|     | LBRACKET expr_list RBRACKET             { ArrayExpr($2) }
000161|     | LBRACE prop_list RBRACE                 { MapExpr($2) }
000162|     | ID                                      { Id($1) }
000163|     | LPAREN expression RPAREN                { $2 }
000164| ;
000165| member_expr:
000166|     | atom_expr                               {$1}
000167|     | FUNCTION LPAREN arglist RPAREN statement_block { Value(FunctionValue($3,extract_stmt_list($5))) }
000168|     | member_expr  LBRACKET expression RBRACKET   { MemberExpr($1,$3) }
000169|     | member_expr DOT ID                      { MemberExpr($1,Value(StringValue($3))) }
000170| ;
000171| call_expr: 
000172|     | member_expr LPAREN fexpr_list RPAREN    { FunctionCall($1,$3) }
000173|     | call_expr LPAREN fexpr_list RPAREN      { FunctionCall($1,$3) }
000174|     | call_expr LBRACKET expression RBRACKET  { MemberExpr($1,$3) }
000175|     | call_expr DOT ID                        { MemberExpr($1,Value(StringValue($3))) }
000176| ; 
000177| lhs_expr:
000178|     | member_expr                             {$1}
000179|     | call_expr                               {$1}
000180| ;
000181| unary_expr:
000182|     | lhs_expr                                { $1 }
000183|     | %prec PREFIX_INCDEC PLUSPLUS lhs_expr   { Assignment($2,BinaryOp($2,Plus,Value(IntegerValue(1)))) }
000184|     | %prec PREFIX_INCDEC MINUSMINUS lhs_expr { Assignment($2,BinaryOp($2,Minus,Value(IntegerValue(1)))) }
000185|     | %prec POSTFIX_INCDEC lhs_expr PLUSPLUS  { PostFixSum($1,1) }
000186|     | %prec POSTFIX_INCDEC lhs_expr MINUSMINUS { PostFixSum($1,-1) }
000187| ;
000188| op_expr:
000189|     | unary_expr                              {$1}
000190|     | op_expr PLUS op_expr              { BinaryOp($1,Plus,$3) }
000191|     | op_expr MINUS op_expr             { BinaryOp($1,Minus,$3) }
000192|     | op_expr TIMES op_expr             { BinaryOp($1,Times,$3) }
000193|     | op_expr DIVIDE op_expr            { BinaryOp($1,Divide,$3) }
000194|     | op_expr MODULO op_expr            { BinaryOp($1,Modulo,$3) }
000195|     | op_expr COMPOP op_expr            { CompOp($1,$2,$3) }
000196|     | NOT lhs_expr                      { Not($2) }
000197|     | op_expr  AND op_expr              { BinaryOp($1,And,$3) }
000198|     | op_expr OR op_expr                { BinaryOp($1,Or,$3) }
000199|     | %prec UMINUS MINUS op_expr        { BinaryOp(Value(IntegerValue(0)),Minus,$2) }
000200| ;
000201| cond_expr:
000202|     | op_expr {$1} 
000203|     | expression QUESTION expression COLON expression
000204|                                         { TernaryCond($1,$3,$5) }                                                                                                   
000205| ;
000206| expression:
000207|     | cond_expr                               {$1}
000208|     | lhs_expr EQUALS expression              { Assignment($1,$3) } 
000209|     | lhs_expr EQUALS empty_statement_block   { Assignment($1,MapExpr([])) }
000210|     | VAR lhs_expr EQUALS expression          { Declaration($2,$4) }
000211|     | VAR lhs_expr EQUALS empty_statement_block { Declaration($2,MapExpr([])) }
000212|     | lhs_expr TIMESEQUALS expression         { Assignment($1,(BinaryOp($1,Times,$3))) }
000213|     | lhs_expr MODEQUALS expression           { Assignment($1,(BinaryOp($1,Modulo,$3))) } 
000214|     | lhs_expr DIVEQUALS expression           { Assignment($1,(BinaryOp($1,Divide,$3))) } 
000215|     | lhs_expr PLUSEQUALS expression          { Assignment($1,(BinaryOp($1,Plus,$3))) } 
000216|     | lhs_expr MINUSEQUALS expression         { Assignment($1,(BinaryOp($1,Minus,$3))) } 
000217| ;
000218| arglist:                              
000219|     | ID                                      { [$1] }
000220|     | ID DOTDOTDOT                            { ["["^$1] } 
000221|     | ID COMMA arglist                        { $1::$3 }
000222|     | /* nothing */                           { [] }
000223| ;
000224| expr_list:
000225|     | expression                              { [$1] }
000226|     | empty_statement_block                   { [MapExpr([])] }
000227|     | expression COMMA expr_list              { $1::$3 }
000228|     | /*nothing*/                             { [] }
000229| ;
000230| fexpr:
000231|     | expression                              { $1 }
000232|     | empty_statement_block                   { MapExpr([]) }
000233|     | AT ID                                   { UnboundVar($2) }
000234|     | AT ID DOTDOTDOT                         { UnboundVar("["^$2) }
000235| ;
000236| fexpr_list:
000237|     | fexpr                                   { [$1] }
000238|     | fexpr COMMA fexpr_list                  { $1::$3 }
000239|     | /*nothing*/                             { [] }
000240| ;
000241| property:                             
000242|     | ID COLON expression                     { ($1,$3) }
000243|     | ID COLON empty_statement_block          { ($1,MapExpr([])) }
000244| ;
000245| prop_list:                            
000246|     | property                                { [$1] }
000247|     | property COMMA prop_list                { $1::$3 }
000248| ;
000249| template_spec:                        
000250|     | label TEXT                              { (Some $1,$2 ^ "\n") }
000251|     | TEXT                                    { (None, $1 ^ "\n") }
000252| ;
000253| template_specs:                       
000254|     | template_spec                           { [$1] }
000255|     | template_spec template_specs            { $1::$2 }
000256| ;   
000257| instruction_spec:                     
000258|     | label repl_condition COLON replacement_list SEMICOLON { ($1,$2,$4) }
000259|     | label repl_condition SEMICOLON          { ($1,$2,[]) }
000260| ;
000261| repl_condition:                       
000262|     | ONCE                                    { Once }
000263|     | WHEN LPAREN expression RPAREN           { When($3) }
000264|     | FOREACH LPAREN ID IN expression RPAREN  { Loop($3,$5) }
000265|     | FOREACH LPAREN ID IN expression RPAREN WHEN LPAREN expression RPAREN
000266|                                               { CondLoop($9,$3,$5) }  
000267| ;
000268| replacement:                          
000269|     | ID EQUALS expression                    { ($1,$3) }
000270| ;
000271| replacement_list:                
000272|     | /* nothing */                           { [] }
000273|     | replacement                             { [$1] }
000274|     | replacement COMMA replacement_list      { $1::$3 }
000275| ;
000276| instruction_specs:                    
000277|     | instruction_spec                        { [$1] }
000278|     | instruction_spec instruction_specs      { $1::$2 }
000279| ; 
000280| label:
000281|     | ID                                      { $1 }
000282|     | INT                                     { string_of_int($1) }
000283| ;
000284| %%

Legend:
   some code - line containing no point
   some code - line containing only visited points
   some code - line containing only unvisited points
   some code - line containing both visited and unvisited points