header { package ruby; } /** * PARSER **/ class P extends Parser; options { k = 6; buildAST = true; } imaginaryTokenDefinition: PROGRAM; program : ( classe | statement)* {#program = #(#[PROGRAM, "PROGRAM"], #program);} ; classe: "class"^ (IDENTIFIER | IDENTIFIER "<" IDENTIFIER ("<" IDENTIFIER!)*) (statement)* body_class "end" ; body_class : (definition)+ ; definition: (statement)* "def"^ IDENTIFIER (IDENTIFIER)* ( "("! (IDENTIFIER)+ (","! IDENTIFIER)* ")"! )* statement (statement)* "end" ; statement : ("if"^ | "while"^) condition (statement)+ "end" | "loop" "do"^ (statement)+ "end" | "yield"^ "("! (IDENTIFIER | instruction) ")"! | "return"^ ret | IDENTIFIER "="^ (NUMBER | IDENTIFIER | STRING) | IDENTIFIER "="^ instruction | IDENTIFIER "="^ "("! (IDENTIFIER | NUMBER | STRING) ")"! | IDENTIFIER "="^ "("! instruction ")"! | IDENTIFIER "="^ IDENTIFIER "("! (IDENTIFIER)+ (","! IDENTIFIER)* ")"! | IDENTIFIER ( "("! (IDENTIFIER | NUMBER)+ (","! (IDENTIFIER | NUMBER))* ")"! )* "do"^ "|"! IDENTIFIER "|"! (statement)* "end" | IDENTIFIER ; condition : "("! condition ")"! ((operator | booleano) (IDENTIFIER | NUMBER))? | IDENTIFIER booleano IDENTIFIER | IDENTIFIER booleano NUMBER | NUMBER booleano IDENTIFIER | NUMBER booleano NUMBER | instruction | IDENTIFIER booleano instruction ; instruction : NUMBER operator NUMBER | IDENTIFIER operator NUMBER | NUMBER operator IDENTIFIER | IDENTIFIER operator IDENTIFIER ; booleano : "<"^ | "<="^ | ">="^ | ">"^ | "=="^ | "%"^ | "&"^ | "|"^; // | "("! // | ")"! // ; ret : IDENTIFIER | NUMBER | instruction | "true" | "false" | "("! IDENTIFIER ")"! | "("! NUMBER ")"! | "("! "true" ")"! | "("! "false" ")"! ; operator : "/"^ | "*"^ | "+"^ | "-"^ | "%"^ ; /** * LEXER **/ class RubyLexer extends Lexer; options { k = 6; } WS : ' '{ _ttype = Token.SKIP; } ; LPAREN : '(' ; RPAREN : ')' ; LT : '<' ; LE : "<=" ; GE : ">=" ; GT : '>' ; EGUAL : "==" ; DIV : '/' ; MUL : '*' ; ASSIGN : '=' ; PLUS : '+' ; OR : '|' ; AND : '&' ; SUB : '-' ; MOD : '%' ; NUMBER : ('0'..'9')+ ; IDENTIFIER : ("@")* ('a'..'z'|'A'..'Z'|'.')+ (NUMBER)*; STRING : '"' (('a'..'z'|'A'..'Z')+)* '"' | '\'' (('a'..'z'|'A'..'Z')+)* '\''; NEWLINE : ( "\r\n" // DOS | '\r' // MAC | '\n' // Unix ); /** * PARSE TREE **/ class RubyParseTree extends TreeParser; program: #(PROGRAM (classe | statement)*) ; classe: #("class" (IDENTIFIER)* "<" (statement)* body_class "end") ; body_class: #("def" definition) ; definition: #("def" (IDENTIFIER)* "(" ")" "," (statement)* "end") ; statement: #("if" condition (statement)+ "end") | #("while" condition (statement)+ "end") | #("yield" "(" (IDENTIFIER | instruction) ")") // | #("return" ret) | #("=" IDENTIFIER (NUMBER | IDENTIFIER | STRING)) | #("=" IDENTIFIER instruction) | #("=" IDENTIFIER "(" (IDENTIFIER | NUMBER | STRING) ")") | #("=" IDENTIFIER "(" instruction ")") | #("=" IDENTIFIER IDENTIFIER "(" (IDENTIFIER)+ ("," IDENTIFIER)* ")") | #("do" IDENTIFIER ( "(" (IDENTIFIER | NUMBER)+ ("," (IDENTIFIER | NUMBER))* ")" )* "|" IDENTIFIER "|" (statement)* "end") ; condition: #("/" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("*" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("+" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("-" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("%" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("<" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("<" IDENTIFIER IDENTIFIER) | #("<" IDENTIFIER instruction) | #("<=" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("<=" IDENTIFIER IDENTIFIER) | #("<=" IDENTIFIER instruction) | #(">=" "(" condition ")" (IDENTIFIER | NUMBER)?) | #(">=" IDENTIFIER IDENTIFIER) | #(">=" IDENTIFIER instruction) | #(">" "(" condition ")" (IDENTIFIER | NUMBER)?) | #(">" IDENTIFIER IDENTIFIER) | #(">" IDENTIFIER instruction) | #("==" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("==" IDENTIFIER IDENTIFIER) | #("==" IDENTIFIER instruction) | #("%" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("%" IDENTIFIER IDENTIFIER) | #("%" IDENTIFIER instruction) | #("&" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("&" IDENTIFIER IDENTIFIER) | #("&" IDENTIFIER instruction) | #("|" "(" condition ")" (IDENTIFIER | NUMBER)?) | #("|" IDENTIFIER IDENTIFIER) | #("|" IDENTIFIER instruction) ; instruction: #("/" NUMBER NUMBER) | #("/" IDENTIFIER NUMBER) | #("/" NUMBER IDENTIFIER) | #("/" IDENTIFIER IDENTIFIER) | #("*" NUMBER NUMBER) | #("*" IDENTIFIER NUMBER) | #("*" NUMBER IDENTIFIER) | #("*" IDENTIFIER IDENTIFIER) | #("+" NUMBER NUMBER) | #("+" IDENTIFIER NUMBER) | #("+" NUMBER IDENTIFIER) | #("+" IDENTIFIER IDENTIFIER) | #("-" NUMBER NUMBER) | #("-" IDENTIFIER NUMBER) | #("-" NUMBER IDENTIFIER) | #("-" IDENTIFIER IDENTIFIER) | #("%" NUMBER NUMBER) | #("%" IDENTIFIER NUMBER) | #("%" NUMBER IDENTIFIER) | #("%" IDENTIFIER IDENTIFIER) ;