First public commit!
This commit is contained in:
427
Grammar/tiger.g
Normal file
427
Grammar/tiger.g
Normal file
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
* Yet Another Tiger Compiler (YATC)
|
||||
*
|
||||
* Copyright 2014 Damian Valdés Santiago, Juan Carlos Pujol Mainegra
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
grammar tiger;
|
||||
|
||||
options
|
||||
{
|
||||
language = CSharp3;
|
||||
//language = Java;
|
||||
output = AST;
|
||||
k = 3;
|
||||
}
|
||||
|
||||
tokens
|
||||
{
|
||||
// para uso del tree adaptor
|
||||
ALIAS_DECL;
|
||||
ARRAY_ACCESS;
|
||||
ARRAY_DECL;
|
||||
ARRAY_INST;
|
||||
BREAK;
|
||||
EXPR_SEQ;
|
||||
FIELD_ACCESS;
|
||||
FIELD_ACCESS_TERMINAL;
|
||||
FIELD_INST;
|
||||
FILL_IN_TYPE;
|
||||
FOR;
|
||||
FUN_CALL;
|
||||
FUN_DECL;
|
||||
FUN_DECL_SEQ;
|
||||
IF;
|
||||
LET;
|
||||
NEG;
|
||||
NIL;
|
||||
PROGRAM;
|
||||
RECORD_DECL;
|
||||
RECORD_INST;
|
||||
TYPE;
|
||||
TYPE_DECL;
|
||||
TYPE_DECL_SEQ;
|
||||
TYPE_FIELD;
|
||||
VAR_ACCESS;
|
||||
VAR_DECL;
|
||||
WHILE;
|
||||
|
||||
// para vista
|
||||
ARGS_FIELDS;
|
||||
DECL_BLOCK;
|
||||
FIELDS_INST;
|
||||
FUN_TYPE_WRAPPER;
|
||||
PARAM_DECL;
|
||||
}
|
||||
|
||||
@lexer::header
|
||||
{
|
||||
using System;
|
||||
}
|
||||
|
||||
@lexer::namespace{YATC.Grammar}
|
||||
|
||||
@lexer::modifier{public}
|
||||
|
||||
@lexer::ctorModifier{public}
|
||||
|
||||
@lexer::members
|
||||
{
|
||||
public override void ReportError(RecognitionException exc)
|
||||
{
|
||||
/* Abort on first error. */
|
||||
throw new ParsingException(GetErrorMessage(exc, TokenNames), exc);
|
||||
}
|
||||
}
|
||||
|
||||
@parser::header
|
||||
{
|
||||
using System;
|
||||
}
|
||||
|
||||
@parser::namespace{YATC.Grammar}
|
||||
|
||||
@parser::modifier{public}
|
||||
|
||||
@parser::ctorModifier{public}
|
||||
|
||||
@parser::members
|
||||
{
|
||||
public override void ReportError(RecognitionException exc)
|
||||
{
|
||||
/* Abort on first error. */
|
||||
throw new ParsingException(GetErrorMessage(exc, TokenNames), exc);
|
||||
}
|
||||
}
|
||||
|
||||
fragment BEGIN_COMMENT
|
||||
: '/*'
|
||||
;
|
||||
|
||||
fragment END_COMMENT
|
||||
: '*/'
|
||||
;
|
||||
|
||||
// binary ops
|
||||
PLUS : '+' ;
|
||||
MINUS : '-' ;
|
||||
MULT : '*' ;
|
||||
DIV : '/' ;
|
||||
|
||||
// binary comparison
|
||||
EQ : '=' ;
|
||||
NOTEQ : '<>' ;
|
||||
GT : '>' ;
|
||||
GTEQ : '>=' ;
|
||||
LT : '<' ;
|
||||
LTEQ : '<=' ;
|
||||
|
||||
// logical ops
|
||||
AND : '&' ;
|
||||
OR : '|' ;
|
||||
|
||||
// grouping symbols
|
||||
LPAREN : '(' ;
|
||||
RPAREN : ')' ;
|
||||
LBRACKET : '[' ;
|
||||
RBRACKET : ']' ;
|
||||
LKEY : '{' ;
|
||||
RKEY : '}' ;
|
||||
|
||||
// separators
|
||||
COMMA : ',' ;
|
||||
SEMI : ';' ;
|
||||
COLON : ':' ;
|
||||
DOT : '.' ;
|
||||
fragment
|
||||
QUOTE : '\"';
|
||||
|
||||
ASSIGN : ':=' ;
|
||||
|
||||
// keywords
|
||||
ARRAYKEY : 'array';
|
||||
BREAKKEY : 'break';
|
||||
DOKEY : 'do';
|
||||
ELSEKEY : 'else';
|
||||
ENDKEY : 'end';
|
||||
FORKEY : 'for';
|
||||
FUNCTIONKEY : 'function';
|
||||
IFKEY : 'if';
|
||||
INKEY : 'in';
|
||||
INTKEY : 'int';
|
||||
LETKEY : 'let';
|
||||
NILKEY : 'nil';
|
||||
OFKEY : 'of';
|
||||
STRINGKEY : 'string';
|
||||
THENKEY : 'then';
|
||||
TOKEY : 'to';
|
||||
TYPEKEY : 'type';
|
||||
VARKEY : 'var';
|
||||
WHILEKEY : 'while';
|
||||
|
||||
fragment
|
||||
DIGIT
|
||||
: '0'..'9'
|
||||
;
|
||||
|
||||
fragment
|
||||
LETTER
|
||||
: 'a'..'z'|'A'..'Z'
|
||||
;
|
||||
|
||||
fragment
|
||||
ASCII_ESC
|
||||
: '12' '0'..'7'
|
||||
| '1' '0'..'1' '0'..'9'
|
||||
| '0' '0'..'9' '0'..'9'
|
||||
;
|
||||
|
||||
INT
|
||||
: DIGIT+
|
||||
;
|
||||
|
||||
ID : LETTER ( LETTER | DIGIT | '_' ) *
|
||||
;
|
||||
|
||||
WS
|
||||
: ( ' '|'\t'|'\r'|'\n' ) +
|
||||
{$channel = Hidden;}
|
||||
//{$channel = HIDDEN;}
|
||||
;
|
||||
|
||||
fragment
|
||||
ESC_SEQ
|
||||
: '\\' ( 'n' | 'r' | 't' | QUOTE | ASCII_ESC | WS '\\' )
|
||||
;
|
||||
|
||||
fragment
|
||||
PRINTABLE_CHARACTER
|
||||
: ((' '..'!') | ('#'.. '[') | (']'..'~'))
|
||||
;
|
||||
|
||||
STRING : QUOTE ( ESC_SEQ | PRINTABLE_CHARACTER )* QUOTE ;
|
||||
|
||||
COMMENTARY
|
||||
: BEGIN_COMMENT
|
||||
( options {greedy=false;} : . )*
|
||||
( COMMENTARY ( options {greedy=false;} : . )* )*
|
||||
END_COMMENT
|
||||
{$channel = Hidden;}
|
||||
//{$channel = HIDDEN;}
|
||||
;
|
||||
|
||||
public a_program
|
||||
: expr ? EOF
|
||||
-> ^(PROGRAM expr ?) ;
|
||||
|
||||
expr
|
||||
: (ID LBRACKET disjunction_expr RBRACKET OFKEY) => array_inst
|
||||
| (lvalue ASSIGN) => assignment
|
||||
| disjunction_expr
|
||||
| record_inst
|
||||
| while_stat
|
||||
| BREAKKEY
|
||||
-> BREAK
|
||||
;
|
||||
|
||||
disjunction_expr
|
||||
: conjunction_expr (OR^ conjunction_expr)*
|
||||
;
|
||||
|
||||
assignment
|
||||
: lvalue ASSIGN^
|
||||
( (ID LBRACKET disjunction_expr RBRACKET OFKEY) => array_inst
|
||||
| disjunction_expr
|
||||
| record_inst
|
||||
)
|
||||
;
|
||||
|
||||
record_inst
|
||||
: ID LKEY field_inst_list? RKEY
|
||||
-> ^(RECORD_INST ID field_inst_list?)
|
||||
;
|
||||
|
||||
/*
|
||||
Queremos que en un for solo se puedan evaluar condiciones retornen valor,
|
||||
por ello que pedimos que la primera y segunda expresiones sean disjunction_expr,
|
||||
para evitar de que no devuelva por otros motivos.
|
||||
*/
|
||||
for_expr
|
||||
: FORKEY type_id ASSIGN disjunction_expr TOKEY disjunction_expr DOKEY expr
|
||||
-> ^(FOR type_id disjunction_expr disjunction_expr expr)
|
||||
;
|
||||
|
||||
array_inst
|
||||
: ID LBRACKET disjunction_expr RBRACKET OFKEY expr
|
||||
-> ^(ARRAY_INST ID disjunction_expr expr)
|
||||
;
|
||||
|
||||
conjunction_expr
|
||||
: relational_expr (AND^ relational_expr)*
|
||||
;
|
||||
|
||||
/*
|
||||
El operador ? al final de la expresion le da la no asociatividad requerida
|
||||
a los operadores de comparacion (notar que en los demas se usa * para
|
||||
anidarlos en una lista). Esto es que no se permite a = b = c, pero si a = (b = c).
|
||||
*/
|
||||
relational_expr
|
||||
: arith_expr ((EQ | NOTEQ | GT | LT | GTEQ | LTEQ )^ arith_expr)?
|
||||
;
|
||||
|
||||
arith_expr
|
||||
: term_expr ((PLUS | MINUS)^ term_expr)*
|
||||
;
|
||||
|
||||
term_expr
|
||||
: atom ((MULT | DIV)^ atom)*
|
||||
;
|
||||
|
||||
field_inst_list
|
||||
: record_field_inst ( COMMA record_field_inst )*
|
||||
-> ^(FIELDS_INST record_field_inst+)
|
||||
;
|
||||
|
||||
record_field_inst
|
||||
: ID EQ expr
|
||||
-> ^(FIELD_INST ID expr)
|
||||
;
|
||||
|
||||
decl
|
||||
: type_decl+
|
||||
-> ^(TYPE_DECL_SEQ type_decl+)
|
||||
| var_decl
|
||||
| fun_decl+
|
||||
-> ^(FUN_DECL_SEQ fun_decl+)
|
||||
;
|
||||
|
||||
type_decl
|
||||
: TYPEKEY ID EQ type
|
||||
-> ^(TYPE_DECL ID type)
|
||||
;
|
||||
|
||||
var_decl
|
||||
: VARKEY type_id COLON type_id ASSIGN expr
|
||||
-> ^(VAR_DECL type_id type_id expr)
|
||||
| VARKEY type_id ASSIGN expr
|
||||
-> ^(VAR_DECL type_id FILL_IN_TYPE expr)
|
||||
;
|
||||
|
||||
fun_decl
|
||||
: FUNCTIONKEY type_id LPAREN type_fields? RPAREN (COLON type_id)? EQ expr
|
||||
-> ^(FUN_DECL type_id ^(PARAM_DECL type_fields?) ^(FUN_TYPE_WRAPPER type_id?) expr)
|
||||
;
|
||||
|
||||
type_id
|
||||
: STRINGKEY
|
||||
| INTKEY
|
||||
| ID
|
||||
;
|
||||
|
||||
type
|
||||
: type_id
|
||||
-> ^(ALIAS_DECL type_id)
|
||||
| array_decl
|
||||
| record_decl
|
||||
;
|
||||
|
||||
record_decl
|
||||
: LKEY type_fields? RKEY
|
||||
-> ^(RECORD_DECL type_fields?)
|
||||
;
|
||||
|
||||
array_decl
|
||||
: ARRAYKEY OFKEY type_id
|
||||
-> ^(ARRAY_DECL type_id)
|
||||
;
|
||||
|
||||
type_fields
|
||||
: type_field (COMMA type_field)*
|
||||
-> type_field+
|
||||
;
|
||||
|
||||
type_field
|
||||
: type_id COLON type_id
|
||||
-> ^(TYPE_FIELD type_id type_id)
|
||||
;
|
||||
|
||||
atom
|
||||
: MINUS atom
|
||||
-> ^(NEG atom)
|
||||
| constant_value
|
||||
| lvalue
|
||||
| funcall
|
||||
| if_then_expr
|
||||
| for_expr
|
||||
| let_expr
|
||||
| LPAREN expr_seq RPAREN
|
||||
-> expr_seq
|
||||
;
|
||||
|
||||
constant_value
|
||||
: STRING
|
||||
| INT
|
||||
| NILKEY
|
||||
;
|
||||
|
||||
if_then_expr
|
||||
: IFKEY conditional=disjunction_expr THENKEY then_expr=expr (ELSEKEY else_expr=expr)?
|
||||
-> ^(IF $conditional $then_expr $else_expr?)
|
||||
;
|
||||
|
||||
while_stat
|
||||
: WHILEKEY cond=disjunction_expr DOKEY do_expr=expr
|
||||
-> ^(WHILE $cond $do_expr)
|
||||
;
|
||||
|
||||
let_expr
|
||||
: LETKEY decl+ INKEY expr_seq ENDKEY
|
||||
-> ^(LET ^(DECL_BLOCK decl+) expr_seq)
|
||||
;
|
||||
|
||||
lvalue
|
||||
: type_id lvalue_access? -> ^(VAR_ACCESS type_id lvalue_access?)
|
||||
;
|
||||
|
||||
lvalue_access
|
||||
: DOT type_id lvalue_access?
|
||||
-> ^(FIELD_ACCESS type_id lvalue_access?)
|
||||
| LBRACKET disjunction_expr RBRACKET lvalue_access?
|
||||
-> ^(ARRAY_ACCESS disjunction_expr lvalue_access?)
|
||||
;
|
||||
|
||||
funcall
|
||||
: type_id LPAREN arg_list? RPAREN
|
||||
-> ^(FUN_CALL type_id arg_list?)
|
||||
;
|
||||
|
||||
expr_seq
|
||||
: expr (SEMI expr)*
|
||||
-> ^(EXPR_SEQ expr+)
|
||||
| -> ^(EXPR_SEQ )
|
||||
;
|
||||
|
||||
arg_list
|
||||
: expr (COMMA expr)*
|
||||
-> ^(ARGS_FIELDS expr+)
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user