lex token c_single_lit /( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )/ token c_double_lit /( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )/ token sym / ';' | ',' | '=' | '(' | ')' | ':' | '&' | '*' | '[' | ']' | '~' | '+' | '-' | '/' | '<' | '>' | '|' | '^' | '!' | '?' | '.' | '#'/ # Identifiers token c_id /( [a-zA-Z_] [a-zA-Z0-9_]* )/ # Comments and whitespace. token comm_c /( '/*' (any | '\n')* :>> '*/' )/ token comm_cxx /( '//' any* :> '\n' )/ token ws /( any - 33..126 )+/ end def c_token [c_single_lit] | [c_double_lit] | [sym] | [c_id] | [comm_c] | [comm_cxx] | [ws] def c_token_list [c_token c_token_list] | [c_token] # Can parse this, use ful for single constructs. #def c # [c_token*] def c [c_token_list] lex literal `%% literal `{ `} literal `protocol `client `server `port `by `tcp `udp token id /[A-Za-z_][A-Za-z_0-9]*/ token number /[0-9]+/ ignore /'/*' any* :>> '*/'/ ignore /[ \t\r\n]+/ end def tcp_by_port [`tcp `by `port] def udp_by_port [`udp `by `port] def attribute [`client id] | [`server id] | [`port number] | [`udp id] | [tcp_by_port] | [udp_by_port] def tcp_protocol [`tcp `protocol id `{ attribute* `}] def udp_protocol [`udp `protocol id `{ attribute* `}] def protocol [tcp_protocol] | [udp_protocol] def program [c `%% protocol*] def port Port: int Protocol: str [] # Parse the input. parse P: program[ stdin ] Output: parser = new parser() # Take off the leading C from the input file and send it out. match P [C: c '%%' protocol*] send Output [ $C "#include " ] eos print( Output->tree ) ##### IN ##### #include "some_header.h" %% tcp protocol FOO { port 99 client c server s } ##### EXP ##### #include "some_header.h" #include