include 'ragel.lm' rl ident /( alpha | '_' ) ( alpha | digit | '_' )*/ rl number / digit+ / rl hex_number / '0x' [0-9a-fA-F]+ / rl hex_char / '0x' [0-9a-fA-F]{2} / rl NL / '\n' / rl c_comment / '/*' ( any | NL )* :>> '*/' / rl cpp_comment / '//' [^\n]* NL / rl ruby_comment / '#' [^\n]* NL / rl s_literal / "'" ([^'\\\n] | '\\' (any | NL))* "'" / rl d_literal / '"' ([^"\\] | NL | '\\' (any | NL))* '"' / rl host_re_literal / '/' ([^/\\] | NL | '\\' (any | NL))* '/' / namespace inline lex literal `fpc `fc `fcurs `ftargs `fentry `fhold `fexec `fgoto `fnext `fcall `fret `fbreak `fncall `fnret `fnbreak token ident /ident/ token number /digit+/ token hex_number /'0x' [0-9a-fA-F]+/ token dec_number /'0x' [0-9a-fA-F]+/ token comment / c_comment | cpp_comment / token string / s_literal | d_literal / token whitespace / ( [ \t] | NL )+ / literal `{ `} `:: `* `, `( `) `; token var_ref / "$" [a-zA-Z_][a-zA-Z_0-9]* / { if GblActionParams { input->push( make_token( typeid, input->pull( match_length ) ) ) } else { # Just pull one char. Don't consume the word because it may # be a keyword. input->push( make_token( typeid, input->pull( 1 ) ) ) } } token c_any / any / end end namespace host lex literal `%%{ token close_inc /'}--%%'/ { input->push( make_token( typeid, input->pull( match_length ) ) ) restoreGlobals() } token close_imp /'}++%%'/ { input->push( make_token( typeid, input->pull( match_length ) ) ) restoreGlobals() } token slr / '%%' [^{] [^\n]* '\n' / { # Translates single line to multi-line input->pull( 2 ) R: str = input->pull( match_length - 3 ) input->push( "\n}%%" ) input->push( R ) input->push( "%%{" ) } rl NL / '\n' / rl s_literal / "'" ([^'\\\n] | '\\' (any | NL))* "'" / rl d_literal / '"' ([^"\\] | NL | '\\' (any | NL))* '"' / literal `define `= token ident /ident "'"?/ token number /digit+/ token hex_number /'0x' [0-9a-fA-F]+/ token comment / c_comment | cpp_comment / token string / s_literal | d_literal / token whitespace / ( [ \t] | NL )+ / token c_any / any / end token no_match // def tok [no_match ident whitespace number] :ImportNum | [no_match ident whitespace string] :ImportStr | [no_match ident] :Else | [`define whitespace ident whitespace? number] :ImportDefNum | [`define whitespace ident whitespace? string] :ImportDefStr | [ident whitespace? `= whitespace? number] :ImportAssignNum | [ident whitespace? `= whitespace? string] :ImportAssignStr | [`define] :Def | [`=] :Eq | [ident] :Ident | [number] :Number | [hex_number] :HexNumber | [comment] :Comment | [string] :String | [whitespace] :Whitespace | [c_any] :Any { NM: no_match = make_token( typeid, "" ) I: ident = make_token( typeid, $lhs.c_any ) lhs = cons tok [NM I] } end namespace indep # Opening the test case header. lex ignore / ( [ \t] | NL )+ / token c_comm_open / '/*' / end # Contents of test case heaer. lex token comm_name /'@' [A-Za-z0-9_]+ ':' / token comm_term /'*/'/ token comm_any / any / end token comm_val /[^\n]* '\n' / lex literal `%%{ `}%% literal `int `bool `char `ptr `byte `if `else `print_int `print_buf `print_str `print_token `print_off `first_token_char `buffer `blen `buf_append `buf_clear literal `fpc `fc `fcurs `ftargs `fentry `fhold `fexec `fgoto `fnext `fcall `fret `fbreak `fncall `fnret `fnbreak literal `; `< `> `( `) `[ `] `= `* `! `{ `} `+ `- `== `!= `>= `<= `, ignore / ( [ \t] | NL )+ / token tk_ident /ident/ token tk_number /digit+/ token tk_hex_number /'0x' [0-9a-fA-F]+/ rl INPUT /'INPUT'/ rl OUTPUT /'OUTPUT'/ token sect_INPUT / '#'+ ' '* INPUT ' '* '#'+ '\n' / token sect_OUTPUT / '#'+ ' '* OUTPUT ' '* '#'+ '\n' / -ni token string / s_literal | d_literal / ignore / cpp_comment / ignore / c_comment / end lex token output_line /[^\n]* '\n'/ end def comm_def [comm_name comm_val] def comm_item [comm_def] | [comm_any] def test_header [c_comm_open comm_item* comm_term] def input_string [string] def input_list [input_list input_string] | [input_string] def input [input_list] def output [output_line*] def factor [`first_token_char] | [`buffer] | [`blen] | [tk_ident] | [tk_ident `[ expr `]] | [tk_ident `( expr `)] | [tk_number] | [`- tk_number] | [tk_hex_number] | [string] | [`< type `> `( expr `)] | [`( expr `)] | [ragel_factor] def ragel_factor [`fentry `( expr `)] | [`fc] | [`fcurs] | [`ftargs] def mult_op [`*] def add_op [`+] | [`-] def cmp_op [`<] | [`>] | [`!=] | [`==] | [`<=] | [`>=] def abs_op [mult_op] | [add_op] | [cmp_op] abs_expr abs_multiplicative( Expr: indep::multiplicative ) { if ( !Expr.Op ) { return cons abs_expr [Expr.factor] } else { return cons abs_expr [ abs_multiplicative( Expr._multiplicative ) Expr.Op Expr.factor ] } } abs_expr abs_additive( Expr: indep::additive ) { if ( !Expr.Op ) { return cons abs_expr [ abs_multiplicative( Expr.multiplicative ) ] } else { return cons abs_expr [ abs_additive( Expr._additive ) Expr.Op abs_multiplicative( Expr.multiplicative ) ] } } abs_expr abs_comparative( Expr: indep::comparative ) { if ( !Expr.Op ) { return cons abs_expr [ abs_additive( Expr.additive ) ] } else { return cons abs_expr [ abs_comparative( Expr._comparative ) Expr.Op abs_additive( Expr.additive ) ] } } def multiplicative [multiplicative Op: mult_op factor] | [factor] def additive [additive Op: add_op multiplicative] | [multiplicative] def comparative [comparative Op: cmp_op additive] | [additive] def abs_expr [E1: abs_expr Op: abs_op E2: abs_expr] | [factor] def expr [comparative] def type [`int] | [`bool] | [`char] | [`ptr] | [`byte] def opt_arr [`[ expr `]] | [] def var_decl [type tk_ident opt_arr `;] def opt_sub [ `[ expr `] ] | [] def expr_stmt [tk_ident opt_sub `= expr `;] | [expr `;] def if_stmt [`if `( expr `) `{ stmt* `} opt_else] def opt_else [`else `{ stmt* `}] | [] def print_stmt [`print_int expr `;] | [`print_buf `;] | [`print_str expr `;] | [`print_token `;] | [`print_off `;] def ragel_stmt [`fgoto tk_ident `;] | [`fcall tk_ident `;] | [`fncall tk_ident `;] | [`fnext tk_ident `;] | [`fgoto `* expr `;] | [`fcall `* expr `;] | [`fncall `* expr `;] | [`fnext `* expr `;] | [`fexec expr `;] | [`fhold `;] | [`fbreak `;] | [`fnbreak `;] | [`fret `;] | [`fnret `;] def buf_stmt [`buf_append `( `) `;] | [`buf_clear `( `) `;] def stmt [var_decl] | [expr_stmt] | [if_stmt] | [print_stmt] | [buf_stmt] | [ragel_stmt] def action_block [`{ stmt* `}] | [`{ expr `}] def section [`%%{ ragel::ragel_start `}%%] def start [ test_header Init: stmt* section sect_INPUT input sect_OUTPUT output ] end namespace out_code lex token line /[^\n]* '\n'/ end def lines [line*] alias line_parser parser end global Out: parser include 'trans-c.lm' include 'trans-asm.lm' include 'trans-d.lm' include 'trans-csharp.lm' include 'trans-go.lm' include 'trans-java.lm' include 'trans-ruby.lm' include 'trans-ocaml.lm' include 'trans-rust.lm' include 'trans-julia.lm' include 'trans-crack.lm' str argvPop() { AE: list_el = argv->pop_el() return AE->value } Lang: str = argvPop() OutputFile: str = argvPop() InputFile: str = argvPop() global ClassName: str = argvPop() Input: stream = open( InputFile, "r" ) Output: stream = open( OutputFile, "w" ) global RagelTree: indep::start = parse indep::start[ Input ] if ( !RagelTree ) { print( error, '\n' ) exit(1) } # Find the machine name. global MachineName: ragel::machine_name = ragel::machine_name in RagelTree global NeedsEof: bool = false global ProhibitGenflags: str for CommDef: indep::comm_def in RagelTree { switch CommDef case "@NEEDS_EOF: yes\n" { NeedsEof = true } case "@PROHIBIT_GENFLAGS:[CV: comm_val]" { ProhibitGenflags = $CV } } if ( Lang == 'c' ) rw_c( Output ) elsif ( Lang == 'cg' ) rw_c( Output ) elsif ( Lang == 'cv' ) rw_c( Output ) elsif ( Lang == 'asm' ) rw_asm( Output ) elsif ( Lang == 'd' ) rw_d( Output ) elsif ( Lang == 'csharp' ) rw_csharp( Output ) elsif ( Lang == 'go' ) rw_go( Output ) elsif ( Lang == 'java' ) rw_java( Output ) elsif ( Lang == 'ruby' ) rw_ruby( Output ) elsif ( Lang == 'ocaml' ) rw_ocaml( Output ) elsif ( Lang == 'rust' ) trans_rust::rust( Output ) elsif ( Lang == 'julia' ) trans_julia::julia( Output ) elsif ( Lang == 'crack' ) trans_crack::crack( Output ) else { print( 'trans: unrecognized language: ', Lang, '\n' ) }