/* * Copyright (C) 2005 Sara di Gregorio * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ header { package ruby; } // l'header indica quello che si deve scrivere come // intestazione dei file che ANTLR crea automaticamente /** * PARSER **/ class P extends Parser; options { k = 6; // pone a 6 il lookahead di token buildAST = true; } imaginaryTokenDefinition: PROGRAM; // inzio di un programma ruby program : ( classe | statement)* {#program = #(#[PROGRAM, "PROGRAM"], #program);} ; classe: "class"^ (IDENTIFIER | IDENTIFIER "<" IDENTIFIER ("<" IDENTIFIER!)*) (statement)* body_class "end" ; // il corpo della classe body_class : (definition)+ ; definition: (statement)* "def"^ IDENTIFIER (IDENTIFIER)* ( "("! (IDENTIFIER)+ (","! IDENTIFIER)* ")"! )* statement (statement)* "end" ; // istruzioni che si possono trovare nel corpo del programma 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 ; // condizioni o operazioni che si possono scrivere nei costrutti condition : "("! condition ")"! ((operator | booleano) (IDENTIFIER | NUMBER))? | IDENTIFIER booleano IDENTIFIER | IDENTIFIER booleano NUMBER | NUMBER booleano IDENTIFIER | NUMBER booleano NUMBER | instruction | IDENTIFIER booleano instruction ; // istruzioni matematiche instruction : NUMBER operator NUMBER | IDENTIFIER operator NUMBER | NUMBER operator IDENTIFIER | IDENTIFIER operator IDENTIFIER ; // operatori che si possono trovare nelle condizioni booleano : "<"^ | "<="^ | ">="^ | ">"^ | "=="^ | "%"^ | "&"^ | "|"^; // | "("! // | ")"! // ; // ciò che può essere scritto con il "return" ret : IDENTIFIER | NUMBER | instruction | "true" | "false" | "("! IDENTIFIER ")"! | "("! NUMBER ")"! | "("! "true" ")"! | "("! "false" ")"! ; // operatori matematici operator : "/"^ | "*"^ | "+"^ | "-"^ | "%"^ ; /** * LEXER **/ class RubyLexer extends Lexer; options { k = 6; // sei caratteri di lookahead } // gestione degli spazi tra le varie parole WS : ' '{ _ttype = Token.SKIP; } ; LPAREN : '(' ; RPAREN : ')' ; LT : '<' ; LE : "<=" ; GE : ">=" ; GT : '>' ; EGUAL : "==" ; DIV : '/' ; MUL : '*' ; ASSIGN : '=' ; PLUS : '+' ; OR : '|' // questo simbolo non ha solo la funzionalità dell'OR! ; AND : '&' ; SUB : '-' ; MOD : '%' ; NUMBER : ('0'..'9')+ ; // Identificatori IDENTIFIER : ("@")* ('a'..'z'|'A'..'Z'|'.')+ (NUMBER)*; // Stringhe STRING : '"' (('a'..'z'|'A'..'Z')+)* '"' | '\'' (('a'..'z'|'A'..'Z')+)* '\''; // regola per il ritorno a capo 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) ;