diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4227eb --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ + +#ignore thumbnails created by windows +Thumbs.db +#Ignore files build by Visual Studio +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +[Bb]in +[Dd]ebug*/ +*.lib +*.sbr +obj/ +[Rr]elease*/ +_ReSharper*/ +[Tt]est[Rr]esult* +output/ diff --git a/Grammar/tiger.g b/Grammar/tiger.g new file mode 100644 index 0000000..3f5abc8 --- /dev/null +++ b/Grammar/tiger.g @@ -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+) + ; + diff --git a/Grammar/tiger.tokens b/Grammar/tiger.tokens new file mode 100644 index 0000000..bf2551e --- /dev/null +++ b/Grammar/tiger.tokens @@ -0,0 +1,88 @@ +ALIAS_DECL=4 +AND=5 +ARGS_FIELDS=6 +ARRAYKEY=7 +ARRAY_ACCESS=8 +ARRAY_DECL=9 +ARRAY_INST=10 +ASCII_ESC=11 +ASSIGN=12 +BEGIN_COMMENT=13 +BREAK=14 +BREAKKEY=15 +COLON=16 +COMMA=17 +COMMENTARY=18 +DECL_BLOCK=19 +DIGIT=20 +DIV=21 +DOKEY=22 +DOT=23 +ELSEKEY=24 +ENDKEY=25 +END_COMMENT=26 +EQ=27 +ESC_SEQ=28 +EXPR_SEQ=29 +FIELDS_INST=30 +FIELD_ACCESS=31 +FIELD_ACCESS_TERMINAL=32 +FIELD_INST=33 +FILL_IN_TYPE=34 +FOR=35 +FORKEY=36 +FUNCTIONKEY=37 +FUN_CALL=38 +FUN_DECL=39 +FUN_DECL_SEQ=40 +FUN_TYPE_WRAPPER=41 +GT=42 +GTEQ=43 +ID=44 +IF=45 +IFKEY=46 +INKEY=47 +INT=48 +INTKEY=49 +LBRACKET=50 +LET=51 +LETKEY=52 +LETTER=53 +LKEY=54 +LPAREN=55 +LT=56 +LTEQ=57 +MINUS=58 +MULT=59 +NEG=60 +NIL=61 +NILKEY=62 +NOTEQ=63 +OFKEY=64 +OR=65 +PARAM_DECL=66 +PLUS=67 +PRINTABLE_CHARACTER=68 +PROGRAM=69 +QUOTE=70 +RBRACKET=71 +RECORD_DECL=72 +RECORD_INST=73 +RKEY=74 +RPAREN=75 +SEMI=76 +STRING=77 +STRINGKEY=78 +THENKEY=79 +TOKEY=80 +TYPE=81 +TYPEKEY=82 +TYPE_DECL=83 +TYPE_DECL_SEQ=84 +TYPE_FIELD=85 +VARKEY=86 +VAR_ACCESS=87 +VAR_DECL=88 +WHILE=89 +WHILEKEY=90 +WS=91 diff --git a/Grammar/tigerLexer.cs b/Grammar/tigerLexer.cs new file mode 100644 index 0000000..f08e681 --- /dev/null +++ b/Grammar/tigerLexer.cs @@ -0,0 +1,3313 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// ANTLR Version: 3.4 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +// $ANTLR 3.4 D:\\~Compilador\\!yatc\\Grammar\\tiger.g 2014-03-10 18:42:50 + +// The variable 'variable' is assigned but its value is never used. +#pragma warning disable 219 +// Unreachable code detected. +#pragma warning disable 162 +// Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable 1591 +// CLS compliance checking will not be performed on 'type' because it is not visible from outside this assembly. +#pragma warning disable 3019 + + + using System; + + +using System.Collections.Generic; +using Antlr.Runtime; +using Antlr.Runtime.Misc; + +namespace YATC.Grammar +{ +[System.CodeDom.Compiler.GeneratedCode("ANTLR", "3.4")] +[System.CLSCompliant(false)] +public partial class tigerLexer : Antlr.Runtime.Lexer +{ + public const int EOF=-1; + public const int ALIAS_DECL=4; + public const int AND=5; + public const int ARGS_FIELDS=6; + public const int ARRAYKEY=7; + public const int ARRAY_ACCESS=8; + public const int ARRAY_DECL=9; + public const int ARRAY_INST=10; + public const int ASCII_ESC=11; + public const int ASSIGN=12; + public const int BEGIN_COMMENT=13; + public const int BREAK=14; + public const int BREAKKEY=15; + public const int COLON=16; + public const int COMMA=17; + public const int COMMENTARY=18; + public const int DECL_BLOCK=19; + public const int DIGIT=20; + public const int DIV=21; + public const int DOKEY=22; + public const int DOT=23; + public const int ELSEKEY=24; + public const int ENDKEY=25; + public const int END_COMMENT=26; + public const int EQ=27; + public const int ESC_SEQ=28; + public const int EXPR_SEQ=29; + public const int FIELDS_INST=30; + public const int FIELD_ACCESS=31; + public const int FIELD_ACCESS_TERMINAL=32; + public const int FIELD_INST=33; + public const int FILL_IN_TYPE=34; + public const int FOR=35; + public const int FORKEY=36; + public const int FUNCTIONKEY=37; + public const int FUN_CALL=38; + public const int FUN_DECL=39; + public const int FUN_DECL_SEQ=40; + public const int FUN_TYPE_WRAPPER=41; + public const int GT=42; + public const int GTEQ=43; + public const int ID=44; + public const int IF=45; + public const int IFKEY=46; + public const int INKEY=47; + public const int INT=48; + public const int INTKEY=49; + public const int LBRACKET=50; + public const int LET=51; + public const int LETKEY=52; + public const int LETTER=53; + public const int LKEY=54; + public const int LPAREN=55; + public const int LT=56; + public const int LTEQ=57; + public const int MINUS=58; + public const int MULT=59; + public const int NEG=60; + public const int NIL=61; + public const int NILKEY=62; + public const int NOTEQ=63; + public const int OFKEY=64; + public const int OR=65; + public const int PARAM_DECL=66; + public const int PLUS=67; + public const int PRINTABLE_CHARACTER=68; + public const int PROGRAM=69; + public const int QUOTE=70; + public const int RBRACKET=71; + public const int RECORD_DECL=72; + public const int RECORD_INST=73; + public const int RKEY=74; + public const int RPAREN=75; + public const int SEMI=76; + public const int STRING=77; + public const int STRINGKEY=78; + public const int THENKEY=79; + public const int TOKEY=80; + public const int TYPE=81; + public const int TYPEKEY=82; + public const int TYPE_DECL=83; + public const int TYPE_DECL_SEQ=84; + public const int TYPE_FIELD=85; + public const int VARKEY=86; + public const int VAR_ACCESS=87; + public const int VAR_DECL=88; + public const int WHILE=89; + public const int WHILEKEY=90; + public const int WS=91; + + public override void ReportError(RecognitionException exc) + { + /* Abort on first error. */ + throw new ParsingException(GetErrorMessage(exc, TokenNames), exc); + } + + + // delegates + // delegators + + public tigerLexer() + { + OnCreated(); + } + + public tigerLexer(ICharStream input ) + : this(input, new RecognizerSharedState()) + { + } + + public tigerLexer(ICharStream input, RecognizerSharedState state) + : base(input, state) + { + + OnCreated(); + } + public override string GrammarFileName { get { return "D:\\~Compilador\\!yatc\\Grammar\\tiger.g"; } } + + + partial void OnCreated(); + partial void EnterRule(string ruleName, int ruleIndex); + partial void LeaveRule(string ruleName, int ruleIndex); + + partial void EnterRule_BEGIN_COMMENT(); + partial void LeaveRule_BEGIN_COMMENT(); + + // $ANTLR start "BEGIN_COMMENT" + [GrammarRule("BEGIN_COMMENT")] + private void mBEGIN_COMMENT() + { + EnterRule_BEGIN_COMMENT(); + EnterRule("BEGIN_COMMENT", 1); + TraceIn("BEGIN_COMMENT", 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:103:2: ( '/*' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:103:4: '/*' + { + DebugLocation(103, 4); + Match("/*"); + + + } + + } + finally + { + TraceOut("BEGIN_COMMENT", 1); + LeaveRule("BEGIN_COMMENT", 1); + LeaveRule_BEGIN_COMMENT(); + } + } + // $ANTLR end "BEGIN_COMMENT" + + partial void EnterRule_END_COMMENT(); + partial void LeaveRule_END_COMMENT(); + + // $ANTLR start "END_COMMENT" + [GrammarRule("END_COMMENT")] + private void mEND_COMMENT() + { + EnterRule_END_COMMENT(); + EnterRule("END_COMMENT", 2); + TraceIn("END_COMMENT", 2); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:107:2: ( '*/' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:107:4: '*/' + { + DebugLocation(107, 4); + Match("*/"); + + + } + + } + finally + { + TraceOut("END_COMMENT", 2); + LeaveRule("END_COMMENT", 2); + LeaveRule_END_COMMENT(); + } + } + // $ANTLR end "END_COMMENT" + + partial void EnterRule_PLUS(); + partial void LeaveRule_PLUS(); + + // $ANTLR start "PLUS" + [GrammarRule("PLUS")] + private void mPLUS() + { + EnterRule_PLUS(); + EnterRule("PLUS", 3); + TraceIn("PLUS", 3); + try + { + int _type = PLUS; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:111:9: ( '+' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:111:11: '+' + { + DebugLocation(111, 11); + Match('+'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("PLUS", 3); + LeaveRule("PLUS", 3); + LeaveRule_PLUS(); + } + } + // $ANTLR end "PLUS" + + partial void EnterRule_MINUS(); + partial void LeaveRule_MINUS(); + + // $ANTLR start "MINUS" + [GrammarRule("MINUS")] + private void mMINUS() + { + EnterRule_MINUS(); + EnterRule("MINUS", 4); + TraceIn("MINUS", 4); + try + { + int _type = MINUS; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:112:9: ( '-' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:112:11: '-' + { + DebugLocation(112, 11); + Match('-'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("MINUS", 4); + LeaveRule("MINUS", 4); + LeaveRule_MINUS(); + } + } + // $ANTLR end "MINUS" + + partial void EnterRule_MULT(); + partial void LeaveRule_MULT(); + + // $ANTLR start "MULT" + [GrammarRule("MULT")] + private void mMULT() + { + EnterRule_MULT(); + EnterRule("MULT", 5); + TraceIn("MULT", 5); + try + { + int _type = MULT; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:113:9: ( '*' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:113:11: '*' + { + DebugLocation(113, 11); + Match('*'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("MULT", 5); + LeaveRule("MULT", 5); + LeaveRule_MULT(); + } + } + // $ANTLR end "MULT" + + partial void EnterRule_DIV(); + partial void LeaveRule_DIV(); + + // $ANTLR start "DIV" + [GrammarRule("DIV")] + private void mDIV() + { + EnterRule_DIV(); + EnterRule("DIV", 6); + TraceIn("DIV", 6); + try + { + int _type = DIV; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:114:9: ( '/' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:114:11: '/' + { + DebugLocation(114, 11); + Match('/'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("DIV", 6); + LeaveRule("DIV", 6); + LeaveRule_DIV(); + } + } + // $ANTLR end "DIV" + + partial void EnterRule_EQ(); + partial void LeaveRule_EQ(); + + // $ANTLR start "EQ" + [GrammarRule("EQ")] + private void mEQ() + { + EnterRule_EQ(); + EnterRule("EQ", 7); + TraceIn("EQ", 7); + try + { + int _type = EQ; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:117:9: ( '=' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:117:11: '=' + { + DebugLocation(117, 11); + Match('='); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("EQ", 7); + LeaveRule("EQ", 7); + LeaveRule_EQ(); + } + } + // $ANTLR end "EQ" + + partial void EnterRule_NOTEQ(); + partial void LeaveRule_NOTEQ(); + + // $ANTLR start "NOTEQ" + [GrammarRule("NOTEQ")] + private void mNOTEQ() + { + EnterRule_NOTEQ(); + EnterRule("NOTEQ", 8); + TraceIn("NOTEQ", 8); + try + { + int _type = NOTEQ; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:118:9: ( '<>' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:118:11: '<>' + { + DebugLocation(118, 11); + Match("<>"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("NOTEQ", 8); + LeaveRule("NOTEQ", 8); + LeaveRule_NOTEQ(); + } + } + // $ANTLR end "NOTEQ" + + partial void EnterRule_GT(); + partial void LeaveRule_GT(); + + // $ANTLR start "GT" + [GrammarRule("GT")] + private void mGT() + { + EnterRule_GT(); + EnterRule("GT", 9); + TraceIn("GT", 9); + try + { + int _type = GT; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:119:9: ( '>' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:119:11: '>' + { + DebugLocation(119, 11); + Match('>'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("GT", 9); + LeaveRule("GT", 9); + LeaveRule_GT(); + } + } + // $ANTLR end "GT" + + partial void EnterRule_GTEQ(); + partial void LeaveRule_GTEQ(); + + // $ANTLR start "GTEQ" + [GrammarRule("GTEQ")] + private void mGTEQ() + { + EnterRule_GTEQ(); + EnterRule("GTEQ", 10); + TraceIn("GTEQ", 10); + try + { + int _type = GTEQ; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:120:9: ( '>=' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:120:11: '>=' + { + DebugLocation(120, 11); + Match(">="); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("GTEQ", 10); + LeaveRule("GTEQ", 10); + LeaveRule_GTEQ(); + } + } + // $ANTLR end "GTEQ" + + partial void EnterRule_LT(); + partial void LeaveRule_LT(); + + // $ANTLR start "LT" + [GrammarRule("LT")] + private void mLT() + { + EnterRule_LT(); + EnterRule("LT", 11); + TraceIn("LT", 11); + try + { + int _type = LT; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:121:9: ( '<' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:121:11: '<' + { + DebugLocation(121, 11); + Match('<'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("LT", 11); + LeaveRule("LT", 11); + LeaveRule_LT(); + } + } + // $ANTLR end "LT" + + partial void EnterRule_LTEQ(); + partial void LeaveRule_LTEQ(); + + // $ANTLR start "LTEQ" + [GrammarRule("LTEQ")] + private void mLTEQ() + { + EnterRule_LTEQ(); + EnterRule("LTEQ", 12); + TraceIn("LTEQ", 12); + try + { + int _type = LTEQ; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:122:9: ( '<=' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:122:11: '<=' + { + DebugLocation(122, 11); + Match("<="); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("LTEQ", 12); + LeaveRule("LTEQ", 12); + LeaveRule_LTEQ(); + } + } + // $ANTLR end "LTEQ" + + partial void EnterRule_AND(); + partial void LeaveRule_AND(); + + // $ANTLR start "AND" + [GrammarRule("AND")] + private void mAND() + { + EnterRule_AND(); + EnterRule("AND", 13); + TraceIn("AND", 13); + try + { + int _type = AND; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:125:9: ( '&' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:125:11: '&' + { + DebugLocation(125, 11); + Match('&'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("AND", 13); + LeaveRule("AND", 13); + LeaveRule_AND(); + } + } + // $ANTLR end "AND" + + partial void EnterRule_OR(); + partial void LeaveRule_OR(); + + // $ANTLR start "OR" + [GrammarRule("OR")] + private void mOR() + { + EnterRule_OR(); + EnterRule("OR", 14); + TraceIn("OR", 14); + try + { + int _type = OR; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:126:9: ( '|' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:126:11: '|' + { + DebugLocation(126, 11); + Match('|'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("OR", 14); + LeaveRule("OR", 14); + LeaveRule_OR(); + } + } + // $ANTLR end "OR" + + partial void EnterRule_LPAREN(); + partial void LeaveRule_LPAREN(); + + // $ANTLR start "LPAREN" + [GrammarRule("LPAREN")] + private void mLPAREN() + { + EnterRule_LPAREN(); + EnterRule("LPAREN", 15); + TraceIn("LPAREN", 15); + try + { + int _type = LPAREN; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:129:8: ( '(' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:129:10: '(' + { + DebugLocation(129, 10); + Match('('); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("LPAREN", 15); + LeaveRule("LPAREN", 15); + LeaveRule_LPAREN(); + } + } + // $ANTLR end "LPAREN" + + partial void EnterRule_RPAREN(); + partial void LeaveRule_RPAREN(); + + // $ANTLR start "RPAREN" + [GrammarRule("RPAREN")] + private void mRPAREN() + { + EnterRule_RPAREN(); + EnterRule("RPAREN", 16); + TraceIn("RPAREN", 16); + try + { + int _type = RPAREN; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:130:8: ( ')' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:130:10: ')' + { + DebugLocation(130, 10); + Match(')'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("RPAREN", 16); + LeaveRule("RPAREN", 16); + LeaveRule_RPAREN(); + } + } + // $ANTLR end "RPAREN" + + partial void EnterRule_LBRACKET(); + partial void LeaveRule_LBRACKET(); + + // $ANTLR start "LBRACKET" + [GrammarRule("LBRACKET")] + private void mLBRACKET() + { + EnterRule_LBRACKET(); + EnterRule("LBRACKET", 17); + TraceIn("LBRACKET", 17); + try + { + int _type = LBRACKET; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:131:11: ( '[' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:131:13: '[' + { + DebugLocation(131, 13); + Match('['); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("LBRACKET", 17); + LeaveRule("LBRACKET", 17); + LeaveRule_LBRACKET(); + } + } + // $ANTLR end "LBRACKET" + + partial void EnterRule_RBRACKET(); + partial void LeaveRule_RBRACKET(); + + // $ANTLR start "RBRACKET" + [GrammarRule("RBRACKET")] + private void mRBRACKET() + { + EnterRule_RBRACKET(); + EnterRule("RBRACKET", 18); + TraceIn("RBRACKET", 18); + try + { + int _type = RBRACKET; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:132:11: ( ']' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:132:13: ']' + { + DebugLocation(132, 13); + Match(']'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("RBRACKET", 18); + LeaveRule("RBRACKET", 18); + LeaveRule_RBRACKET(); + } + } + // $ANTLR end "RBRACKET" + + partial void EnterRule_LKEY(); + partial void LeaveRule_LKEY(); + + // $ANTLR start "LKEY" + [GrammarRule("LKEY")] + private void mLKEY() + { + EnterRule_LKEY(); + EnterRule("LKEY", 19); + TraceIn("LKEY", 19); + try + { + int _type = LKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:133:9: ( '{' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:133:11: '{' + { + DebugLocation(133, 11); + Match('{'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("LKEY", 19); + LeaveRule("LKEY", 19); + LeaveRule_LKEY(); + } + } + // $ANTLR end "LKEY" + + partial void EnterRule_RKEY(); + partial void LeaveRule_RKEY(); + + // $ANTLR start "RKEY" + [GrammarRule("RKEY")] + private void mRKEY() + { + EnterRule_RKEY(); + EnterRule("RKEY", 20); + TraceIn("RKEY", 20); + try + { + int _type = RKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:134:9: ( '}' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:134:11: '}' + { + DebugLocation(134, 11); + Match('}'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("RKEY", 20); + LeaveRule("RKEY", 20); + LeaveRule_RKEY(); + } + } + // $ANTLR end "RKEY" + + partial void EnterRule_COMMA(); + partial void LeaveRule_COMMA(); + + // $ANTLR start "COMMA" + [GrammarRule("COMMA")] + private void mCOMMA() + { + EnterRule_COMMA(); + EnterRule("COMMA", 21); + TraceIn("COMMA", 21); + try + { + int _type = COMMA; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:137:7: ( ',' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:137:9: ',' + { + DebugLocation(137, 9); + Match(','); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("COMMA", 21); + LeaveRule("COMMA", 21); + LeaveRule_COMMA(); + } + } + // $ANTLR end "COMMA" + + partial void EnterRule_SEMI(); + partial void LeaveRule_SEMI(); + + // $ANTLR start "SEMI" + [GrammarRule("SEMI")] + private void mSEMI() + { + EnterRule_SEMI(); + EnterRule("SEMI", 22); + TraceIn("SEMI", 22); + try + { + int _type = SEMI; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:138:6: ( ';' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:138:8: ';' + { + DebugLocation(138, 8); + Match(';'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("SEMI", 22); + LeaveRule("SEMI", 22); + LeaveRule_SEMI(); + } + } + // $ANTLR end "SEMI" + + partial void EnterRule_COLON(); + partial void LeaveRule_COLON(); + + // $ANTLR start "COLON" + [GrammarRule("COLON")] + private void mCOLON() + { + EnterRule_COLON(); + EnterRule("COLON", 23); + TraceIn("COLON", 23); + try + { + int _type = COLON; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:139:9: ( ':' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:139:11: ':' + { + DebugLocation(139, 11); + Match(':'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("COLON", 23); + LeaveRule("COLON", 23); + LeaveRule_COLON(); + } + } + // $ANTLR end "COLON" + + partial void EnterRule_DOT(); + partial void LeaveRule_DOT(); + + // $ANTLR start "DOT" + [GrammarRule("DOT")] + private void mDOT() + { + EnterRule_DOT(); + EnterRule("DOT", 24); + TraceIn("DOT", 24); + try + { + int _type = DOT; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:140:9: ( '.' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:140:11: '.' + { + DebugLocation(140, 11); + Match('.'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("DOT", 24); + LeaveRule("DOT", 24); + LeaveRule_DOT(); + } + } + // $ANTLR end "DOT" + + partial void EnterRule_QUOTE(); + partial void LeaveRule_QUOTE(); + + // $ANTLR start "QUOTE" + [GrammarRule("QUOTE")] + private void mQUOTE() + { + EnterRule_QUOTE(); + EnterRule("QUOTE", 25); + TraceIn("QUOTE", 25); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:143:9: ( '\\\"' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:143:11: '\\\"' + { + DebugLocation(143, 11); + Match('\"'); + + } + + } + finally + { + TraceOut("QUOTE", 25); + LeaveRule("QUOTE", 25); + LeaveRule_QUOTE(); + } + } + // $ANTLR end "QUOTE" + + partial void EnterRule_ASSIGN(); + partial void LeaveRule_ASSIGN(); + + // $ANTLR start "ASSIGN" + [GrammarRule("ASSIGN")] + private void mASSIGN() + { + EnterRule_ASSIGN(); + EnterRule("ASSIGN", 26); + TraceIn("ASSIGN", 26); + try + { + int _type = ASSIGN; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:144:9: ( ':=' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:144:11: ':=' + { + DebugLocation(144, 11); + Match(":="); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("ASSIGN", 26); + LeaveRule("ASSIGN", 26); + LeaveRule_ASSIGN(); + } + } + // $ANTLR end "ASSIGN" + + partial void EnterRule_ARRAYKEY(); + partial void LeaveRule_ARRAYKEY(); + + // $ANTLR start "ARRAYKEY" + [GrammarRule("ARRAYKEY")] + private void mARRAYKEY() + { + EnterRule_ARRAYKEY(); + EnterRule("ARRAYKEY", 27); + TraceIn("ARRAYKEY", 27); + try + { + int _type = ARRAYKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:147:13: ( 'array' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:147:15: 'array' + { + DebugLocation(147, 15); + Match("array"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("ARRAYKEY", 27); + LeaveRule("ARRAYKEY", 27); + LeaveRule_ARRAYKEY(); + } + } + // $ANTLR end "ARRAYKEY" + + partial void EnterRule_BREAKKEY(); + partial void LeaveRule_BREAKKEY(); + + // $ANTLR start "BREAKKEY" + [GrammarRule("BREAKKEY")] + private void mBREAKKEY() + { + EnterRule_BREAKKEY(); + EnterRule("BREAKKEY", 28); + TraceIn("BREAKKEY", 28); + try + { + int _type = BREAKKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:148:13: ( 'break' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:148:15: 'break' + { + DebugLocation(148, 15); + Match("break"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("BREAKKEY", 28); + LeaveRule("BREAKKEY", 28); + LeaveRule_BREAKKEY(); + } + } + // $ANTLR end "BREAKKEY" + + partial void EnterRule_DOKEY(); + partial void LeaveRule_DOKEY(); + + // $ANTLR start "DOKEY" + [GrammarRule("DOKEY")] + private void mDOKEY() + { + EnterRule_DOKEY(); + EnterRule("DOKEY", 29); + TraceIn("DOKEY", 29); + try + { + int _type = DOKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:149:13: ( 'do' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:149:15: 'do' + { + DebugLocation(149, 15); + Match("do"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("DOKEY", 29); + LeaveRule("DOKEY", 29); + LeaveRule_DOKEY(); + } + } + // $ANTLR end "DOKEY" + + partial void EnterRule_ELSEKEY(); + partial void LeaveRule_ELSEKEY(); + + // $ANTLR start "ELSEKEY" + [GrammarRule("ELSEKEY")] + private void mELSEKEY() + { + EnterRule_ELSEKEY(); + EnterRule("ELSEKEY", 30); + TraceIn("ELSEKEY", 30); + try + { + int _type = ELSEKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:150:13: ( 'else' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:150:15: 'else' + { + DebugLocation(150, 15); + Match("else"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("ELSEKEY", 30); + LeaveRule("ELSEKEY", 30); + LeaveRule_ELSEKEY(); + } + } + // $ANTLR end "ELSEKEY" + + partial void EnterRule_ENDKEY(); + partial void LeaveRule_ENDKEY(); + + // $ANTLR start "ENDKEY" + [GrammarRule("ENDKEY")] + private void mENDKEY() + { + EnterRule_ENDKEY(); + EnterRule("ENDKEY", 31); + TraceIn("ENDKEY", 31); + try + { + int _type = ENDKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:151:13: ( 'end' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:151:15: 'end' + { + DebugLocation(151, 15); + Match("end"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("ENDKEY", 31); + LeaveRule("ENDKEY", 31); + LeaveRule_ENDKEY(); + } + } + // $ANTLR end "ENDKEY" + + partial void EnterRule_FORKEY(); + partial void LeaveRule_FORKEY(); + + // $ANTLR start "FORKEY" + [GrammarRule("FORKEY")] + private void mFORKEY() + { + EnterRule_FORKEY(); + EnterRule("FORKEY", 32); + TraceIn("FORKEY", 32); + try + { + int _type = FORKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:152:13: ( 'for' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:152:15: 'for' + { + DebugLocation(152, 15); + Match("for"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("FORKEY", 32); + LeaveRule("FORKEY", 32); + LeaveRule_FORKEY(); + } + } + // $ANTLR end "FORKEY" + + partial void EnterRule_FUNCTIONKEY(); + partial void LeaveRule_FUNCTIONKEY(); + + // $ANTLR start "FUNCTIONKEY" + [GrammarRule("FUNCTIONKEY")] + private void mFUNCTIONKEY() + { + EnterRule_FUNCTIONKEY(); + EnterRule("FUNCTIONKEY", 33); + TraceIn("FUNCTIONKEY", 33); + try + { + int _type = FUNCTIONKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:153:13: ( 'function' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:153:15: 'function' + { + DebugLocation(153, 15); + Match("function"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("FUNCTIONKEY", 33); + LeaveRule("FUNCTIONKEY", 33); + LeaveRule_FUNCTIONKEY(); + } + } + // $ANTLR end "FUNCTIONKEY" + + partial void EnterRule_IFKEY(); + partial void LeaveRule_IFKEY(); + + // $ANTLR start "IFKEY" + [GrammarRule("IFKEY")] + private void mIFKEY() + { + EnterRule_IFKEY(); + EnterRule("IFKEY", 34); + TraceIn("IFKEY", 34); + try + { + int _type = IFKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:154:13: ( 'if' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:154:15: 'if' + { + DebugLocation(154, 15); + Match("if"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("IFKEY", 34); + LeaveRule("IFKEY", 34); + LeaveRule_IFKEY(); + } + } + // $ANTLR end "IFKEY" + + partial void EnterRule_INKEY(); + partial void LeaveRule_INKEY(); + + // $ANTLR start "INKEY" + [GrammarRule("INKEY")] + private void mINKEY() + { + EnterRule_INKEY(); + EnterRule("INKEY", 35); + TraceIn("INKEY", 35); + try + { + int _type = INKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:155:13: ( 'in' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:155:15: 'in' + { + DebugLocation(155, 15); + Match("in"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("INKEY", 35); + LeaveRule("INKEY", 35); + LeaveRule_INKEY(); + } + } + // $ANTLR end "INKEY" + + partial void EnterRule_INTKEY(); + partial void LeaveRule_INTKEY(); + + // $ANTLR start "INTKEY" + [GrammarRule("INTKEY")] + private void mINTKEY() + { + EnterRule_INTKEY(); + EnterRule("INTKEY", 36); + TraceIn("INTKEY", 36); + try + { + int _type = INTKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:156:9: ( 'int' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:156:11: 'int' + { + DebugLocation(156, 11); + Match("int"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("INTKEY", 36); + LeaveRule("INTKEY", 36); + LeaveRule_INTKEY(); + } + } + // $ANTLR end "INTKEY" + + partial void EnterRule_LETKEY(); + partial void LeaveRule_LETKEY(); + + // $ANTLR start "LETKEY" + [GrammarRule("LETKEY")] + private void mLETKEY() + { + EnterRule_LETKEY(); + EnterRule("LETKEY", 37); + TraceIn("LETKEY", 37); + try + { + int _type = LETKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:157:13: ( 'let' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:157:15: 'let' + { + DebugLocation(157, 15); + Match("let"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("LETKEY", 37); + LeaveRule("LETKEY", 37); + LeaveRule_LETKEY(); + } + } + // $ANTLR end "LETKEY" + + partial void EnterRule_NILKEY(); + partial void LeaveRule_NILKEY(); + + // $ANTLR start "NILKEY" + [GrammarRule("NILKEY")] + private void mNILKEY() + { + EnterRule_NILKEY(); + EnterRule("NILKEY", 38); + TraceIn("NILKEY", 38); + try + { + int _type = NILKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:158:13: ( 'nil' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:158:15: 'nil' + { + DebugLocation(158, 15); + Match("nil"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("NILKEY", 38); + LeaveRule("NILKEY", 38); + LeaveRule_NILKEY(); + } + } + // $ANTLR end "NILKEY" + + partial void EnterRule_OFKEY(); + partial void LeaveRule_OFKEY(); + + // $ANTLR start "OFKEY" + [GrammarRule("OFKEY")] + private void mOFKEY() + { + EnterRule_OFKEY(); + EnterRule("OFKEY", 39); + TraceIn("OFKEY", 39); + try + { + int _type = OFKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:159:13: ( 'of' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:159:15: 'of' + { + DebugLocation(159, 15); + Match("of"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("OFKEY", 39); + LeaveRule("OFKEY", 39); + LeaveRule_OFKEY(); + } + } + // $ANTLR end "OFKEY" + + partial void EnterRule_STRINGKEY(); + partial void LeaveRule_STRINGKEY(); + + // $ANTLR start "STRINGKEY" + [GrammarRule("STRINGKEY")] + private void mSTRINGKEY() + { + EnterRule_STRINGKEY(); + EnterRule("STRINGKEY", 40); + TraceIn("STRINGKEY", 40); + try + { + int _type = STRINGKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:160:11: ( 'string' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:160:13: 'string' + { + DebugLocation(160, 13); + Match("string"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("STRINGKEY", 40); + LeaveRule("STRINGKEY", 40); + LeaveRule_STRINGKEY(); + } + } + // $ANTLR end "STRINGKEY" + + partial void EnterRule_THENKEY(); + partial void LeaveRule_THENKEY(); + + // $ANTLR start "THENKEY" + [GrammarRule("THENKEY")] + private void mTHENKEY() + { + EnterRule_THENKEY(); + EnterRule("THENKEY", 41); + TraceIn("THENKEY", 41); + try + { + int _type = THENKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:161:13: ( 'then' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:161:15: 'then' + { + DebugLocation(161, 15); + Match("then"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("THENKEY", 41); + LeaveRule("THENKEY", 41); + LeaveRule_THENKEY(); + } + } + // $ANTLR end "THENKEY" + + partial void EnterRule_TOKEY(); + partial void LeaveRule_TOKEY(); + + // $ANTLR start "TOKEY" + [GrammarRule("TOKEY")] + private void mTOKEY() + { + EnterRule_TOKEY(); + EnterRule("TOKEY", 42); + TraceIn("TOKEY", 42); + try + { + int _type = TOKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:162:13: ( 'to' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:162:15: 'to' + { + DebugLocation(162, 15); + Match("to"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("TOKEY", 42); + LeaveRule("TOKEY", 42); + LeaveRule_TOKEY(); + } + } + // $ANTLR end "TOKEY" + + partial void EnterRule_TYPEKEY(); + partial void LeaveRule_TYPEKEY(); + + // $ANTLR start "TYPEKEY" + [GrammarRule("TYPEKEY")] + private void mTYPEKEY() + { + EnterRule_TYPEKEY(); + EnterRule("TYPEKEY", 43); + TraceIn("TYPEKEY", 43); + try + { + int _type = TYPEKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:163:13: ( 'type' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:163:15: 'type' + { + DebugLocation(163, 15); + Match("type"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("TYPEKEY", 43); + LeaveRule("TYPEKEY", 43); + LeaveRule_TYPEKEY(); + } + } + // $ANTLR end "TYPEKEY" + + partial void EnterRule_VARKEY(); + partial void LeaveRule_VARKEY(); + + // $ANTLR start "VARKEY" + [GrammarRule("VARKEY")] + private void mVARKEY() + { + EnterRule_VARKEY(); + EnterRule("VARKEY", 44); + TraceIn("VARKEY", 44); + try + { + int _type = VARKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:164:13: ( 'var' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:164:15: 'var' + { + DebugLocation(164, 15); + Match("var"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("VARKEY", 44); + LeaveRule("VARKEY", 44); + LeaveRule_VARKEY(); + } + } + // $ANTLR end "VARKEY" + + partial void EnterRule_WHILEKEY(); + partial void LeaveRule_WHILEKEY(); + + // $ANTLR start "WHILEKEY" + [GrammarRule("WHILEKEY")] + private void mWHILEKEY() + { + EnterRule_WHILEKEY(); + EnterRule("WHILEKEY", 45); + TraceIn("WHILEKEY", 45); + try + { + int _type = WHILEKEY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:165:13: ( 'while' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:165:15: 'while' + { + DebugLocation(165, 15); + Match("while"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("WHILEKEY", 45); + LeaveRule("WHILEKEY", 45); + LeaveRule_WHILEKEY(); + } + } + // $ANTLR end "WHILEKEY" + + partial void EnterRule_DIGIT(); + partial void LeaveRule_DIGIT(); + + // $ANTLR start "DIGIT" + [GrammarRule("DIGIT")] + private void mDIGIT() + { + EnterRule_DIGIT(); + EnterRule("DIGIT", 46); + TraceIn("DIGIT", 46); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:170:2: ( '0' .. '9' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g: + { + DebugLocation(170, 2); + if ((input.LA(1)>='0' && input.LA(1)<='9')) + { + input.Consume(); + } + else + { + MismatchedSetException mse = new MismatchedSetException(null,input); + DebugRecognitionException(mse); + Recover(mse); + throw mse; + } + + + } + + } + finally + { + TraceOut("DIGIT", 46); + LeaveRule("DIGIT", 46); + LeaveRule_DIGIT(); + } + } + // $ANTLR end "DIGIT" + + partial void EnterRule_LETTER(); + partial void LeaveRule_LETTER(); + + // $ANTLR start "LETTER" + [GrammarRule("LETTER")] + private void mLETTER() + { + EnterRule_LETTER(); + EnterRule("LETTER", 47); + TraceIn("LETTER", 47); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:175:2: ( 'a' .. 'z' | 'A' .. 'Z' ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g: + { + DebugLocation(175, 2); + if ((input.LA(1)>='A' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='z')) + { + input.Consume(); + } + else + { + MismatchedSetException mse = new MismatchedSetException(null,input); + DebugRecognitionException(mse); + Recover(mse); + throw mse; + } + + + } + + } + finally + { + TraceOut("LETTER", 47); + LeaveRule("LETTER", 47); + LeaveRule_LETTER(); + } + } + // $ANTLR end "LETTER" + + partial void EnterRule_ASCII_ESC(); + partial void LeaveRule_ASCII_ESC(); + + // $ANTLR start "ASCII_ESC" + [GrammarRule("ASCII_ESC")] + private void mASCII_ESC() + { + EnterRule_ASCII_ESC(); + EnterRule("ASCII_ESC", 48); + TraceIn("ASCII_ESC", 48); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:180:2: ( '12' '0' .. '7' | '1' '0' .. '1' '0' .. '9' | '0' '0' .. '9' '0' .. '9' ) + int alt1=3; + try { DebugEnterDecision(1, false); + int LA1_0 = input.LA(1); + + if ((LA1_0=='1')) + { + int LA1_1 = input.LA(2); + + if ((LA1_1=='2')) + { + alt1 = 1; + } + else if (((LA1_1>='0' && LA1_1<='1'))) + { + alt1 = 2; + } + else + { + NoViableAltException nvae = new NoViableAltException("", 1, 1, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + else if ((LA1_0=='0')) + { + alt1 = 3; + } + else + { + NoViableAltException nvae = new NoViableAltException("", 1, 0, input); + DebugRecognitionException(nvae); + throw nvae; + } + } finally { DebugExitDecision(1); } + switch (alt1) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:180:4: '12' '0' .. '7' + { + DebugLocation(180, 4); + Match("12"); + + DebugLocation(180, 9); + MatchRange('0','7'); + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:181:4: '1' '0' .. '1' '0' .. '9' + { + DebugLocation(181, 4); + Match('1'); + DebugLocation(181, 8); + MatchRange('0','1'); + DebugLocation(181, 17); + MatchRange('0','9'); + + } + break; + case 3: + DebugEnterAlt(3); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:182:4: '0' '0' .. '9' '0' .. '9' + { + DebugLocation(182, 4); + Match('0'); + DebugLocation(182, 8); + MatchRange('0','9'); + DebugLocation(182, 17); + MatchRange('0','9'); + + } + break; + + } + } + finally + { + TraceOut("ASCII_ESC", 48); + LeaveRule("ASCII_ESC", 48); + LeaveRule_ASCII_ESC(); + } + } + // $ANTLR end "ASCII_ESC" + + partial void EnterRule_INT(); + partial void LeaveRule_INT(); + + // $ANTLR start "INT" + [GrammarRule("INT")] + private void mINT() + { + EnterRule_INT(); + EnterRule("INT", 49); + TraceIn("INT", 49); + try + { + int _type = INT; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:185:2: ( ( DIGIT )+ ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:185:4: ( DIGIT )+ + { + DebugLocation(185, 4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:185:4: ( DIGIT )+ + int cnt2=0; + try { DebugEnterSubRule(2); + while (true) + { + int alt2=2; + try { DebugEnterDecision(2, false); + int LA2_0 = input.LA(1); + + if (((LA2_0>='0' && LA2_0<='9'))) + { + alt2 = 1; + } + + + } finally { DebugExitDecision(2); } + switch (alt2) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g: + { + DebugLocation(185, 4); + input.Consume(); + + + } + break; + + default: + if (cnt2 >= 1) + goto loop2; + + EarlyExitException eee2 = new EarlyExitException( 2, input ); + DebugRecognitionException(eee2); + throw eee2; + } + cnt2++; + } + loop2: + ; + + } finally { DebugExitSubRule(2); } + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("INT", 49); + LeaveRule("INT", 49); + LeaveRule_INT(); + } + } + // $ANTLR end "INT" + + partial void EnterRule_ID(); + partial void LeaveRule_ID(); + + // $ANTLR start "ID" + [GrammarRule("ID")] + private void mID() + { + EnterRule_ID(); + EnterRule("ID", 50); + TraceIn("ID", 50); + try + { + int _type = ID; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:188:5: ( LETTER ( LETTER | DIGIT | '_' )* ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:188:7: LETTER ( LETTER | DIGIT | '_' )* + { + DebugLocation(188, 7); + mLETTER(); + DebugLocation(188, 14); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:188:14: ( LETTER | DIGIT | '_' )* + try { DebugEnterSubRule(3); + while (true) + { + int alt3=2; + try { DebugEnterDecision(3, false); + int LA3_0 = input.LA(1); + + if (((LA3_0>='0' && LA3_0<='9')||(LA3_0>='A' && LA3_0<='Z')||LA3_0=='_'||(LA3_0>='a' && LA3_0<='z'))) + { + alt3 = 1; + } + + + } finally { DebugExitDecision(3); } + switch ( alt3 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g: + { + DebugLocation(188, 14); + input.Consume(); + + + } + break; + + default: + goto loop3; + } + } + + loop3: + ; + + } finally { DebugExitSubRule(3); } + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("ID", 50); + LeaveRule("ID", 50); + LeaveRule_ID(); + } + } + // $ANTLR end "ID" + + partial void EnterRule_WS(); + partial void LeaveRule_WS(); + + // $ANTLR start "WS" + [GrammarRule("WS")] + private void mWS() + { + EnterRule_WS(); + EnterRule("WS", 51); + TraceIn("WS", 51); + try + { + int _type = WS; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:192:2: ( ( ' ' | '\\t' | '\\r' | '\\n' )+ ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:192:4: ( ' ' | '\\t' | '\\r' | '\\n' )+ + { + DebugLocation(192, 4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:192:4: ( ' ' | '\\t' | '\\r' | '\\n' )+ + int cnt4=0; + try { DebugEnterSubRule(4); + while (true) + { + int alt4=2; + try { DebugEnterDecision(4, false); + int LA4_0 = input.LA(1); + + if (((LA4_0>='\t' && LA4_0<='\n')||LA4_0=='\r'||LA4_0==' ')) + { + alt4 = 1; + } + + + } finally { DebugExitDecision(4); } + switch (alt4) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g: + { + DebugLocation(192, 4); + input.Consume(); + + + } + break; + + default: + if (cnt4 >= 1) + goto loop4; + + EarlyExitException eee4 = new EarlyExitException( 4, input ); + DebugRecognitionException(eee4); + throw eee4; + } + cnt4++; + } + loop4: + ; + + } finally { DebugExitSubRule(4); } + + DebugLocation(193, 2); + _channel = Hidden; + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("WS", 51); + LeaveRule("WS", 51); + LeaveRule_WS(); + } + } + // $ANTLR end "WS" + + partial void EnterRule_ESC_SEQ(); + partial void LeaveRule_ESC_SEQ(); + + // $ANTLR start "ESC_SEQ" + [GrammarRule("ESC_SEQ")] + private void mESC_SEQ() + { + EnterRule_ESC_SEQ(); + EnterRule("ESC_SEQ", 52); + TraceIn("ESC_SEQ", 52); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:200:2: ( '\\\\' ( 'n' | 'r' | 't' | QUOTE | ASCII_ESC | WS '\\\\' ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:200:4: '\\\\' ( 'n' | 'r' | 't' | QUOTE | ASCII_ESC | WS '\\\\' ) + { + DebugLocation(200, 4); + Match('\\'); + DebugLocation(200, 9); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:200:9: ( 'n' | 'r' | 't' | QUOTE | ASCII_ESC | WS '\\\\' ) + int alt5=6; + try { DebugEnterSubRule(5); + try { DebugEnterDecision(5, false); + switch (input.LA(1)) + { + case 'n': + { + alt5 = 1; + } + break; + case 'r': + { + alt5 = 2; + } + break; + case 't': + { + alt5 = 3; + } + break; + case '\"': + { + alt5 = 4; + } + break; + case '0': + case '1': + { + alt5 = 5; + } + break; + case '\t': + case '\n': + case '\r': + case ' ': + { + alt5 = 6; + } + break; + default: + { + NoViableAltException nvae = new NoViableAltException("", 5, 0, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + + } finally { DebugExitDecision(5); } + switch (alt5) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:200:11: 'n' + { + DebugLocation(200, 11); + Match('n'); + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:200:17: 'r' + { + DebugLocation(200, 17); + Match('r'); + + } + break; + case 3: + DebugEnterAlt(3); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:200:23: 't' + { + DebugLocation(200, 23); + Match('t'); + + } + break; + case 4: + DebugEnterAlt(4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:200:29: QUOTE + { + DebugLocation(200, 29); + mQUOTE(); + + } + break; + case 5: + DebugEnterAlt(5); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:200:37: ASCII_ESC + { + DebugLocation(200, 37); + mASCII_ESC(); + + } + break; + case 6: + DebugEnterAlt(6); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:200:49: WS '\\\\' + { + DebugLocation(200, 49); + mWS(); + DebugLocation(200, 52); + Match('\\'); + + } + break; + + } + } finally { DebugExitSubRule(5); } + + + } + + } + finally + { + TraceOut("ESC_SEQ", 52); + LeaveRule("ESC_SEQ", 52); + LeaveRule_ESC_SEQ(); + } + } + // $ANTLR end "ESC_SEQ" + + partial void EnterRule_PRINTABLE_CHARACTER(); + partial void LeaveRule_PRINTABLE_CHARACTER(); + + // $ANTLR start "PRINTABLE_CHARACTER" + [GrammarRule("PRINTABLE_CHARACTER")] + private void mPRINTABLE_CHARACTER() + { + EnterRule_PRINTABLE_CHARACTER(); + EnterRule("PRINTABLE_CHARACTER", 53); + TraceIn("PRINTABLE_CHARACTER", 53); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:205:2: ( ( ( ' ' .. '!' ) | ( '#' .. '[' ) | ( ']' .. '~' ) ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g: + { + DebugLocation(205, 2); + if ((input.LA(1)>=' ' && input.LA(1)<='!')||(input.LA(1)>='#' && input.LA(1)<='[')||(input.LA(1)>=']' && input.LA(1)<='~')) + { + input.Consume(); + } + else + { + MismatchedSetException mse = new MismatchedSetException(null,input); + DebugRecognitionException(mse); + Recover(mse); + throw mse; + } + + + } + + } + finally + { + TraceOut("PRINTABLE_CHARACTER", 53); + LeaveRule("PRINTABLE_CHARACTER", 53); + LeaveRule_PRINTABLE_CHARACTER(); + } + } + // $ANTLR end "PRINTABLE_CHARACTER" + + partial void EnterRule_STRING(); + partial void LeaveRule_STRING(); + + // $ANTLR start "STRING" + [GrammarRule("STRING")] + private void mSTRING() + { + EnterRule_STRING(); + EnterRule("STRING", 54); + TraceIn("STRING", 54); + try + { + int _type = STRING; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:207:8: ( QUOTE ( ESC_SEQ | PRINTABLE_CHARACTER )* QUOTE ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:207:10: QUOTE ( ESC_SEQ | PRINTABLE_CHARACTER )* QUOTE + { + DebugLocation(207, 10); + mQUOTE(); + DebugLocation(207, 16); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:207:16: ( ESC_SEQ | PRINTABLE_CHARACTER )* + try { DebugEnterSubRule(6); + while (true) + { + int alt6=3; + try { DebugEnterDecision(6, false); + int LA6_0 = input.LA(1); + + if ((LA6_0=='\\')) + { + alt6 = 1; + } + else if (((LA6_0>=' ' && LA6_0<='!')||(LA6_0>='#' && LA6_0<='[')||(LA6_0>=']' && LA6_0<='~'))) + { + alt6 = 2; + } + + + } finally { DebugExitDecision(6); } + switch ( alt6 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:207:18: ESC_SEQ + { + DebugLocation(207, 18); + mESC_SEQ(); + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:207:28: PRINTABLE_CHARACTER + { + DebugLocation(207, 28); + mPRINTABLE_CHARACTER(); + + } + break; + + default: + goto loop6; + } + } + + loop6: + ; + + } finally { DebugExitSubRule(6); } + + DebugLocation(207, 51); + mQUOTE(); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("STRING", 54); + LeaveRule("STRING", 54); + LeaveRule_STRING(); + } + } + // $ANTLR end "STRING" + + partial void EnterRule_COMMENTARY(); + partial void LeaveRule_COMMENTARY(); + + // $ANTLR start "COMMENTARY" + [GrammarRule("COMMENTARY")] + private void mCOMMENTARY() + { + EnterRule_COMMENTARY(); + EnterRule("COMMENTARY", 55); + TraceIn("COMMENTARY", 55); + try + { + int _type = COMMENTARY; + int _channel = DefaultTokenChannel; + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:210:2: ( BEGIN_COMMENT ( options {greedy=false; } : . )* ( COMMENTARY ( options {greedy=false; } : . )* )* END_COMMENT ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:210:4: BEGIN_COMMENT ( options {greedy=false; } : . )* ( COMMENTARY ( options {greedy=false; } : . )* )* END_COMMENT + { + DebugLocation(210, 4); + mBEGIN_COMMENT(); + DebugLocation(211, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:211:7: ( options {greedy=false; } : . )* + try { DebugEnterSubRule(7); + while (true) + { + int alt7=2; + try { DebugEnterDecision(7, false); + int LA7_0 = input.LA(1); + + if ((LA7_0=='/')) + { + int LA7_1 = input.LA(2); + + if ((LA7_1=='*')) + { + alt7 = 2; + } + else if (((LA7_1>='\u0000' && LA7_1<=')')||(LA7_1>='+' && LA7_1<='\uFFFF'))) + { + alt7 = 1; + } + + + } + else if ((LA7_0=='*')) + { + int LA7_2 = input.LA(2); + + if ((LA7_2=='/')) + { + alt7 = 2; + } + else if (((LA7_2>='\u0000' && LA7_2<='.')||(LA7_2>='0' && LA7_2<='\uFFFF'))) + { + alt7 = 1; + } + + + } + else if (((LA7_0>='\u0000' && LA7_0<=')')||(LA7_0>='+' && LA7_0<='.')||(LA7_0>='0' && LA7_0<='\uFFFF'))) + { + alt7 = 1; + } + + + } finally { DebugExitDecision(7); } + switch ( alt7 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:211:35: . + { + DebugLocation(211, 35); + MatchAny(); + + } + break; + + default: + goto loop7; + } + } + + loop7: + ; + + } finally { DebugExitSubRule(7); } + + DebugLocation(212, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:212:7: ( COMMENTARY ( options {greedy=false; } : . )* )* + try { DebugEnterSubRule(9); + while (true) + { + int alt9=2; + try { DebugEnterDecision(9, false); + int LA9_0 = input.LA(1); + + if ((LA9_0=='/')) + { + alt9 = 1; + } + + + } finally { DebugExitDecision(9); } + switch ( alt9 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:212:10: COMMENTARY ( options {greedy=false; } : . )* + { + DebugLocation(212, 10); + mCOMMENTARY(); + DebugLocation(212, 21); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:212:21: ( options {greedy=false; } : . )* + try { DebugEnterSubRule(8); + while (true) + { + int alt8=2; + try { DebugEnterDecision(8, false); + int LA8_0 = input.LA(1); + + if ((LA8_0=='*')) + { + int LA8_1 = input.LA(2); + + if ((LA8_1=='/')) + { + alt8 = 2; + } + else if (((LA8_1>='\u0000' && LA8_1<='.')||(LA8_1>='0' && LA8_1<='\uFFFF'))) + { + alt8 = 1; + } + + + } + else if ((LA8_0=='/')) + { + int LA8_2 = input.LA(2); + + if ((LA8_2=='*')) + { + alt8 = 2; + } + else if (((LA8_2>='\u0000' && LA8_2<=')')||(LA8_2>='+' && LA8_2<='\uFFFF'))) + { + alt8 = 1; + } + + + } + else if (((LA8_0>='\u0000' && LA8_0<=')')||(LA8_0>='+' && LA8_0<='.')||(LA8_0>='0' && LA8_0<='\uFFFF'))) + { + alt8 = 1; + } + + + } finally { DebugExitDecision(8); } + switch ( alt8 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:212:49: . + { + DebugLocation(212, 49); + MatchAny(); + + } + break; + + default: + goto loop8; + } + } + + loop8: + ; + + } finally { DebugExitSubRule(8); } + + + } + break; + + default: + goto loop9; + } + } + + loop9: + ; + + } finally { DebugExitSubRule(9); } + + DebugLocation(213, 6); + mEND_COMMENT(); + DebugLocation(214, 4); + _channel = Hidden; + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + TraceOut("COMMENTARY", 55); + LeaveRule("COMMENTARY", 55); + LeaveRule_COMMENTARY(); + } + } + // $ANTLR end "COMMENTARY" + + public override void mTokens() + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:8: ( PLUS | MINUS | MULT | DIV | EQ | NOTEQ | GT | GTEQ | LT | LTEQ | AND | OR | LPAREN | RPAREN | LBRACKET | RBRACKET | LKEY | RKEY | COMMA | SEMI | COLON | DOT | ASSIGN | ARRAYKEY | BREAKKEY | DOKEY | ELSEKEY | ENDKEY | FORKEY | FUNCTIONKEY | IFKEY | INKEY | INTKEY | LETKEY | NILKEY | OFKEY | STRINGKEY | THENKEY | TOKEY | TYPEKEY | VARKEY | WHILEKEY | INT | ID | WS | STRING | COMMENTARY ) + int alt10=47; + try { DebugEnterDecision(10, false); + try + { + alt10 = dfa10.Predict(input); + } + catch (NoViableAltException nvae) + { + DebugRecognitionException(nvae); + throw; + } + } finally { DebugExitDecision(10); } + switch (alt10) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:10: PLUS + { + DebugLocation(1, 10); + mPLUS(); + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:15: MINUS + { + DebugLocation(1, 15); + mMINUS(); + + } + break; + case 3: + DebugEnterAlt(3); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:21: MULT + { + DebugLocation(1, 21); + mMULT(); + + } + break; + case 4: + DebugEnterAlt(4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:26: DIV + { + DebugLocation(1, 26); + mDIV(); + + } + break; + case 5: + DebugEnterAlt(5); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:30: EQ + { + DebugLocation(1, 30); + mEQ(); + + } + break; + case 6: + DebugEnterAlt(6); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:33: NOTEQ + { + DebugLocation(1, 33); + mNOTEQ(); + + } + break; + case 7: + DebugEnterAlt(7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:39: GT + { + DebugLocation(1, 39); + mGT(); + + } + break; + case 8: + DebugEnterAlt(8); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:42: GTEQ + { + DebugLocation(1, 42); + mGTEQ(); + + } + break; + case 9: + DebugEnterAlt(9); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:47: LT + { + DebugLocation(1, 47); + mLT(); + + } + break; + case 10: + DebugEnterAlt(10); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:50: LTEQ + { + DebugLocation(1, 50); + mLTEQ(); + + } + break; + case 11: + DebugEnterAlt(11); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:55: AND + { + DebugLocation(1, 55); + mAND(); + + } + break; + case 12: + DebugEnterAlt(12); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:59: OR + { + DebugLocation(1, 59); + mOR(); + + } + break; + case 13: + DebugEnterAlt(13); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:62: LPAREN + { + DebugLocation(1, 62); + mLPAREN(); + + } + break; + case 14: + DebugEnterAlt(14); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:69: RPAREN + { + DebugLocation(1, 69); + mRPAREN(); + + } + break; + case 15: + DebugEnterAlt(15); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:76: LBRACKET + { + DebugLocation(1, 76); + mLBRACKET(); + + } + break; + case 16: + DebugEnterAlt(16); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:85: RBRACKET + { + DebugLocation(1, 85); + mRBRACKET(); + + } + break; + case 17: + DebugEnterAlt(17); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:94: LKEY + { + DebugLocation(1, 94); + mLKEY(); + + } + break; + case 18: + DebugEnterAlt(18); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:99: RKEY + { + DebugLocation(1, 99); + mRKEY(); + + } + break; + case 19: + DebugEnterAlt(19); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:104: COMMA + { + DebugLocation(1, 104); + mCOMMA(); + + } + break; + case 20: + DebugEnterAlt(20); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:110: SEMI + { + DebugLocation(1, 110); + mSEMI(); + + } + break; + case 21: + DebugEnterAlt(21); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:115: COLON + { + DebugLocation(1, 115); + mCOLON(); + + } + break; + case 22: + DebugEnterAlt(22); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:121: DOT + { + DebugLocation(1, 121); + mDOT(); + + } + break; + case 23: + DebugEnterAlt(23); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:125: ASSIGN + { + DebugLocation(1, 125); + mASSIGN(); + + } + break; + case 24: + DebugEnterAlt(24); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:132: ARRAYKEY + { + DebugLocation(1, 132); + mARRAYKEY(); + + } + break; + case 25: + DebugEnterAlt(25); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:141: BREAKKEY + { + DebugLocation(1, 141); + mBREAKKEY(); + + } + break; + case 26: + DebugEnterAlt(26); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:150: DOKEY + { + DebugLocation(1, 150); + mDOKEY(); + + } + break; + case 27: + DebugEnterAlt(27); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:156: ELSEKEY + { + DebugLocation(1, 156); + mELSEKEY(); + + } + break; + case 28: + DebugEnterAlt(28); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:164: ENDKEY + { + DebugLocation(1, 164); + mENDKEY(); + + } + break; + case 29: + DebugEnterAlt(29); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:171: FORKEY + { + DebugLocation(1, 171); + mFORKEY(); + + } + break; + case 30: + DebugEnterAlt(30); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:178: FUNCTIONKEY + { + DebugLocation(1, 178); + mFUNCTIONKEY(); + + } + break; + case 31: + DebugEnterAlt(31); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:190: IFKEY + { + DebugLocation(1, 190); + mIFKEY(); + + } + break; + case 32: + DebugEnterAlt(32); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:196: INKEY + { + DebugLocation(1, 196); + mINKEY(); + + } + break; + case 33: + DebugEnterAlt(33); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:202: INTKEY + { + DebugLocation(1, 202); + mINTKEY(); + + } + break; + case 34: + DebugEnterAlt(34); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:209: LETKEY + { + DebugLocation(1, 209); + mLETKEY(); + + } + break; + case 35: + DebugEnterAlt(35); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:216: NILKEY + { + DebugLocation(1, 216); + mNILKEY(); + + } + break; + case 36: + DebugEnterAlt(36); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:223: OFKEY + { + DebugLocation(1, 223); + mOFKEY(); + + } + break; + case 37: + DebugEnterAlt(37); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:229: STRINGKEY + { + DebugLocation(1, 229); + mSTRINGKEY(); + + } + break; + case 38: + DebugEnterAlt(38); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:239: THENKEY + { + DebugLocation(1, 239); + mTHENKEY(); + + } + break; + case 39: + DebugEnterAlt(39); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:247: TOKEY + { + DebugLocation(1, 247); + mTOKEY(); + + } + break; + case 40: + DebugEnterAlt(40); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:253: TYPEKEY + { + DebugLocation(1, 253); + mTYPEKEY(); + + } + break; + case 41: + DebugEnterAlt(41); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:261: VARKEY + { + DebugLocation(1, 261); + mVARKEY(); + + } + break; + case 42: + DebugEnterAlt(42); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:268: WHILEKEY + { + DebugLocation(1, 268); + mWHILEKEY(); + + } + break; + case 43: + DebugEnterAlt(43); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:277: INT + { + DebugLocation(1, 277); + mINT(); + + } + break; + case 44: + DebugEnterAlt(44); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:281: ID + { + DebugLocation(1, 281); + mID(); + + } + break; + case 45: + DebugEnterAlt(45); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:284: WS + { + DebugLocation(1, 284); + mWS(); + + } + break; + case 46: + DebugEnterAlt(46); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:287: STRING + { + DebugLocation(1, 287); + mSTRING(); + + } + break; + case 47: + DebugEnterAlt(47); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:1:294: COMMENTARY + { + DebugLocation(1, 294); + mCOMMENTARY(); + + } + break; + + } + + } + + + #region DFA + DFA10 dfa10; + + protected override void InitDFAs() + { + base.InitDFAs(); + dfa10 = new DFA10(this); + } + + private class DFA10 : DFA + { + private const string DFA10_eotS = + "\x4\xFFFF\x1\x26\x1\xFFFF\x1\x29\x1\x2B\xA\xFFFF\x1\x2D\x1\xFFFF\xD\x22"+ + "\xD\xFFFF\x2\x22\x1\x42\x4\x22\x1\x47\x1\x49\x2\x22\x1\x4C\x2\x22\x1"+ + "\x4F\x5\x22\x1\xFFFF\x1\x22\x1\x56\x1\x57\x1\x22\x1\xFFFF\x1\x59\x1\xFFFF"+ + "\x1\x5A\x1\x5B\x1\xFFFF\x2\x22\x1\xFFFF\x1\x22\x1\x5F\x3\x22\x1\x63\x2"+ + "\xFFFF\x1\x22\x3\xFFFF\x1\x22\x1\x66\x1\x67\x1\xFFFF\x1\x22\x1\x69\x1"+ + "\x6A\x1\xFFFF\x2\x22\x2\xFFFF\x1\x6D\x2\xFFFF\x1\x22\x1\x6F\x1\xFFFF"+ + "\x1\x22\x1\xFFFF\x1\x71\x1\xFFFF"; + private const string DFA10_eofS = + "\x72\xFFFF"; + private const string DFA10_minS = + "\x1\x9\x3\xFFFF\x1\x2A\x1\xFFFF\x2\x3D\xA\xFFFF\x1\x3D\x1\xFFFF\x2\x72"+ + "\x1\x6F\x1\x6C\x1\x6F\x1\x66\x1\x65\x1\x69\x1\x66\x1\x74\x1\x68\x1\x61"+ + "\x1\x68\xD\xFFFF\x1\x72\x1\x65\x1\x30\x1\x73\x1\x64\x1\x72\x1\x6E\x2"+ + "\x30\x1\x74\x1\x6C\x1\x30\x1\x72\x1\x65\x1\x30\x1\x70\x1\x72\x1\x69\x2"+ + "\x61\x1\xFFFF\x1\x65\x2\x30\x1\x63\x1\xFFFF\x1\x30\x1\xFFFF\x2\x30\x1"+ + "\xFFFF\x1\x69\x1\x6E\x1\xFFFF\x1\x65\x1\x30\x1\x6C\x1\x79\x1\x6B\x1\x30"+ + "\x2\xFFFF\x1\x74\x3\xFFFF\x1\x6E\x2\x30\x1\xFFFF\x1\x65\x2\x30\x1\xFFFF"+ + "\x1\x69\x1\x67\x2\xFFFF\x1\x30\x2\xFFFF\x1\x6F\x1\x30\x1\xFFFF\x1\x6E"+ + "\x1\xFFFF\x1\x30\x1\xFFFF"; + private const string DFA10_maxS = + "\x1\x7D\x3\xFFFF\x1\x2A\x1\xFFFF\x1\x3E\x1\x3D\xA\xFFFF\x1\x3D\x1\xFFFF"+ + "\x2\x72\x1\x6F\x1\x6E\x1\x75\x1\x6E\x1\x65\x1\x69\x1\x66\x1\x74\x1\x79"+ + "\x1\x61\x1\x68\xD\xFFFF\x1\x72\x1\x65\x1\x7A\x1\x73\x1\x64\x1\x72\x1"+ + "\x6E\x2\x7A\x1\x74\x1\x6C\x1\x7A\x1\x72\x1\x65\x1\x7A\x1\x70\x1\x72\x1"+ + "\x69\x2\x61\x1\xFFFF\x1\x65\x2\x7A\x1\x63\x1\xFFFF\x1\x7A\x1\xFFFF\x2"+ + "\x7A\x1\xFFFF\x1\x69\x1\x6E\x1\xFFFF\x1\x65\x1\x7A\x1\x6C\x1\x79\x1\x6B"+ + "\x1\x7A\x2\xFFFF\x1\x74\x3\xFFFF\x1\x6E\x2\x7A\x1\xFFFF\x1\x65\x2\x7A"+ + "\x1\xFFFF\x1\x69\x1\x67\x2\xFFFF\x1\x7A\x2\xFFFF\x1\x6F\x1\x7A\x1\xFFFF"+ + "\x1\x6E\x1\xFFFF\x1\x7A\x1\xFFFF"; + private const string DFA10_acceptS = + "\x1\xFFFF\x1\x1\x1\x2\x1\x3\x1\xFFFF\x1\x5\x2\xFFFF\x1\xB\x1\xC\x1\xD"+ + "\x1\xE\x1\xF\x1\x10\x1\x11\x1\x12\x1\x13\x1\x14\x1\xFFFF\x1\x16\xD\xFFFF"+ + "\x1\x2B\x1\x2C\x1\x2D\x1\x2E\x1\x2F\x1\x4\x1\x6\x1\xA\x1\x9\x1\x8\x1"+ + "\x7\x1\x17\x1\x15\x14\xFFFF\x1\x1A\x4\xFFFF\x1\x1F\x1\xFFFF\x1\x20\x2"+ + "\xFFFF\x1\x24\x2\xFFFF\x1\x27\x6\xFFFF\x1\x1C\x1\x1D\x1\xFFFF\x1\x21"+ + "\x1\x22\x1\x23\x3\xFFFF\x1\x29\x3\xFFFF\x1\x1B\x2\xFFFF\x1\x26\x1\x28"+ + "\x1\xFFFF\x1\x18\x1\x19\x2\xFFFF\x1\x2A\x1\xFFFF\x1\x25\x1\xFFFF\x1\x1E"; + private const string DFA10_specialS = + "\x72\xFFFF}>"; + private static readonly string[] DFA10_transitionS = + { + "\x2\x23\x2\xFFFF\x1\x23\x12\xFFFF\x1\x23\x1\xFFFF\x1\x24\x3\xFFFF\x1"+ + "\x8\x1\xFFFF\x1\xA\x1\xB\x1\x3\x1\x1\x1\x10\x1\x2\x1\x13\x1\x4\xA\x21"+ + "\x1\x12\x1\x11\x1\x6\x1\x5\x1\x7\x2\xFFFF\x1A\x22\x1\xC\x1\xFFFF\x1"+ + "\xD\x3\xFFFF\x1\x14\x1\x15\x1\x22\x1\x16\x1\x17\x1\x18\x2\x22\x1\x19"+ + "\x2\x22\x1\x1A\x1\x22\x1\x1B\x1\x1C\x3\x22\x1\x1D\x1\x1E\x1\x22\x1\x1F"+ + "\x1\x20\x3\x22\x1\xE\x1\x9\x1\xF", + "", + "", + "", + "\x1\x25", + "", + "\x1\x28\x1\x27", + "\x1\x2A", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\x1\x2C", + "", + "\x1\x2E", + "\x1\x2F", + "\x1\x30", + "\x1\x31\x1\xFFFF\x1\x32", + "\x1\x33\x5\xFFFF\x1\x34", + "\x1\x35\x7\xFFFF\x1\x36", + "\x1\x37", + "\x1\x38", + "\x1\x39", + "\x1\x3A", + "\x1\x3B\x6\xFFFF\x1\x3C\x9\xFFFF\x1\x3D", + "\x1\x3E", + "\x1\x3F", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\x1\x40", + "\x1\x41", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\x1\x43", + "\x1\x44", + "\x1\x45", + "\x1\x46", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x13\x22\x1\x48\x6"+ + "\x22", + "\x1\x4A", + "\x1\x4B", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\x1\x4D", + "\x1\x4E", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\x1\x50", + "\x1\x51", + "\x1\x52", + "\x1\x53", + "\x1\x54", + "", + "\x1\x55", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\x1\x58", + "", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "", + "\x1\x5C", + "\x1\x5D", + "", + "\x1\x5E", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\x1\x60", + "\x1\x61", + "\x1\x62", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "", + "", + "\x1\x64", + "", + "", + "", + "\x1\x65", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "", + "\x1\x68", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "", + "\x1\x6B", + "\x1\x6C", + "", + "", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "", + "", + "\x1\x6E", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "", + "\x1\x70", + "", + "\xA\x22\x7\xFFFF\x1A\x22\x4\xFFFF\x1\x22\x1\xFFFF\x1A\x22", + "" + }; + + private static readonly short[] DFA10_eot = DFA.UnpackEncodedString(DFA10_eotS); + private static readonly short[] DFA10_eof = DFA.UnpackEncodedString(DFA10_eofS); + private static readonly char[] DFA10_min = DFA.UnpackEncodedStringToUnsignedChars(DFA10_minS); + private static readonly char[] DFA10_max = DFA.UnpackEncodedStringToUnsignedChars(DFA10_maxS); + private static readonly short[] DFA10_accept = DFA.UnpackEncodedString(DFA10_acceptS); + private static readonly short[] DFA10_special = DFA.UnpackEncodedString(DFA10_specialS); + private static readonly short[][] DFA10_transition; + + static DFA10() + { + int numStates = DFA10_transitionS.Length; + DFA10_transition = new short[numStates][]; + for ( int i=0; i < numStates; i++ ) + { + DFA10_transition[i] = DFA.UnpackEncodedString(DFA10_transitionS[i]); + } + } + + public DFA10( BaseRecognizer recognizer ) + { + this.recognizer = recognizer; + this.decisionNumber = 10; + this.eot = DFA10_eot; + this.eof = DFA10_eof; + this.min = DFA10_min; + this.max = DFA10_max; + this.accept = DFA10_accept; + this.special = DFA10_special; + this.transition = DFA10_transition; + } + + public override string Description { get { return "1:1: Tokens : ( PLUS | MINUS | MULT | DIV | EQ | NOTEQ | GT | GTEQ | LT | LTEQ | AND | OR | LPAREN | RPAREN | LBRACKET | RBRACKET | LKEY | RKEY | COMMA | SEMI | COLON | DOT | ASSIGN | ARRAYKEY | BREAKKEY | DOKEY | ELSEKEY | ENDKEY | FORKEY | FUNCTIONKEY | IFKEY | INKEY | INTKEY | LETKEY | NILKEY | OFKEY | STRINGKEY | THENKEY | TOKEY | TYPEKEY | VARKEY | WHILEKEY | INT | ID | WS | STRING | COMMENTARY );"; } } + + public override void Error(NoViableAltException nvae) + { + DebugRecognitionException(nvae); + } + } + + + #endregion + +} + +} // namespace YATC.Grammar diff --git a/Grammar/tigerParser.cs b/Grammar/tigerParser.cs new file mode 100644 index 0000000..73fa26c --- /dev/null +++ b/Grammar/tigerParser.cs @@ -0,0 +1,6497 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// ANTLR Version: 3.4 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +// $ANTLR 3.4 D:\\~Compilador\\!yatc\\Grammar\\tiger.g 2014-03-10 18:42:49 + +// The variable 'variable' is assigned but its value is never used. +#pragma warning disable 219 +// Unreachable code detected. +#pragma warning disable 162 +// Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable 1591 +// CLS compliance checking will not be performed on 'type' because it is not visible from outside this assembly. +#pragma warning disable 3019 + + + using System; + + +using System.Collections.Generic; +using Antlr.Runtime; +using Antlr.Runtime.Misc; + + +using Antlr.Runtime.Tree; +using RewriteRuleITokenStream = Antlr.Runtime.Tree.RewriteRuleTokenStream; + +namespace YATC.Grammar +{ +[System.CodeDom.Compiler.GeneratedCode("ANTLR", "3.4")] +[System.CLSCompliant(false)] +public partial class tigerParser : Antlr.Runtime.Parser +{ + internal static readonly string[] tokenNames = new string[] { + "", "", "", "", "ALIAS_DECL", "AND", "ARGS_FIELDS", "ARRAYKEY", "ARRAY_ACCESS", "ARRAY_DECL", "ARRAY_INST", "ASCII_ESC", "ASSIGN", "BEGIN_COMMENT", "BREAK", "BREAKKEY", "COLON", "COMMA", "COMMENTARY", "DECL_BLOCK", "DIGIT", "DIV", "DOKEY", "DOT", "ELSEKEY", "ENDKEY", "END_COMMENT", "EQ", "ESC_SEQ", "EXPR_SEQ", "FIELDS_INST", "FIELD_ACCESS", "FIELD_ACCESS_TERMINAL", "FIELD_INST", "FILL_IN_TYPE", "FOR", "FORKEY", "FUNCTIONKEY", "FUN_CALL", "FUN_DECL", "FUN_DECL_SEQ", "FUN_TYPE_WRAPPER", "GT", "GTEQ", "ID", "IF", "IFKEY", "INKEY", "INT", "INTKEY", "LBRACKET", "LET", "LETKEY", "LETTER", "LKEY", "LPAREN", "LT", "LTEQ", "MINUS", "MULT", "NEG", "NIL", "NILKEY", "NOTEQ", "OFKEY", "OR", "PARAM_DECL", "PLUS", "PRINTABLE_CHARACTER", "PROGRAM", "QUOTE", "RBRACKET", "RECORD_DECL", "RECORD_INST", "RKEY", "RPAREN", "SEMI", "STRING", "STRINGKEY", "THENKEY", "TOKEY", "TYPE", "TYPEKEY", "TYPE_DECL", "TYPE_DECL_SEQ", "TYPE_FIELD", "VARKEY", "VAR_ACCESS", "VAR_DECL", "WHILE", "WHILEKEY", "WS" + }; + public const int EOF=-1; + public const int ALIAS_DECL=4; + public const int AND=5; + public const int ARGS_FIELDS=6; + public const int ARRAYKEY=7; + public const int ARRAY_ACCESS=8; + public const int ARRAY_DECL=9; + public const int ARRAY_INST=10; + public const int ASCII_ESC=11; + public const int ASSIGN=12; + public const int BEGIN_COMMENT=13; + public const int BREAK=14; + public const int BREAKKEY=15; + public const int COLON=16; + public const int COMMA=17; + public const int COMMENTARY=18; + public const int DECL_BLOCK=19; + public const int DIGIT=20; + public const int DIV=21; + public const int DOKEY=22; + public const int DOT=23; + public const int ELSEKEY=24; + public const int ENDKEY=25; + public const int END_COMMENT=26; + public const int EQ=27; + public const int ESC_SEQ=28; + public const int EXPR_SEQ=29; + public const int FIELDS_INST=30; + public const int FIELD_ACCESS=31; + public const int FIELD_ACCESS_TERMINAL=32; + public const int FIELD_INST=33; + public const int FILL_IN_TYPE=34; + public const int FOR=35; + public const int FORKEY=36; + public const int FUNCTIONKEY=37; + public const int FUN_CALL=38; + public const int FUN_DECL=39; + public const int FUN_DECL_SEQ=40; + public const int FUN_TYPE_WRAPPER=41; + public const int GT=42; + public const int GTEQ=43; + public const int ID=44; + public const int IF=45; + public const int IFKEY=46; + public const int INKEY=47; + public const int INT=48; + public const int INTKEY=49; + public const int LBRACKET=50; + public const int LET=51; + public const int LETKEY=52; + public const int LETTER=53; + public const int LKEY=54; + public const int LPAREN=55; + public const int LT=56; + public const int LTEQ=57; + public const int MINUS=58; + public const int MULT=59; + public const int NEG=60; + public const int NIL=61; + public const int NILKEY=62; + public const int NOTEQ=63; + public const int OFKEY=64; + public const int OR=65; + public const int PARAM_DECL=66; + public const int PLUS=67; + public const int PRINTABLE_CHARACTER=68; + public const int PROGRAM=69; + public const int QUOTE=70; + public const int RBRACKET=71; + public const int RECORD_DECL=72; + public const int RECORD_INST=73; + public const int RKEY=74; + public const int RPAREN=75; + public const int SEMI=76; + public const int STRING=77; + public const int STRINGKEY=78; + public const int THENKEY=79; + public const int TOKEY=80; + public const int TYPE=81; + public const int TYPEKEY=82; + public const int TYPE_DECL=83; + public const int TYPE_DECL_SEQ=84; + public const int TYPE_FIELD=85; + public const int VARKEY=86; + public const int VAR_ACCESS=87; + public const int VAR_DECL=88; + public const int WHILE=89; + public const int WHILEKEY=90; + public const int WS=91; + + public tigerParser(ITokenStream input) + : this(input, new RecognizerSharedState()) + { + } + public tigerParser(ITokenStream input, RecognizerSharedState state) + : base(input, state) + { + ITreeAdaptor treeAdaptor = default(ITreeAdaptor); + CreateTreeAdaptor(ref treeAdaptor); + TreeAdaptor = treeAdaptor ?? new CommonTreeAdaptor(); + OnCreated(); + } + // Implement this function in your helper file to use a custom tree adaptor + partial void CreateTreeAdaptor(ref ITreeAdaptor adaptor); + + private ITreeAdaptor adaptor; + + public ITreeAdaptor TreeAdaptor + { + get + { + return adaptor; + } + + set + { + this.adaptor = value; + } + } + + public override string[] TokenNames { get { return tigerParser.tokenNames; } } + public override string GrammarFileName { get { return "D:\\~Compilador\\!yatc\\Grammar\\tiger.g"; } } + + + public override void ReportError(RecognitionException exc) + { + /* Abort on first error. */ + throw new ParsingException(GetErrorMessage(exc, TokenNames), exc); + } + + + partial void OnCreated(); + partial void EnterRule(string ruleName, int ruleIndex); + partial void LeaveRule(string ruleName, int ruleIndex); + + #region Rules + partial void EnterRule_a_program(); + partial void LeaveRule_a_program(); + + // $ANTLR start "a_program" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:218:8: public a_program : ( expr )? EOF -> ^( PROGRAM ( expr )? ) ; + [GrammarRule("a_program")] + public AstParserRuleReturnScope a_program() + { + EnterRule_a_program(); + EnterRule("a_program", 1); + TraceIn("a_program", 1); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken EOF2 = default(IToken); + AstParserRuleReturnScope expr1 = default(AstParserRuleReturnScope); + + object EOF2_tree = default(object); + RewriteRuleITokenStream stream_EOF=new RewriteRuleITokenStream(adaptor,"token EOF"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "a_program"); + DebugLocation(218, 23); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:219:2: ( ( expr )? EOF -> ^( PROGRAM ( expr )? ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:219:4: ( expr )? EOF + { + DebugLocation(219, 4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:219:4: ( expr )? + int alt1=2; + try { DebugEnterSubRule(1); + try { DebugEnterDecision(1, false); + int LA1_0 = input.LA(1); + + if ((LA1_0==BREAKKEY||LA1_0==FORKEY||LA1_0==ID||LA1_0==IFKEY||(LA1_0>=INT && LA1_0<=INTKEY)||LA1_0==LETKEY||LA1_0==LPAREN||LA1_0==MINUS||LA1_0==NILKEY||(LA1_0>=STRING && LA1_0<=STRINGKEY)||LA1_0==WHILEKEY)) + { + alt1 = 1; + } + } finally { DebugExitDecision(1); } + switch (alt1) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:219:4: expr + { + DebugLocation(219, 4); + PushFollow(Follow._expr_in_a_program1145); + expr1=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr1.Tree); + + } + break; + + } + } finally { DebugExitSubRule(1); } + + DebugLocation(219, 11); + EOF2=(IToken)Match(input,EOF,Follow._EOF_in_a_program1149); if (state.failed) return retval; + if (state.backtracking == 0) stream_EOF.Add(EOF2); + + + + { + // AST REWRITE + // elements: expr + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 220:3: -> ^( PROGRAM ( expr )? ) + { + DebugLocation(220, 6); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:220:6: ^( PROGRAM ( expr )? ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(220, 8); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(PROGRAM, "PROGRAM"), root_1); + + DebugLocation(220, 16); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:220:16: ( expr )? + if (stream_expr.HasNext) + { + DebugLocation(220, 16); + adaptor.AddChild(root_1, stream_expr.NextTree()); + + } + stream_expr.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("a_program", 1); + LeaveRule("a_program", 1); + LeaveRule_a_program(); + } + DebugLocation(220, 23); + } finally { DebugExitRule(GrammarFileName, "a_program"); } + return retval; + + } + // $ANTLR end "a_program" + + partial void EnterRule_expr(); + partial void LeaveRule_expr(); + + // $ANTLR start "expr" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:222:1: expr : ( ( ID LBRACKET disjunction_expr RBRACKET OFKEY )=> array_inst | ( lvalue ASSIGN )=> assignment | disjunction_expr | record_inst | while_stat | BREAKKEY -> BREAK ); + [GrammarRule("expr")] + private AstParserRuleReturnScope expr() + { + EnterRule_expr(); + EnterRule("expr", 2); + TraceIn("expr", 2); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken BREAKKEY8 = default(IToken); + AstParserRuleReturnScope array_inst3 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope assignment4 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope disjunction_expr5 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope record_inst6 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope while_stat7 = default(AstParserRuleReturnScope); + + object BREAKKEY8_tree = default(object); + RewriteRuleITokenStream stream_BREAKKEY=new RewriteRuleITokenStream(adaptor,"token BREAKKEY"); + try { DebugEnterRule(GrammarFileName, "expr"); + DebugLocation(222, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:223:2: ( ( ID LBRACKET disjunction_expr RBRACKET OFKEY )=> array_inst | ( lvalue ASSIGN )=> assignment | disjunction_expr | record_inst | while_stat | BREAKKEY -> BREAK ) + int alt2=6; + try { DebugEnterDecision(2, false); + try + { + alt2 = dfa2.Predict(input); + } + catch (NoViableAltException nvae) + { + DebugRecognitionException(nvae); + throw; + } + } finally { DebugExitDecision(2); } + switch (alt2) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:223:4: ( ID LBRACKET disjunction_expr RBRACKET OFKEY )=> array_inst + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(223, 53); + PushFollow(Follow._array_inst_in_expr1185); + array_inst3=array_inst(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, array_inst3.Tree); + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:224:4: ( lvalue ASSIGN )=> assignment + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(224, 23); + PushFollow(Follow._assignment_in_expr1198); + assignment4=assignment(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, assignment4.Tree); + + } + break; + case 3: + DebugEnterAlt(3); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:225:4: disjunction_expr + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(225, 4); + PushFollow(Follow._disjunction_expr_in_expr1203); + disjunction_expr5=disjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, disjunction_expr5.Tree); + + } + break; + case 4: + DebugEnterAlt(4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:226:4: record_inst + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(226, 4); + PushFollow(Follow._record_inst_in_expr1209); + record_inst6=record_inst(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, record_inst6.Tree); + + } + break; + case 5: + DebugEnterAlt(5); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:227:4: while_stat + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(227, 4); + PushFollow(Follow._while_stat_in_expr1214); + while_stat7=while_stat(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, while_stat7.Tree); + + } + break; + case 6: + DebugEnterAlt(6); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:228:4: BREAKKEY + { + DebugLocation(228, 4); + BREAKKEY8=(IToken)Match(input,BREAKKEY,Follow._BREAKKEY_in_expr1219); if (state.failed) return retval; + if (state.backtracking == 0) stream_BREAKKEY.Add(BREAKKEY8); + + + + { + // AST REWRITE + // elements: + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 229:13: -> BREAK + { + DebugLocation(229, 16); + adaptor.AddChild(root_0, (object)adaptor.Create(BREAK, "BREAK")); + + } + + retval.Tree = root_0; + } + } + + } + break; + + } + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("expr", 2); + LeaveRule("expr", 2); + LeaveRule_expr(); + } + DebugLocation(230, 1); + } finally { DebugExitRule(GrammarFileName, "expr"); } + return retval; + + } + // $ANTLR end "expr" + + partial void EnterRule_disjunction_expr(); + partial void LeaveRule_disjunction_expr(); + + // $ANTLR start "disjunction_expr" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:232:1: disjunction_expr : conjunction_expr ( OR ^ conjunction_expr )* ; + [GrammarRule("disjunction_expr")] + private AstParserRuleReturnScope disjunction_expr() + { + EnterRule_disjunction_expr(); + EnterRule("disjunction_expr", 3); + TraceIn("disjunction_expr", 3); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken OR10 = default(IToken); + AstParserRuleReturnScope conjunction_expr9 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope conjunction_expr11 = default(AstParserRuleReturnScope); + + object OR10_tree = default(object); + try { DebugEnterRule(GrammarFileName, "disjunction_expr"); + DebugLocation(232, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:233:2: ( conjunction_expr ( OR ^ conjunction_expr )* ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:233:4: conjunction_expr ( OR ^ conjunction_expr )* + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(233, 4); + PushFollow(Follow._conjunction_expr_in_disjunction_expr1248); + conjunction_expr9=conjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, conjunction_expr9.Tree); + DebugLocation(233, 21); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:233:21: ( OR ^ conjunction_expr )* + try { DebugEnterSubRule(3); + while (true) + { + int alt3=2; + try { DebugEnterDecision(3, false); + int LA3_0 = input.LA(1); + + if ((LA3_0==OR)) + { + alt3 = 1; + } + + + } finally { DebugExitDecision(3); } + switch ( alt3 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:233:22: OR ^ conjunction_expr + { + DebugLocation(233, 24); + OR10=(IToken)Match(input,OR,Follow._OR_in_disjunction_expr1251); if (state.failed) return retval; + if (state.backtracking == 0) { + OR10_tree = (object)adaptor.Create(OR10); + root_0 = (object)adaptor.BecomeRoot(OR10_tree, root_0); + } + DebugLocation(233, 26); + PushFollow(Follow._conjunction_expr_in_disjunction_expr1254); + conjunction_expr11=conjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, conjunction_expr11.Tree); + + } + break; + + default: + goto loop3; + } + } + + loop3: + ; + + } finally { DebugExitSubRule(3); } + + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("disjunction_expr", 3); + LeaveRule("disjunction_expr", 3); + LeaveRule_disjunction_expr(); + } + DebugLocation(234, 1); + } finally { DebugExitRule(GrammarFileName, "disjunction_expr"); } + return retval; + + } + // $ANTLR end "disjunction_expr" + + partial void EnterRule_assignment(); + partial void LeaveRule_assignment(); + + // $ANTLR start "assignment" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:236:1: assignment : lvalue ASSIGN ^ ( ( ID LBRACKET disjunction_expr RBRACKET OFKEY )=> array_inst | disjunction_expr | record_inst ) ; + [GrammarRule("assignment")] + private AstParserRuleReturnScope assignment() + { + EnterRule_assignment(); + EnterRule("assignment", 4); + TraceIn("assignment", 4); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken ASSIGN13 = default(IToken); + AstParserRuleReturnScope lvalue12 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope array_inst14 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope disjunction_expr15 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope record_inst16 = default(AstParserRuleReturnScope); + + object ASSIGN13_tree = default(object); + try { DebugEnterRule(GrammarFileName, "assignment"); + DebugLocation(236, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:237:2: ( lvalue ASSIGN ^ ( ( ID LBRACKET disjunction_expr RBRACKET OFKEY )=> array_inst | disjunction_expr | record_inst ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:237:4: lvalue ASSIGN ^ ( ( ID LBRACKET disjunction_expr RBRACKET OFKEY )=> array_inst | disjunction_expr | record_inst ) + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(237, 4); + PushFollow(Follow._lvalue_in_assignment1267); + lvalue12=lvalue(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, lvalue12.Tree); + DebugLocation(237, 17); + ASSIGN13=(IToken)Match(input,ASSIGN,Follow._ASSIGN_in_assignment1269); if (state.failed) return retval; + if (state.backtracking == 0) { + ASSIGN13_tree = (object)adaptor.Create(ASSIGN13); + root_0 = (object)adaptor.BecomeRoot(ASSIGN13_tree, root_0); + } + DebugLocation(238, 4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:238:4: ( ( ID LBRACKET disjunction_expr RBRACKET OFKEY )=> array_inst | disjunction_expr | record_inst ) + int alt4=3; + try { DebugEnterSubRule(4); + try { DebugEnterDecision(4, false); + int LA4_0 = input.LA(1); + + if ((LA4_0==ID)) + { + switch (input.LA(2)) + { + case LBRACKET: + { + switch (input.LA(3)) + { + case MINUS: + { + int LA4_33 = input.LA(4); + + if ((EvaluatePredicate(synpred3_tiger_fragment))) + { + alt4 = 1; + } + else if ((true)) + { + alt4 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 33, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + break; + case INT: + case NILKEY: + case STRING: + { + int LA4_34 = input.LA(4); + + if ((EvaluatePredicate(synpred3_tiger_fragment))) + { + alt4 = 1; + } + else if ((true)) + { + alt4 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 34, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + break; + case ID: + case INTKEY: + case STRINGKEY: + { + int LA4_35 = input.LA(4); + + if ((EvaluatePredicate(synpred3_tiger_fragment))) + { + alt4 = 1; + } + else if ((true)) + { + alt4 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 35, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + break; + case IFKEY: + { + int LA4_36 = input.LA(4); + + if ((EvaluatePredicate(synpred3_tiger_fragment))) + { + alt4 = 1; + } + else if ((true)) + { + alt4 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 36, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + break; + case FORKEY: + { + int LA4_37 = input.LA(4); + + if ((EvaluatePredicate(synpred3_tiger_fragment))) + { + alt4 = 1; + } + else if ((true)) + { + alt4 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 37, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + break; + case LETKEY: + { + int LA4_38 = input.LA(4); + + if ((EvaluatePredicate(synpred3_tiger_fragment))) + { + alt4 = 1; + } + else if ((true)) + { + alt4 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 38, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + break; + case LPAREN: + { + int LA4_39 = input.LA(4); + + if ((EvaluatePredicate(synpred3_tiger_fragment))) + { + alt4 = 1; + } + else if ((true)) + { + alt4 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 39, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + break; + default: + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 9, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + + } + break; + case LKEY: + { + alt4 = 3; + } + break; + case EOF: + case AND: + case COMMA: + case DIV: + case DOKEY: + case DOT: + case ELSEKEY: + case ENDKEY: + case EQ: + case FUNCTIONKEY: + case GT: + case GTEQ: + case INKEY: + case LPAREN: + case LT: + case LTEQ: + case MINUS: + case MULT: + case NOTEQ: + case OR: + case PLUS: + case RBRACKET: + case RKEY: + case RPAREN: + case SEMI: + case THENKEY: + case TOKEY: + case TYPEKEY: + case VARKEY: + { + alt4 = 2; + } + break; + default: + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 1, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + + } + else if ((LA4_0==FORKEY||LA4_0==IFKEY||(LA4_0>=INT && LA4_0<=INTKEY)||LA4_0==LETKEY||LA4_0==LPAREN||LA4_0==MINUS||LA4_0==NILKEY||(LA4_0>=STRING && LA4_0<=STRINGKEY))) + { + alt4 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 4, 0, input); + DebugRecognitionException(nvae); + throw nvae; + } + } finally { DebugExitDecision(4); } + switch (alt4) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:238:6: ( ID LBRACKET disjunction_expr RBRACKET OFKEY )=> array_inst + { + DebugLocation(238, 55); + PushFollow(Follow._array_inst_in_assignment1292); + array_inst14=array_inst(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, array_inst14.Tree); + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:239:6: disjunction_expr + { + DebugLocation(239, 6); + PushFollow(Follow._disjunction_expr_in_assignment1300); + disjunction_expr15=disjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, disjunction_expr15.Tree); + + } + break; + case 3: + DebugEnterAlt(3); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:240:6: record_inst + { + DebugLocation(240, 6); + PushFollow(Follow._record_inst_in_assignment1308); + record_inst16=record_inst(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, record_inst16.Tree); + + } + break; + + } + } finally { DebugExitSubRule(4); } + + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("assignment", 4); + LeaveRule("assignment", 4); + LeaveRule_assignment(); + } + DebugLocation(242, 1); + } finally { DebugExitRule(GrammarFileName, "assignment"); } + return retval; + + } + // $ANTLR end "assignment" + + partial void EnterRule_record_inst(); + partial void LeaveRule_record_inst(); + + // $ANTLR start "record_inst" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:244:1: record_inst : ID LKEY ( field_inst_list )? RKEY -> ^( RECORD_INST ID ( field_inst_list )? ) ; + [GrammarRule("record_inst")] + private AstParserRuleReturnScope record_inst() + { + EnterRule_record_inst(); + EnterRule("record_inst", 5); + TraceIn("record_inst", 5); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken ID17 = default(IToken); + IToken LKEY18 = default(IToken); + IToken RKEY20 = default(IToken); + AstParserRuleReturnScope field_inst_list19 = default(AstParserRuleReturnScope); + + object ID17_tree = default(object); + object LKEY18_tree = default(object); + object RKEY20_tree = default(object); + RewriteRuleITokenStream stream_LKEY=new RewriteRuleITokenStream(adaptor,"token LKEY"); + RewriteRuleITokenStream stream_ID=new RewriteRuleITokenStream(adaptor,"token ID"); + RewriteRuleITokenStream stream_RKEY=new RewriteRuleITokenStream(adaptor,"token RKEY"); + RewriteRuleSubtreeStream stream_field_inst_list=new RewriteRuleSubtreeStream(adaptor,"rule field_inst_list"); + try { DebugEnterRule(GrammarFileName, "record_inst"); + DebugLocation(244, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:245:2: ( ID LKEY ( field_inst_list )? RKEY -> ^( RECORD_INST ID ( field_inst_list )? ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:245:4: ID LKEY ( field_inst_list )? RKEY + { + DebugLocation(245, 4); + ID17=(IToken)Match(input,ID,Follow._ID_in_record_inst1325); if (state.failed) return retval; + if (state.backtracking == 0) stream_ID.Add(ID17); + + DebugLocation(245, 7); + LKEY18=(IToken)Match(input,LKEY,Follow._LKEY_in_record_inst1327); if (state.failed) return retval; + if (state.backtracking == 0) stream_LKEY.Add(LKEY18); + + DebugLocation(245, 12); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:245:12: ( field_inst_list )? + int alt5=2; + try { DebugEnterSubRule(5); + try { DebugEnterDecision(5, false); + int LA5_0 = input.LA(1); + + if ((LA5_0==ID)) + { + alt5 = 1; + } + } finally { DebugExitDecision(5); } + switch (alt5) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:245:12: field_inst_list + { + DebugLocation(245, 12); + PushFollow(Follow._field_inst_list_in_record_inst1329); + field_inst_list19=field_inst_list(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_field_inst_list.Add(field_inst_list19.Tree); + + } + break; + + } + } finally { DebugExitSubRule(5); } + + DebugLocation(245, 29); + RKEY20=(IToken)Match(input,RKEY,Follow._RKEY_in_record_inst1332); if (state.failed) return retval; + if (state.backtracking == 0) stream_RKEY.Add(RKEY20); + + + + { + // AST REWRITE + // elements: ID, field_inst_list + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 246:4: -> ^( RECORD_INST ID ( field_inst_list )? ) + { + DebugLocation(246, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:246:7: ^( RECORD_INST ID ( field_inst_list )? ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(246, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(RECORD_INST, "RECORD_INST"), root_1); + + DebugLocation(246, 21); + adaptor.AddChild(root_1, stream_ID.NextNode()); + DebugLocation(246, 24); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:246:24: ( field_inst_list )? + if (stream_field_inst_list.HasNext) + { + DebugLocation(246, 24); + adaptor.AddChild(root_1, stream_field_inst_list.NextTree()); + + } + stream_field_inst_list.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("record_inst", 5); + LeaveRule("record_inst", 5); + LeaveRule_record_inst(); + } + DebugLocation(247, 1); + } finally { DebugExitRule(GrammarFileName, "record_inst"); } + return retval; + + } + // $ANTLR end "record_inst" + + partial void EnterRule_for_expr(); + partial void LeaveRule_for_expr(); + + // $ANTLR start "for_expr" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:254:1: for_expr : FORKEY type_id ASSIGN disjunction_expr TOKEY disjunction_expr DOKEY expr -> ^( FOR type_id disjunction_expr disjunction_expr expr ) ; + [GrammarRule("for_expr")] + private AstParserRuleReturnScope for_expr() + { + EnterRule_for_expr(); + EnterRule("for_expr", 6); + TraceIn("for_expr", 6); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken FORKEY21 = default(IToken); + IToken ASSIGN23 = default(IToken); + IToken TOKEY25 = default(IToken); + IToken DOKEY27 = default(IToken); + AstParserRuleReturnScope type_id22 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope disjunction_expr24 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope disjunction_expr26 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope expr28 = default(AstParserRuleReturnScope); + + object FORKEY21_tree = default(object); + object ASSIGN23_tree = default(object); + object TOKEY25_tree = default(object); + object DOKEY27_tree = default(object); + RewriteRuleITokenStream stream_TOKEY=new RewriteRuleITokenStream(adaptor,"token TOKEY"); + RewriteRuleITokenStream stream_FORKEY=new RewriteRuleITokenStream(adaptor,"token FORKEY"); + RewriteRuleITokenStream stream_DOKEY=new RewriteRuleITokenStream(adaptor,"token DOKEY"); + RewriteRuleITokenStream stream_ASSIGN=new RewriteRuleITokenStream(adaptor,"token ASSIGN"); + RewriteRuleSubtreeStream stream_type_id=new RewriteRuleSubtreeStream(adaptor,"rule type_id"); + RewriteRuleSubtreeStream stream_disjunction_expr=new RewriteRuleSubtreeStream(adaptor,"rule disjunction_expr"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "for_expr"); + DebugLocation(254, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:255:2: ( FORKEY type_id ASSIGN disjunction_expr TOKEY disjunction_expr DOKEY expr -> ^( FOR type_id disjunction_expr disjunction_expr expr ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:255:4: FORKEY type_id ASSIGN disjunction_expr TOKEY disjunction_expr DOKEY expr + { + DebugLocation(255, 4); + FORKEY21=(IToken)Match(input,FORKEY,Follow._FORKEY_in_for_expr1359); if (state.failed) return retval; + if (state.backtracking == 0) stream_FORKEY.Add(FORKEY21); + + DebugLocation(255, 11); + PushFollow(Follow._type_id_in_for_expr1361); + type_id22=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id22.Tree); + DebugLocation(255, 19); + ASSIGN23=(IToken)Match(input,ASSIGN,Follow._ASSIGN_in_for_expr1363); if (state.failed) return retval; + if (state.backtracking == 0) stream_ASSIGN.Add(ASSIGN23); + + DebugLocation(255, 26); + PushFollow(Follow._disjunction_expr_in_for_expr1365); + disjunction_expr24=disjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_disjunction_expr.Add(disjunction_expr24.Tree); + DebugLocation(255, 43); + TOKEY25=(IToken)Match(input,TOKEY,Follow._TOKEY_in_for_expr1367); if (state.failed) return retval; + if (state.backtracking == 0) stream_TOKEY.Add(TOKEY25); + + DebugLocation(255, 49); + PushFollow(Follow._disjunction_expr_in_for_expr1369); + disjunction_expr26=disjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_disjunction_expr.Add(disjunction_expr26.Tree); + DebugLocation(255, 66); + DOKEY27=(IToken)Match(input,DOKEY,Follow._DOKEY_in_for_expr1371); if (state.failed) return retval; + if (state.backtracking == 0) stream_DOKEY.Add(DOKEY27); + + DebugLocation(255, 72); + PushFollow(Follow._expr_in_for_expr1373); + expr28=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr28.Tree); + + + { + // AST REWRITE + // elements: type_id, expr, disjunction_expr, disjunction_expr + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 256:4: -> ^( FOR type_id disjunction_expr disjunction_expr expr ) + { + DebugLocation(256, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:256:7: ^( FOR type_id disjunction_expr disjunction_expr expr ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(256, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(FOR, "FOR"), root_1); + + DebugLocation(256, 13); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + DebugLocation(256, 21); + adaptor.AddChild(root_1, stream_disjunction_expr.NextTree()); + DebugLocation(256, 38); + adaptor.AddChild(root_1, stream_disjunction_expr.NextTree()); + DebugLocation(256, 55); + adaptor.AddChild(root_1, stream_expr.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("for_expr", 6); + LeaveRule("for_expr", 6); + LeaveRule_for_expr(); + } + DebugLocation(257, 1); + } finally { DebugExitRule(GrammarFileName, "for_expr"); } + return retval; + + } + // $ANTLR end "for_expr" + + partial void EnterRule_array_inst(); + partial void LeaveRule_array_inst(); + + // $ANTLR start "array_inst" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:259:1: array_inst : ID LBRACKET disjunction_expr RBRACKET OFKEY expr -> ^( ARRAY_INST ID disjunction_expr expr ) ; + [GrammarRule("array_inst")] + private AstParserRuleReturnScope array_inst() + { + EnterRule_array_inst(); + EnterRule("array_inst", 7); + TraceIn("array_inst", 7); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken ID29 = default(IToken); + IToken LBRACKET30 = default(IToken); + IToken RBRACKET32 = default(IToken); + IToken OFKEY33 = default(IToken); + AstParserRuleReturnScope disjunction_expr31 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope expr34 = default(AstParserRuleReturnScope); + + object ID29_tree = default(object); + object LBRACKET30_tree = default(object); + object RBRACKET32_tree = default(object); + object OFKEY33_tree = default(object); + RewriteRuleITokenStream stream_OFKEY=new RewriteRuleITokenStream(adaptor,"token OFKEY"); + RewriteRuleITokenStream stream_LBRACKET=new RewriteRuleITokenStream(adaptor,"token LBRACKET"); + RewriteRuleITokenStream stream_RBRACKET=new RewriteRuleITokenStream(adaptor,"token RBRACKET"); + RewriteRuleITokenStream stream_ID=new RewriteRuleITokenStream(adaptor,"token ID"); + RewriteRuleSubtreeStream stream_disjunction_expr=new RewriteRuleSubtreeStream(adaptor,"rule disjunction_expr"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "array_inst"); + DebugLocation(259, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:260:2: ( ID LBRACKET disjunction_expr RBRACKET OFKEY expr -> ^( ARRAY_INST ID disjunction_expr expr ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:260:4: ID LBRACKET disjunction_expr RBRACKET OFKEY expr + { + DebugLocation(260, 4); + ID29=(IToken)Match(input,ID,Follow._ID_in_array_inst1401); if (state.failed) return retval; + if (state.backtracking == 0) stream_ID.Add(ID29); + + DebugLocation(260, 7); + LBRACKET30=(IToken)Match(input,LBRACKET,Follow._LBRACKET_in_array_inst1403); if (state.failed) return retval; + if (state.backtracking == 0) stream_LBRACKET.Add(LBRACKET30); + + DebugLocation(260, 16); + PushFollow(Follow._disjunction_expr_in_array_inst1405); + disjunction_expr31=disjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_disjunction_expr.Add(disjunction_expr31.Tree); + DebugLocation(260, 33); + RBRACKET32=(IToken)Match(input,RBRACKET,Follow._RBRACKET_in_array_inst1407); if (state.failed) return retval; + if (state.backtracking == 0) stream_RBRACKET.Add(RBRACKET32); + + DebugLocation(260, 42); + OFKEY33=(IToken)Match(input,OFKEY,Follow._OFKEY_in_array_inst1409); if (state.failed) return retval; + if (state.backtracking == 0) stream_OFKEY.Add(OFKEY33); + + DebugLocation(260, 48); + PushFollow(Follow._expr_in_array_inst1411); + expr34=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr34.Tree); + + + { + // AST REWRITE + // elements: ID, expr, disjunction_expr + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 261:4: -> ^( ARRAY_INST ID disjunction_expr expr ) + { + DebugLocation(261, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:261:7: ^( ARRAY_INST ID disjunction_expr expr ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(261, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(ARRAY_INST, "ARRAY_INST"), root_1); + + DebugLocation(261, 20); + adaptor.AddChild(root_1, stream_ID.NextNode()); + DebugLocation(261, 23); + adaptor.AddChild(root_1, stream_disjunction_expr.NextTree()); + DebugLocation(261, 40); + adaptor.AddChild(root_1, stream_expr.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("array_inst", 7); + LeaveRule("array_inst", 7); + LeaveRule_array_inst(); + } + DebugLocation(262, 1); + } finally { DebugExitRule(GrammarFileName, "array_inst"); } + return retval; + + } + // $ANTLR end "array_inst" + + partial void EnterRule_conjunction_expr(); + partial void LeaveRule_conjunction_expr(); + + // $ANTLR start "conjunction_expr" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:264:1: conjunction_expr : relational_expr ( AND ^ relational_expr )* ; + [GrammarRule("conjunction_expr")] + private AstParserRuleReturnScope conjunction_expr() + { + EnterRule_conjunction_expr(); + EnterRule("conjunction_expr", 8); + TraceIn("conjunction_expr", 8); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken AND36 = default(IToken); + AstParserRuleReturnScope relational_expr35 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope relational_expr37 = default(AstParserRuleReturnScope); + + object AND36_tree = default(object); + try { DebugEnterRule(GrammarFileName, "conjunction_expr"); + DebugLocation(264, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:265:2: ( relational_expr ( AND ^ relational_expr )* ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:265:4: relational_expr ( AND ^ relational_expr )* + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(265, 4); + PushFollow(Follow._relational_expr_in_conjunction_expr1437); + relational_expr35=relational_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, relational_expr35.Tree); + DebugLocation(265, 20); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:265:20: ( AND ^ relational_expr )* + try { DebugEnterSubRule(6); + while (true) + { + int alt6=2; + try { DebugEnterDecision(6, false); + int LA6_0 = input.LA(1); + + if ((LA6_0==AND)) + { + alt6 = 1; + } + + + } finally { DebugExitDecision(6); } + switch ( alt6 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:265:21: AND ^ relational_expr + { + DebugLocation(265, 24); + AND36=(IToken)Match(input,AND,Follow._AND_in_conjunction_expr1440); if (state.failed) return retval; + if (state.backtracking == 0) { + AND36_tree = (object)adaptor.Create(AND36); + root_0 = (object)adaptor.BecomeRoot(AND36_tree, root_0); + } + DebugLocation(265, 26); + PushFollow(Follow._relational_expr_in_conjunction_expr1443); + relational_expr37=relational_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, relational_expr37.Tree); + + } + break; + + default: + goto loop6; + } + } + + loop6: + ; + + } finally { DebugExitSubRule(6); } + + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("conjunction_expr", 8); + LeaveRule("conjunction_expr", 8); + LeaveRule_conjunction_expr(); + } + DebugLocation(266, 1); + } finally { DebugExitRule(GrammarFileName, "conjunction_expr"); } + return retval; + + } + // $ANTLR end "conjunction_expr" + + partial void EnterRule_relational_expr(); + partial void LeaveRule_relational_expr(); + + // $ANTLR start "relational_expr" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:273:1: relational_expr : arith_expr ( ( EQ | NOTEQ | GT | LT | GTEQ | LTEQ ) ^ arith_expr )? ; + [GrammarRule("relational_expr")] + private AstParserRuleReturnScope relational_expr() + { + EnterRule_relational_expr(); + EnterRule("relational_expr", 9); + TraceIn("relational_expr", 9); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken set39 = default(IToken); + AstParserRuleReturnScope arith_expr38 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope arith_expr40 = default(AstParserRuleReturnScope); + + object set39_tree = default(object); + try { DebugEnterRule(GrammarFileName, "relational_expr"); + DebugLocation(273, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:274:2: ( arith_expr ( ( EQ | NOTEQ | GT | LT | GTEQ | LTEQ ) ^ arith_expr )? ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:274:4: arith_expr ( ( EQ | NOTEQ | GT | LT | GTEQ | LTEQ ) ^ arith_expr )? + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(274, 4); + PushFollow(Follow._arith_expr_in_relational_expr1459); + arith_expr38=arith_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, arith_expr38.Tree); + DebugLocation(274, 15); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:274:15: ( ( EQ | NOTEQ | GT | LT | GTEQ | LTEQ ) ^ arith_expr )? + int alt7=2; + try { DebugEnterSubRule(7); + try { DebugEnterDecision(7, false); + int LA7_0 = input.LA(1); + + if ((LA7_0==EQ||(LA7_0>=GT && LA7_0<=GTEQ)||(LA7_0>=LT && LA7_0<=LTEQ)||LA7_0==NOTEQ)) + { + alt7 = 1; + } + } finally { DebugExitDecision(7); } + switch (alt7) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:274:16: ( EQ | NOTEQ | GT | LT | GTEQ | LTEQ ) ^ arith_expr + { + DebugLocation(274, 53); + + set39=(IToken)input.LT(1); + set39=(IToken)input.LT(1); + if (input.LA(1)==EQ||(input.LA(1)>=GT && input.LA(1)<=GTEQ)||(input.LA(1)>=LT && input.LA(1)<=LTEQ)||input.LA(1)==NOTEQ) + { + input.Consume(); + if (state.backtracking == 0) root_0 = (object)adaptor.BecomeRoot((object)adaptor.Create(set39), root_0); + state.errorRecovery=false;state.failed=false; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + MismatchedSetException mse = new MismatchedSetException(null,input); + DebugRecognitionException(mse); + throw mse; + } + + DebugLocation(274, 55); + PushFollow(Follow._arith_expr_in_relational_expr1488); + arith_expr40=arith_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, arith_expr40.Tree); + + } + break; + + } + } finally { DebugExitSubRule(7); } + + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("relational_expr", 9); + LeaveRule("relational_expr", 9); + LeaveRule_relational_expr(); + } + DebugLocation(275, 1); + } finally { DebugExitRule(GrammarFileName, "relational_expr"); } + return retval; + + } + // $ANTLR end "relational_expr" + + partial void EnterRule_arith_expr(); + partial void LeaveRule_arith_expr(); + + // $ANTLR start "arith_expr" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:277:1: arith_expr : term_expr ( ( PLUS | MINUS ) ^ term_expr )* ; + [GrammarRule("arith_expr")] + private AstParserRuleReturnScope arith_expr() + { + EnterRule_arith_expr(); + EnterRule("arith_expr", 10); + TraceIn("arith_expr", 10); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken set42 = default(IToken); + AstParserRuleReturnScope term_expr41 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope term_expr43 = default(AstParserRuleReturnScope); + + object set42_tree = default(object); + try { DebugEnterRule(GrammarFileName, "arith_expr"); + DebugLocation(277, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:278:2: ( term_expr ( ( PLUS | MINUS ) ^ term_expr )* ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:278:4: term_expr ( ( PLUS | MINUS ) ^ term_expr )* + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(278, 4); + PushFollow(Follow._term_expr_in_arith_expr1502); + term_expr41=term_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, term_expr41.Tree); + DebugLocation(278, 14); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:278:14: ( ( PLUS | MINUS ) ^ term_expr )* + try { DebugEnterSubRule(8); + while (true) + { + int alt8=2; + try { DebugEnterDecision(8, false); + int LA8_0 = input.LA(1); + + if ((LA8_0==MINUS||LA8_0==PLUS)) + { + alt8 = 1; + } + + + } finally { DebugExitDecision(8); } + switch ( alt8 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:278:15: ( PLUS | MINUS ) ^ term_expr + { + DebugLocation(278, 29); + + set42=(IToken)input.LT(1); + set42=(IToken)input.LT(1); + if (input.LA(1)==MINUS||input.LA(1)==PLUS) + { + input.Consume(); + if (state.backtracking == 0) root_0 = (object)adaptor.BecomeRoot((object)adaptor.Create(set42), root_0); + state.errorRecovery=false;state.failed=false; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + MismatchedSetException mse = new MismatchedSetException(null,input); + DebugRecognitionException(mse); + throw mse; + } + + DebugLocation(278, 31); + PushFollow(Follow._term_expr_in_arith_expr1514); + term_expr43=term_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, term_expr43.Tree); + + } + break; + + default: + goto loop8; + } + } + + loop8: + ; + + } finally { DebugExitSubRule(8); } + + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("arith_expr", 10); + LeaveRule("arith_expr", 10); + LeaveRule_arith_expr(); + } + DebugLocation(279, 1); + } finally { DebugExitRule(GrammarFileName, "arith_expr"); } + return retval; + + } + // $ANTLR end "arith_expr" + + partial void EnterRule_term_expr(); + partial void LeaveRule_term_expr(); + + // $ANTLR start "term_expr" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:281:1: term_expr : atom ( ( MULT | DIV ) ^ atom )* ; + [GrammarRule("term_expr")] + private AstParserRuleReturnScope term_expr() + { + EnterRule_term_expr(); + EnterRule("term_expr", 11); + TraceIn("term_expr", 11); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken set45 = default(IToken); + AstParserRuleReturnScope atom44 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope atom46 = default(AstParserRuleReturnScope); + + object set45_tree = default(object); + try { DebugEnterRule(GrammarFileName, "term_expr"); + DebugLocation(281, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:282:2: ( atom ( ( MULT | DIV ) ^ atom )* ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:282:4: atom ( ( MULT | DIV ) ^ atom )* + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(282, 4); + PushFollow(Follow._atom_in_term_expr1527); + atom44=atom(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, atom44.Tree); + DebugLocation(282, 9); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:282:9: ( ( MULT | DIV ) ^ atom )* + try { DebugEnterSubRule(9); + while (true) + { + int alt9=2; + try { DebugEnterDecision(9, false); + int LA9_0 = input.LA(1); + + if ((LA9_0==DIV||LA9_0==MULT)) + { + alt9 = 1; + } + + + } finally { DebugExitDecision(9); } + switch ( alt9 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:282:10: ( MULT | DIV ) ^ atom + { + DebugLocation(282, 22); + + set45=(IToken)input.LT(1); + set45=(IToken)input.LT(1); + if (input.LA(1)==DIV||input.LA(1)==MULT) + { + input.Consume(); + if (state.backtracking == 0) root_0 = (object)adaptor.BecomeRoot((object)adaptor.Create(set45), root_0); + state.errorRecovery=false;state.failed=false; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + MismatchedSetException mse = new MismatchedSetException(null,input); + DebugRecognitionException(mse); + throw mse; + } + + DebugLocation(282, 24); + PushFollow(Follow._atom_in_term_expr1539); + atom46=atom(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, atom46.Tree); + + } + break; + + default: + goto loop9; + } + } + + loop9: + ; + + } finally { DebugExitSubRule(9); } + + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("term_expr", 11); + LeaveRule("term_expr", 11); + LeaveRule_term_expr(); + } + DebugLocation(283, 1); + } finally { DebugExitRule(GrammarFileName, "term_expr"); } + return retval; + + } + // $ANTLR end "term_expr" + + partial void EnterRule_field_inst_list(); + partial void LeaveRule_field_inst_list(); + + // $ANTLR start "field_inst_list" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:285:1: field_inst_list : record_field_inst ( COMMA record_field_inst )* -> ^( FIELDS_INST ( record_field_inst )+ ) ; + [GrammarRule("field_inst_list")] + private AstParserRuleReturnScope field_inst_list() + { + EnterRule_field_inst_list(); + EnterRule("field_inst_list", 12); + TraceIn("field_inst_list", 12); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken COMMA48 = default(IToken); + AstParserRuleReturnScope record_field_inst47 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope record_field_inst49 = default(AstParserRuleReturnScope); + + object COMMA48_tree = default(object); + RewriteRuleITokenStream stream_COMMA=new RewriteRuleITokenStream(adaptor,"token COMMA"); + RewriteRuleSubtreeStream stream_record_field_inst=new RewriteRuleSubtreeStream(adaptor,"rule record_field_inst"); + try { DebugEnterRule(GrammarFileName, "field_inst_list"); + DebugLocation(285, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:286:2: ( record_field_inst ( COMMA record_field_inst )* -> ^( FIELDS_INST ( record_field_inst )+ ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:286:5: record_field_inst ( COMMA record_field_inst )* + { + DebugLocation(286, 5); + PushFollow(Follow._record_field_inst_in_field_inst_list1553); + record_field_inst47=record_field_inst(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_record_field_inst.Add(record_field_inst47.Tree); + DebugLocation(286, 23); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:286:23: ( COMMA record_field_inst )* + try { DebugEnterSubRule(10); + while (true) + { + int alt10=2; + try { DebugEnterDecision(10, false); + int LA10_0 = input.LA(1); + + if ((LA10_0==COMMA)) + { + alt10 = 1; + } + + + } finally { DebugExitDecision(10); } + switch ( alt10 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:286:25: COMMA record_field_inst + { + DebugLocation(286, 25); + COMMA48=(IToken)Match(input,COMMA,Follow._COMMA_in_field_inst_list1557); if (state.failed) return retval; + if (state.backtracking == 0) stream_COMMA.Add(COMMA48); + + DebugLocation(286, 31); + PushFollow(Follow._record_field_inst_in_field_inst_list1559); + record_field_inst49=record_field_inst(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_record_field_inst.Add(record_field_inst49.Tree); + + } + break; + + default: + goto loop10; + } + } + + loop10: + ; + + } finally { DebugExitSubRule(10); } + + + + { + // AST REWRITE + // elements: record_field_inst + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 287:4: -> ^( FIELDS_INST ( record_field_inst )+ ) + { + DebugLocation(287, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:287:7: ^( FIELDS_INST ( record_field_inst )+ ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(287, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(FIELDS_INST, "FIELDS_INST"), root_1); + + DebugLocation(287, 21); + if (!(stream_record_field_inst.HasNext)) + { + throw new RewriteEarlyExitException(); + } + while ( stream_record_field_inst.HasNext ) + { + DebugLocation(287, 21); + adaptor.AddChild(root_1, stream_record_field_inst.NextTree()); + + } + stream_record_field_inst.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("field_inst_list", 12); + LeaveRule("field_inst_list", 12); + LeaveRule_field_inst_list(); + } + DebugLocation(288, 1); + } finally { DebugExitRule(GrammarFileName, "field_inst_list"); } + return retval; + + } + // $ANTLR end "field_inst_list" + + partial void EnterRule_record_field_inst(); + partial void LeaveRule_record_field_inst(); + + // $ANTLR start "record_field_inst" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:290:1: record_field_inst : ID EQ expr -> ^( FIELD_INST ID expr ) ; + [GrammarRule("record_field_inst")] + private AstParserRuleReturnScope record_field_inst() + { + EnterRule_record_field_inst(); + EnterRule("record_field_inst", 13); + TraceIn("record_field_inst", 13); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken ID50 = default(IToken); + IToken EQ51 = default(IToken); + AstParserRuleReturnScope expr52 = default(AstParserRuleReturnScope); + + object ID50_tree = default(object); + object EQ51_tree = default(object); + RewriteRuleITokenStream stream_ID=new RewriteRuleITokenStream(adaptor,"token ID"); + RewriteRuleITokenStream stream_EQ=new RewriteRuleITokenStream(adaptor,"token EQ"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "record_field_inst"); + DebugLocation(290, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:291:2: ( ID EQ expr -> ^( FIELD_INST ID expr ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:291:5: ID EQ expr + { + DebugLocation(291, 5); + ID50=(IToken)Match(input,ID,Follow._ID_in_record_field_inst1586); if (state.failed) return retval; + if (state.backtracking == 0) stream_ID.Add(ID50); + + DebugLocation(291, 8); + EQ51=(IToken)Match(input,EQ,Follow._EQ_in_record_field_inst1588); if (state.failed) return retval; + if (state.backtracking == 0) stream_EQ.Add(EQ51); + + DebugLocation(291, 11); + PushFollow(Follow._expr_in_record_field_inst1590); + expr52=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr52.Tree); + + + { + // AST REWRITE + // elements: ID, expr + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 292:4: -> ^( FIELD_INST ID expr ) + { + DebugLocation(292, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:292:7: ^( FIELD_INST ID expr ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(292, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(FIELD_INST, "FIELD_INST"), root_1); + + DebugLocation(292, 20); + adaptor.AddChild(root_1, stream_ID.NextNode()); + DebugLocation(292, 23); + adaptor.AddChild(root_1, stream_expr.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("record_field_inst", 13); + LeaveRule("record_field_inst", 13); + LeaveRule_record_field_inst(); + } + DebugLocation(293, 1); + } finally { DebugExitRule(GrammarFileName, "record_field_inst"); } + return retval; + + } + // $ANTLR end "record_field_inst" + + partial void EnterRule_decl(); + partial void LeaveRule_decl(); + + // $ANTLR start "decl" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:295:1: decl : ( ( type_decl )+ -> ^( TYPE_DECL_SEQ ( type_decl )+ ) | var_decl | ( fun_decl )+ -> ^( FUN_DECL_SEQ ( fun_decl )+ ) ); + [GrammarRule("decl")] + private AstParserRuleReturnScope decl() + { + EnterRule_decl(); + EnterRule("decl", 14); + TraceIn("decl", 14); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + AstParserRuleReturnScope type_decl53 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope var_decl54 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope fun_decl55 = default(AstParserRuleReturnScope); + + RewriteRuleSubtreeStream stream_type_decl=new RewriteRuleSubtreeStream(adaptor,"rule type_decl"); + RewriteRuleSubtreeStream stream_fun_decl=new RewriteRuleSubtreeStream(adaptor,"rule fun_decl"); + try { DebugEnterRule(GrammarFileName, "decl"); + DebugLocation(295, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:296:2: ( ( type_decl )+ -> ^( TYPE_DECL_SEQ ( type_decl )+ ) | var_decl | ( fun_decl )+ -> ^( FUN_DECL_SEQ ( fun_decl )+ ) ) + int alt13=3; + try { DebugEnterDecision(13, false); + switch (input.LA(1)) + { + case TYPEKEY: + { + alt13 = 1; + } + break; + case VARKEY: + { + alt13 = 2; + } + break; + case FUNCTIONKEY: + { + alt13 = 3; + } + break; + default: + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 13, 0, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + + } finally { DebugExitDecision(13); } + switch (alt13) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:296:4: ( type_decl )+ + { + DebugLocation(296, 4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:296:4: ( type_decl )+ + int cnt11=0; + try { DebugEnterSubRule(11); + while (true) + { + int alt11=2; + try { DebugEnterDecision(11, false); + int LA11_0 = input.LA(1); + + if ((LA11_0==TYPEKEY)) + { + alt11 = 1; + } + + + } finally { DebugExitDecision(11); } + switch (alt11) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:296:4: type_decl + { + DebugLocation(296, 4); + PushFollow(Follow._type_decl_in_decl1615); + type_decl53=type_decl(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_decl.Add(type_decl53.Tree); + + } + break; + + default: + if (cnt11 >= 1) + goto loop11; + + if (state.backtracking>0) {state.failed=true; return retval;} + EarlyExitException eee11 = new EarlyExitException( 11, input ); + DebugRecognitionException(eee11); + throw eee11; + } + cnt11++; + } + loop11: + ; + + } finally { DebugExitSubRule(11); } + + + + { + // AST REWRITE + // elements: type_decl + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 297:4: -> ^( TYPE_DECL_SEQ ( type_decl )+ ) + { + DebugLocation(297, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:297:7: ^( TYPE_DECL_SEQ ( type_decl )+ ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(297, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(TYPE_DECL_SEQ, "TYPE_DECL_SEQ"), root_1); + + DebugLocation(297, 23); + if (!(stream_type_decl.HasNext)) + { + throw new RewriteEarlyExitException(); + } + while ( stream_type_decl.HasNext ) + { + DebugLocation(297, 23); + adaptor.AddChild(root_1, stream_type_decl.NextTree()); + + } + stream_type_decl.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:298:4: var_decl + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(298, 4); + PushFollow(Follow._var_decl_in_decl1633); + var_decl54=var_decl(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, var_decl54.Tree); + + } + break; + case 3: + DebugEnterAlt(3); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:299:4: ( fun_decl )+ + { + DebugLocation(299, 4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:299:4: ( fun_decl )+ + int cnt12=0; + try { DebugEnterSubRule(12); + while (true) + { + int alt12=2; + try { DebugEnterDecision(12, false); + int LA12_0 = input.LA(1); + + if ((LA12_0==FUNCTIONKEY)) + { + alt12 = 1; + } + + + } finally { DebugExitDecision(12); } + switch (alt12) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:299:4: fun_decl + { + DebugLocation(299, 4); + PushFollow(Follow._fun_decl_in_decl1638); + fun_decl55=fun_decl(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_fun_decl.Add(fun_decl55.Tree); + + } + break; + + default: + if (cnt12 >= 1) + goto loop12; + + if (state.backtracking>0) {state.failed=true; return retval;} + EarlyExitException eee12 = new EarlyExitException( 12, input ); + DebugRecognitionException(eee12); + throw eee12; + } + cnt12++; + } + loop12: + ; + + } finally { DebugExitSubRule(12); } + + + + { + // AST REWRITE + // elements: fun_decl + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 300:4: -> ^( FUN_DECL_SEQ ( fun_decl )+ ) + { + DebugLocation(300, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:300:7: ^( FUN_DECL_SEQ ( fun_decl )+ ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(300, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(FUN_DECL_SEQ, "FUN_DECL_SEQ"), root_1); + + DebugLocation(300, 22); + if (!(stream_fun_decl.HasNext)) + { + throw new RewriteEarlyExitException(); + } + while ( stream_fun_decl.HasNext ) + { + DebugLocation(300, 22); + adaptor.AddChild(root_1, stream_fun_decl.NextTree()); + + } + stream_fun_decl.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + + } + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("decl", 14); + LeaveRule("decl", 14); + LeaveRule_decl(); + } + DebugLocation(301, 1); + } finally { DebugExitRule(GrammarFileName, "decl"); } + return retval; + + } + // $ANTLR end "decl" + + partial void EnterRule_type_decl(); + partial void LeaveRule_type_decl(); + + // $ANTLR start "type_decl" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:303:1: type_decl : TYPEKEY ID EQ type -> ^( TYPE_DECL ID type ) ; + [GrammarRule("type_decl")] + private AstParserRuleReturnScope type_decl() + { + EnterRule_type_decl(); + EnterRule("type_decl", 15); + TraceIn("type_decl", 15); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken TYPEKEY56 = default(IToken); + IToken ID57 = default(IToken); + IToken EQ58 = default(IToken); + AstParserRuleReturnScope type59 = default(AstParserRuleReturnScope); + + object TYPEKEY56_tree = default(object); + object ID57_tree = default(object); + object EQ58_tree = default(object); + RewriteRuleITokenStream stream_TYPEKEY=new RewriteRuleITokenStream(adaptor,"token TYPEKEY"); + RewriteRuleITokenStream stream_ID=new RewriteRuleITokenStream(adaptor,"token ID"); + RewriteRuleITokenStream stream_EQ=new RewriteRuleITokenStream(adaptor,"token EQ"); + RewriteRuleSubtreeStream stream_type=new RewriteRuleSubtreeStream(adaptor,"rule type"); + try { DebugEnterRule(GrammarFileName, "type_decl"); + DebugLocation(303, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:304:2: ( TYPEKEY ID EQ type -> ^( TYPE_DECL ID type ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:304:4: TYPEKEY ID EQ type + { + DebugLocation(304, 4); + TYPEKEY56=(IToken)Match(input,TYPEKEY,Follow._TYPEKEY_in_type_decl1662); if (state.failed) return retval; + if (state.backtracking == 0) stream_TYPEKEY.Add(TYPEKEY56); + + DebugLocation(304, 12); + ID57=(IToken)Match(input,ID,Follow._ID_in_type_decl1664); if (state.failed) return retval; + if (state.backtracking == 0) stream_ID.Add(ID57); + + DebugLocation(304, 15); + EQ58=(IToken)Match(input,EQ,Follow._EQ_in_type_decl1666); if (state.failed) return retval; + if (state.backtracking == 0) stream_EQ.Add(EQ58); + + DebugLocation(304, 18); + PushFollow(Follow._type_in_type_decl1668); + type59=type(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type.Add(type59.Tree); + + + { + // AST REWRITE + // elements: type, ID + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 305:4: -> ^( TYPE_DECL ID type ) + { + DebugLocation(305, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:305:7: ^( TYPE_DECL ID type ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(305, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(TYPE_DECL, "TYPE_DECL"), root_1); + + DebugLocation(305, 19); + adaptor.AddChild(root_1, stream_ID.NextNode()); + DebugLocation(305, 22); + adaptor.AddChild(root_1, stream_type.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("type_decl", 15); + LeaveRule("type_decl", 15); + LeaveRule_type_decl(); + } + DebugLocation(306, 1); + } finally { DebugExitRule(GrammarFileName, "type_decl"); } + return retval; + + } + // $ANTLR end "type_decl" + + partial void EnterRule_var_decl(); + partial void LeaveRule_var_decl(); + + // $ANTLR start "var_decl" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:308:1: 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 ) ); + [GrammarRule("var_decl")] + private AstParserRuleReturnScope var_decl() + { + EnterRule_var_decl(); + EnterRule("var_decl", 16); + TraceIn("var_decl", 16); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken VARKEY60 = default(IToken); + IToken COLON62 = default(IToken); + IToken ASSIGN64 = default(IToken); + IToken VARKEY66 = default(IToken); + IToken ASSIGN68 = default(IToken); + AstParserRuleReturnScope type_id61 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope type_id63 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope expr65 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope type_id67 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope expr69 = default(AstParserRuleReturnScope); + + object VARKEY60_tree = default(object); + object COLON62_tree = default(object); + object ASSIGN64_tree = default(object); + object VARKEY66_tree = default(object); + object ASSIGN68_tree = default(object); + RewriteRuleITokenStream stream_VARKEY=new RewriteRuleITokenStream(adaptor,"token VARKEY"); + RewriteRuleITokenStream stream_COLON=new RewriteRuleITokenStream(adaptor,"token COLON"); + RewriteRuleITokenStream stream_ASSIGN=new RewriteRuleITokenStream(adaptor,"token ASSIGN"); + RewriteRuleSubtreeStream stream_type_id=new RewriteRuleSubtreeStream(adaptor,"rule type_id"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "var_decl"); + DebugLocation(308, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:309:2: ( 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 ) ) + int alt14=2; + try { DebugEnterDecision(14, false); + int LA14_0 = input.LA(1); + + if ((LA14_0==VARKEY)) + { + int LA14_1 = input.LA(2); + + if ((LA14_1==ID||LA14_1==INTKEY||LA14_1==STRINGKEY)) + { + int LA14_2 = input.LA(3); + + if ((LA14_2==COLON)) + { + alt14 = 1; + } + else if ((LA14_2==ASSIGN)) + { + alt14 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 14, 2, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 14, 1, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 14, 0, input); + DebugRecognitionException(nvae); + throw nvae; + } + } finally { DebugExitDecision(14); } + switch (alt14) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:309:4: VARKEY type_id COLON type_id ASSIGN expr + { + DebugLocation(309, 4); + VARKEY60=(IToken)Match(input,VARKEY,Follow._VARKEY_in_var_decl1692); if (state.failed) return retval; + if (state.backtracking == 0) stream_VARKEY.Add(VARKEY60); + + DebugLocation(309, 11); + PushFollow(Follow._type_id_in_var_decl1694); + type_id61=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id61.Tree); + DebugLocation(309, 19); + COLON62=(IToken)Match(input,COLON,Follow._COLON_in_var_decl1696); if (state.failed) return retval; + if (state.backtracking == 0) stream_COLON.Add(COLON62); + + DebugLocation(309, 25); + PushFollow(Follow._type_id_in_var_decl1698); + type_id63=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id63.Tree); + DebugLocation(309, 33); + ASSIGN64=(IToken)Match(input,ASSIGN,Follow._ASSIGN_in_var_decl1700); if (state.failed) return retval; + if (state.backtracking == 0) stream_ASSIGN.Add(ASSIGN64); + + DebugLocation(309, 40); + PushFollow(Follow._expr_in_var_decl1702); + expr65=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr65.Tree); + + + { + // AST REWRITE + // elements: type_id, expr, type_id + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 310:4: -> ^( VAR_DECL type_id type_id expr ) + { + DebugLocation(310, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:310:7: ^( VAR_DECL type_id type_id expr ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(310, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(VAR_DECL, "VAR_DECL"), root_1); + + DebugLocation(310, 18); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + DebugLocation(310, 26); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + DebugLocation(310, 34); + adaptor.AddChild(root_1, stream_expr.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:311:4: VARKEY type_id ASSIGN expr + { + DebugLocation(311, 4); + VARKEY66=(IToken)Match(input,VARKEY,Follow._VARKEY_in_var_decl1723); if (state.failed) return retval; + if (state.backtracking == 0) stream_VARKEY.Add(VARKEY66); + + DebugLocation(311, 11); + PushFollow(Follow._type_id_in_var_decl1725); + type_id67=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id67.Tree); + DebugLocation(311, 19); + ASSIGN68=(IToken)Match(input,ASSIGN,Follow._ASSIGN_in_var_decl1727); if (state.failed) return retval; + if (state.backtracking == 0) stream_ASSIGN.Add(ASSIGN68); + + DebugLocation(311, 26); + PushFollow(Follow._expr_in_var_decl1729); + expr69=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr69.Tree); + + + { + // AST REWRITE + // elements: expr, type_id + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 312:4: -> ^( VAR_DECL type_id FILL_IN_TYPE expr ) + { + DebugLocation(312, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:312:7: ^( VAR_DECL type_id FILL_IN_TYPE expr ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(312, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(VAR_DECL, "VAR_DECL"), root_1); + + DebugLocation(312, 18); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + DebugLocation(312, 26); + adaptor.AddChild(root_1, (object)adaptor.Create(FILL_IN_TYPE, "FILL_IN_TYPE")); + DebugLocation(312, 39); + adaptor.AddChild(root_1, stream_expr.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + + } + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("var_decl", 16); + LeaveRule("var_decl", 16); + LeaveRule_var_decl(); + } + DebugLocation(313, 1); + } finally { DebugExitRule(GrammarFileName, "var_decl"); } + return retval; + + } + // $ANTLR end "var_decl" + + partial void EnterRule_fun_decl(); + partial void LeaveRule_fun_decl(); + + // $ANTLR start "fun_decl" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:315:1: 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 ) ; + [GrammarRule("fun_decl")] + private AstParserRuleReturnScope fun_decl() + { + EnterRule_fun_decl(); + EnterRule("fun_decl", 17); + TraceIn("fun_decl", 17); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken FUNCTIONKEY70 = default(IToken); + IToken LPAREN72 = default(IToken); + IToken RPAREN74 = default(IToken); + IToken COLON75 = default(IToken); + IToken EQ77 = default(IToken); + AstParserRuleReturnScope type_id71 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope type_fields73 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope type_id76 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope expr78 = default(AstParserRuleReturnScope); + + object FUNCTIONKEY70_tree = default(object); + object LPAREN72_tree = default(object); + object RPAREN74_tree = default(object); + object COLON75_tree = default(object); + object EQ77_tree = default(object); + RewriteRuleITokenStream stream_FUNCTIONKEY=new RewriteRuleITokenStream(adaptor,"token FUNCTIONKEY"); + RewriteRuleITokenStream stream_LPAREN=new RewriteRuleITokenStream(adaptor,"token LPAREN"); + RewriteRuleITokenStream stream_COLON=new RewriteRuleITokenStream(adaptor,"token COLON"); + RewriteRuleITokenStream stream_RPAREN=new RewriteRuleITokenStream(adaptor,"token RPAREN"); + RewriteRuleITokenStream stream_EQ=new RewriteRuleITokenStream(adaptor,"token EQ"); + RewriteRuleSubtreeStream stream_type_id=new RewriteRuleSubtreeStream(adaptor,"rule type_id"); + RewriteRuleSubtreeStream stream_type_fields=new RewriteRuleSubtreeStream(adaptor,"rule type_fields"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "fun_decl"); + DebugLocation(315, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:316:2: ( 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 ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:316:4: FUNCTIONKEY type_id LPAREN ( type_fields )? RPAREN ( COLON type_id )? EQ expr + { + DebugLocation(316, 4); + FUNCTIONKEY70=(IToken)Match(input,FUNCTIONKEY,Follow._FUNCTIONKEY_in_fun_decl1755); if (state.failed) return retval; + if (state.backtracking == 0) stream_FUNCTIONKEY.Add(FUNCTIONKEY70); + + DebugLocation(316, 16); + PushFollow(Follow._type_id_in_fun_decl1757); + type_id71=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id71.Tree); + DebugLocation(316, 24); + LPAREN72=(IToken)Match(input,LPAREN,Follow._LPAREN_in_fun_decl1759); if (state.failed) return retval; + if (state.backtracking == 0) stream_LPAREN.Add(LPAREN72); + + DebugLocation(316, 31); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:316:31: ( type_fields )? + int alt15=2; + try { DebugEnterSubRule(15); + try { DebugEnterDecision(15, false); + int LA15_0 = input.LA(1); + + if ((LA15_0==ID||LA15_0==INTKEY||LA15_0==STRINGKEY)) + { + alt15 = 1; + } + } finally { DebugExitDecision(15); } + switch (alt15) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:316:31: type_fields + { + DebugLocation(316, 31); + PushFollow(Follow._type_fields_in_fun_decl1761); + type_fields73=type_fields(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_fields.Add(type_fields73.Tree); + + } + break; + + } + } finally { DebugExitSubRule(15); } + + DebugLocation(316, 44); + RPAREN74=(IToken)Match(input,RPAREN,Follow._RPAREN_in_fun_decl1764); if (state.failed) return retval; + if (state.backtracking == 0) stream_RPAREN.Add(RPAREN74); + + DebugLocation(316, 51); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:316:51: ( COLON type_id )? + int alt16=2; + try { DebugEnterSubRule(16); + try { DebugEnterDecision(16, false); + int LA16_0 = input.LA(1); + + if ((LA16_0==COLON)) + { + alt16 = 1; + } + } finally { DebugExitDecision(16); } + switch (alt16) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:316:52: COLON type_id + { + DebugLocation(316, 52); + COLON75=(IToken)Match(input,COLON,Follow._COLON_in_fun_decl1767); if (state.failed) return retval; + if (state.backtracking == 0) stream_COLON.Add(COLON75); + + DebugLocation(316, 58); + PushFollow(Follow._type_id_in_fun_decl1769); + type_id76=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id76.Tree); + + } + break; + + } + } finally { DebugExitSubRule(16); } + + DebugLocation(316, 68); + EQ77=(IToken)Match(input,EQ,Follow._EQ_in_fun_decl1773); if (state.failed) return retval; + if (state.backtracking == 0) stream_EQ.Add(EQ77); + + DebugLocation(316, 71); + PushFollow(Follow._expr_in_fun_decl1775); + expr78=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr78.Tree); + + + { + // AST REWRITE + // elements: type_id, expr, type_id, type_fields + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 317:4: -> ^( FUN_DECL type_id ^( PARAM_DECL ( type_fields )? ) ^( FUN_TYPE_WRAPPER ( type_id )? ) expr ) + { + DebugLocation(317, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:317:7: ^( FUN_DECL type_id ^( PARAM_DECL ( type_fields )? ) ^( FUN_TYPE_WRAPPER ( type_id )? ) expr ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(317, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(FUN_DECL, "FUN_DECL"), root_1); + + DebugLocation(317, 18); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + DebugLocation(317, 26); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:317:26: ^( PARAM_DECL ( type_fields )? ) + { + object root_2 = (object)adaptor.Nil(); + DebugLocation(317, 28); + root_2 = (object)adaptor.BecomeRoot((object)adaptor.Create(PARAM_DECL, "PARAM_DECL"), root_2); + + DebugLocation(317, 39); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:317:39: ( type_fields )? + if (stream_type_fields.HasNext) + { + DebugLocation(317, 39); + adaptor.AddChild(root_2, stream_type_fields.NextTree()); + + } + stream_type_fields.Reset(); + + adaptor.AddChild(root_1, root_2); + } + DebugLocation(317, 53); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:317:53: ^( FUN_TYPE_WRAPPER ( type_id )? ) + { + object root_2 = (object)adaptor.Nil(); + DebugLocation(317, 55); + root_2 = (object)adaptor.BecomeRoot((object)adaptor.Create(FUN_TYPE_WRAPPER, "FUN_TYPE_WRAPPER"), root_2); + + DebugLocation(317, 72); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:317:72: ( type_id )? + if (stream_type_id.HasNext) + { + DebugLocation(317, 72); + adaptor.AddChild(root_2, stream_type_id.NextTree()); + + } + stream_type_id.Reset(); + + adaptor.AddChild(root_1, root_2); + } + DebugLocation(317, 82); + adaptor.AddChild(root_1, stream_expr.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("fun_decl", 17); + LeaveRule("fun_decl", 17); + LeaveRule_fun_decl(); + } + DebugLocation(318, 1); + } finally { DebugExitRule(GrammarFileName, "fun_decl"); } + return retval; + + } + // $ANTLR end "fun_decl" + + partial void EnterRule_type_id(); + partial void LeaveRule_type_id(); + + // $ANTLR start "type_id" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:320:1: type_id : ( STRINGKEY | INTKEY | ID ); + [GrammarRule("type_id")] + private AstParserRuleReturnScope type_id() + { + EnterRule_type_id(); + EnterRule("type_id", 18); + TraceIn("type_id", 18); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken set79 = default(IToken); + + object set79_tree = default(object); + try { DebugEnterRule(GrammarFileName, "type_id"); + DebugLocation(320, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:321:2: ( STRINGKEY | INTKEY | ID ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g: + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(321, 2); + + set79=(IToken)input.LT(1); + if (input.LA(1)==ID||input.LA(1)==INTKEY||input.LA(1)==STRINGKEY) + { + input.Consume(); + if (state.backtracking == 0) adaptor.AddChild(root_0, (object)adaptor.Create(set79)); + state.errorRecovery=false;state.failed=false; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + MismatchedSetException mse = new MismatchedSetException(null,input); + DebugRecognitionException(mse); + throw mse; + } + + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("type_id", 18); + LeaveRule("type_id", 18); + LeaveRule_type_id(); + } + DebugLocation(324, 1); + } finally { DebugExitRule(GrammarFileName, "type_id"); } + return retval; + + } + // $ANTLR end "type_id" + + partial void EnterRule_type(); + partial void LeaveRule_type(); + + // $ANTLR start "type" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:326:1: type : ( type_id -> ^( ALIAS_DECL type_id ) | array_decl | record_decl ); + [GrammarRule("type")] + private AstParserRuleReturnScope type() + { + EnterRule_type(); + EnterRule("type", 19); + TraceIn("type", 19); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + AstParserRuleReturnScope type_id80 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope array_decl81 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope record_decl82 = default(AstParserRuleReturnScope); + + RewriteRuleSubtreeStream stream_type_id=new RewriteRuleSubtreeStream(adaptor,"rule type_id"); + try { DebugEnterRule(GrammarFileName, "type"); + DebugLocation(326, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:327:2: ( type_id -> ^( ALIAS_DECL type_id ) | array_decl | record_decl ) + int alt17=3; + try { DebugEnterDecision(17, false); + switch (input.LA(1)) + { + case ID: + case INTKEY: + case STRINGKEY: + { + alt17 = 1; + } + break; + case ARRAYKEY: + { + alt17 = 2; + } + break; + case LKEY: + { + alt17 = 3; + } + break; + default: + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 17, 0, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + + } finally { DebugExitDecision(17); } + switch (alt17) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:327:4: type_id + { + DebugLocation(327, 4); + PushFollow(Follow._type_id_in_type1834); + type_id80=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id80.Tree); + + + { + // AST REWRITE + // elements: type_id + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 328:13: -> ^( ALIAS_DECL type_id ) + { + DebugLocation(328, 16); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:328:16: ^( ALIAS_DECL type_id ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(328, 18); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(ALIAS_DECL, "ALIAS_DECL"), root_1); + + DebugLocation(328, 29); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:329:4: array_decl + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(329, 4); + PushFollow(Follow._array_decl_in_type1859); + array_decl81=array_decl(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, array_decl81.Tree); + + } + break; + case 3: + DebugEnterAlt(3); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:330:4: record_decl + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(330, 4); + PushFollow(Follow._record_decl_in_type1865); + record_decl82=record_decl(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, record_decl82.Tree); + + } + break; + + } + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("type", 19); + LeaveRule("type", 19); + LeaveRule_type(); + } + DebugLocation(331, 1); + } finally { DebugExitRule(GrammarFileName, "type"); } + return retval; + + } + // $ANTLR end "type" + + partial void EnterRule_record_decl(); + partial void LeaveRule_record_decl(); + + // $ANTLR start "record_decl" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:333:1: record_decl : LKEY ( type_fields )? RKEY -> ^( RECORD_DECL ( type_fields )? ) ; + [GrammarRule("record_decl")] + private AstParserRuleReturnScope record_decl() + { + EnterRule_record_decl(); + EnterRule("record_decl", 20); + TraceIn("record_decl", 20); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken LKEY83 = default(IToken); + IToken RKEY85 = default(IToken); + AstParserRuleReturnScope type_fields84 = default(AstParserRuleReturnScope); + + object LKEY83_tree = default(object); + object RKEY85_tree = default(object); + RewriteRuleITokenStream stream_LKEY=new RewriteRuleITokenStream(adaptor,"token LKEY"); + RewriteRuleITokenStream stream_RKEY=new RewriteRuleITokenStream(adaptor,"token RKEY"); + RewriteRuleSubtreeStream stream_type_fields=new RewriteRuleSubtreeStream(adaptor,"rule type_fields"); + try { DebugEnterRule(GrammarFileName, "record_decl"); + DebugLocation(333, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:334:2: ( LKEY ( type_fields )? RKEY -> ^( RECORD_DECL ( type_fields )? ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:334:4: LKEY ( type_fields )? RKEY + { + DebugLocation(334, 4); + LKEY83=(IToken)Match(input,LKEY,Follow._LKEY_in_record_decl1876); if (state.failed) return retval; + if (state.backtracking == 0) stream_LKEY.Add(LKEY83); + + DebugLocation(334, 9); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:334:9: ( type_fields )? + int alt18=2; + try { DebugEnterSubRule(18); + try { DebugEnterDecision(18, false); + int LA18_0 = input.LA(1); + + if ((LA18_0==ID||LA18_0==INTKEY||LA18_0==STRINGKEY)) + { + alt18 = 1; + } + } finally { DebugExitDecision(18); } + switch (alt18) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:334:9: type_fields + { + DebugLocation(334, 9); + PushFollow(Follow._type_fields_in_record_decl1878); + type_fields84=type_fields(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_fields.Add(type_fields84.Tree); + + } + break; + + } + } finally { DebugExitSubRule(18); } + + DebugLocation(334, 22); + RKEY85=(IToken)Match(input,RKEY,Follow._RKEY_in_record_decl1881); if (state.failed) return retval; + if (state.backtracking == 0) stream_RKEY.Add(RKEY85); + + + + { + // AST REWRITE + // elements: type_fields + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 335:4: -> ^( RECORD_DECL ( type_fields )? ) + { + DebugLocation(335, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:335:7: ^( RECORD_DECL ( type_fields )? ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(335, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(RECORD_DECL, "RECORD_DECL"), root_1); + + DebugLocation(335, 21); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:335:21: ( type_fields )? + if (stream_type_fields.HasNext) + { + DebugLocation(335, 21); + adaptor.AddChild(root_1, stream_type_fields.NextTree()); + + } + stream_type_fields.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("record_decl", 20); + LeaveRule("record_decl", 20); + LeaveRule_record_decl(); + } + DebugLocation(336, 1); + } finally { DebugExitRule(GrammarFileName, "record_decl"); } + return retval; + + } + // $ANTLR end "record_decl" + + partial void EnterRule_array_decl(); + partial void LeaveRule_array_decl(); + + // $ANTLR start "array_decl" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:338:1: array_decl : ARRAYKEY OFKEY type_id -> ^( ARRAY_DECL type_id ) ; + [GrammarRule("array_decl")] + private AstParserRuleReturnScope array_decl() + { + EnterRule_array_decl(); + EnterRule("array_decl", 21); + TraceIn("array_decl", 21); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken ARRAYKEY86 = default(IToken); + IToken OFKEY87 = default(IToken); + AstParserRuleReturnScope type_id88 = default(AstParserRuleReturnScope); + + object ARRAYKEY86_tree = default(object); + object OFKEY87_tree = default(object); + RewriteRuleITokenStream stream_ARRAYKEY=new RewriteRuleITokenStream(adaptor,"token ARRAYKEY"); + RewriteRuleITokenStream stream_OFKEY=new RewriteRuleITokenStream(adaptor,"token OFKEY"); + RewriteRuleSubtreeStream stream_type_id=new RewriteRuleSubtreeStream(adaptor,"rule type_id"); + try { DebugEnterRule(GrammarFileName, "array_decl"); + DebugLocation(338, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:339:2: ( ARRAYKEY OFKEY type_id -> ^( ARRAY_DECL type_id ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:339:4: ARRAYKEY OFKEY type_id + { + DebugLocation(339, 4); + ARRAYKEY86=(IToken)Match(input,ARRAYKEY,Follow._ARRAYKEY_in_array_decl1904); if (state.failed) return retval; + if (state.backtracking == 0) stream_ARRAYKEY.Add(ARRAYKEY86); + + DebugLocation(339, 13); + OFKEY87=(IToken)Match(input,OFKEY,Follow._OFKEY_in_array_decl1906); if (state.failed) return retval; + if (state.backtracking == 0) stream_OFKEY.Add(OFKEY87); + + DebugLocation(339, 19); + PushFollow(Follow._type_id_in_array_decl1908); + type_id88=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id88.Tree); + + + { + // AST REWRITE + // elements: type_id + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 340:4: -> ^( ARRAY_DECL type_id ) + { + DebugLocation(340, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:340:7: ^( ARRAY_DECL type_id ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(340, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(ARRAY_DECL, "ARRAY_DECL"), root_1); + + DebugLocation(340, 20); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("array_decl", 21); + LeaveRule("array_decl", 21); + LeaveRule_array_decl(); + } + DebugLocation(341, 1); + } finally { DebugExitRule(GrammarFileName, "array_decl"); } + return retval; + + } + // $ANTLR end "array_decl" + + partial void EnterRule_type_fields(); + partial void LeaveRule_type_fields(); + + // $ANTLR start "type_fields" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:343:1: type_fields : type_field ( COMMA type_field )* -> ( type_field )+ ; + [GrammarRule("type_fields")] + private AstParserRuleReturnScope type_fields() + { + EnterRule_type_fields(); + EnterRule("type_fields", 22); + TraceIn("type_fields", 22); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken COMMA90 = default(IToken); + AstParserRuleReturnScope type_field89 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope type_field91 = default(AstParserRuleReturnScope); + + object COMMA90_tree = default(object); + RewriteRuleITokenStream stream_COMMA=new RewriteRuleITokenStream(adaptor,"token COMMA"); + RewriteRuleSubtreeStream stream_type_field=new RewriteRuleSubtreeStream(adaptor,"rule type_field"); + try { DebugEnterRule(GrammarFileName, "type_fields"); + DebugLocation(343, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:344:2: ( type_field ( COMMA type_field )* -> ( type_field )+ ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:344:4: type_field ( COMMA type_field )* + { + DebugLocation(344, 4); + PushFollow(Follow._type_field_in_type_fields1931); + type_field89=type_field(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_field.Add(type_field89.Tree); + DebugLocation(344, 15); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:344:15: ( COMMA type_field )* + try { DebugEnterSubRule(19); + while (true) + { + int alt19=2; + try { DebugEnterDecision(19, false); + int LA19_0 = input.LA(1); + + if ((LA19_0==COMMA)) + { + alt19 = 1; + } + + + } finally { DebugExitDecision(19); } + switch ( alt19 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:344:16: COMMA type_field + { + DebugLocation(344, 16); + COMMA90=(IToken)Match(input,COMMA,Follow._COMMA_in_type_fields1934); if (state.failed) return retval; + if (state.backtracking == 0) stream_COMMA.Add(COMMA90); + + DebugLocation(344, 22); + PushFollow(Follow._type_field_in_type_fields1936); + type_field91=type_field(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_field.Add(type_field91.Tree); + + } + break; + + default: + goto loop19; + } + } + + loop19: + ; + + } finally { DebugExitSubRule(19); } + + + + { + // AST REWRITE + // elements: type_field + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 345:4: -> ( type_field )+ + { + DebugLocation(345, 7); + if (!(stream_type_field.HasNext)) + { + throw new RewriteEarlyExitException(); + } + while ( stream_type_field.HasNext ) + { + DebugLocation(345, 7); + adaptor.AddChild(root_0, stream_type_field.NextTree()); + + } + stream_type_field.Reset(); + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("type_fields", 22); + LeaveRule("type_fields", 22); + LeaveRule_type_fields(); + } + DebugLocation(346, 1); + } finally { DebugExitRule(GrammarFileName, "type_fields"); } + return retval; + + } + // $ANTLR end "type_fields" + + partial void EnterRule_type_field(); + partial void LeaveRule_type_field(); + + // $ANTLR start "type_field" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:348:1: type_field : type_id COLON type_id -> ^( TYPE_FIELD type_id type_id ) ; + [GrammarRule("type_field")] + private AstParserRuleReturnScope type_field() + { + EnterRule_type_field(); + EnterRule("type_field", 23); + TraceIn("type_field", 23); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken COLON93 = default(IToken); + AstParserRuleReturnScope type_id92 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope type_id94 = default(AstParserRuleReturnScope); + + object COLON93_tree = default(object); + RewriteRuleITokenStream stream_COLON=new RewriteRuleITokenStream(adaptor,"token COLON"); + RewriteRuleSubtreeStream stream_type_id=new RewriteRuleSubtreeStream(adaptor,"rule type_id"); + try { DebugEnterRule(GrammarFileName, "type_field"); + DebugLocation(348, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:349:2: ( type_id COLON type_id -> ^( TYPE_FIELD type_id type_id ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:349:4: type_id COLON type_id + { + DebugLocation(349, 4); + PushFollow(Follow._type_id_in_type_field1957); + type_id92=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id92.Tree); + DebugLocation(349, 12); + COLON93=(IToken)Match(input,COLON,Follow._COLON_in_type_field1959); if (state.failed) return retval; + if (state.backtracking == 0) stream_COLON.Add(COLON93); + + DebugLocation(349, 18); + PushFollow(Follow._type_id_in_type_field1961); + type_id94=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id94.Tree); + + + { + // AST REWRITE + // elements: type_id, type_id + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 350:4: -> ^( TYPE_FIELD type_id type_id ) + { + DebugLocation(350, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:350:7: ^( TYPE_FIELD type_id type_id ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(350, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(TYPE_FIELD, "TYPE_FIELD"), root_1); + + DebugLocation(350, 20); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + DebugLocation(350, 28); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("type_field", 23); + LeaveRule("type_field", 23); + LeaveRule_type_field(); + } + DebugLocation(351, 1); + } finally { DebugExitRule(GrammarFileName, "type_field"); } + return retval; + + } + // $ANTLR end "type_field" + + partial void EnterRule_atom(); + partial void LeaveRule_atom(); + + // $ANTLR start "atom" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:353:1: atom : ( MINUS atom -> ^( NEG atom ) | constant_value | lvalue | funcall | if_then_expr | for_expr | let_expr | LPAREN expr_seq RPAREN -> expr_seq ); + [GrammarRule("atom")] + private AstParserRuleReturnScope atom() + { + EnterRule_atom(); + EnterRule("atom", 24); + TraceIn("atom", 24); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken MINUS95 = default(IToken); + IToken LPAREN103 = default(IToken); + IToken RPAREN105 = default(IToken); + AstParserRuleReturnScope atom96 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope constant_value97 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope lvalue98 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope funcall99 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope if_then_expr100 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope for_expr101 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope let_expr102 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope expr_seq104 = default(AstParserRuleReturnScope); + + object MINUS95_tree = default(object); + object LPAREN103_tree = default(object); + object RPAREN105_tree = default(object); + RewriteRuleITokenStream stream_LPAREN=new RewriteRuleITokenStream(adaptor,"token LPAREN"); + RewriteRuleITokenStream stream_RPAREN=new RewriteRuleITokenStream(adaptor,"token RPAREN"); + RewriteRuleITokenStream stream_MINUS=new RewriteRuleITokenStream(adaptor,"token MINUS"); + RewriteRuleSubtreeStream stream_expr_seq=new RewriteRuleSubtreeStream(adaptor,"rule expr_seq"); + RewriteRuleSubtreeStream stream_atom=new RewriteRuleSubtreeStream(adaptor,"rule atom"); + try { DebugEnterRule(GrammarFileName, "atom"); + DebugLocation(353, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:354:2: ( MINUS atom -> ^( NEG atom ) | constant_value | lvalue | funcall | if_then_expr | for_expr | let_expr | LPAREN expr_seq RPAREN -> expr_seq ) + int alt20=8; + try { DebugEnterDecision(20, false); + switch (input.LA(1)) + { + case MINUS: + { + alt20 = 1; + } + break; + case INT: + case NILKEY: + case STRING: + { + alt20 = 2; + } + break; + case ID: + case INTKEY: + case STRINGKEY: + { + int LA20_3 = input.LA(2); + + if ((LA20_3==EOF||LA20_3==AND||LA20_3==COMMA||(LA20_3>=DIV && LA20_3<=ENDKEY)||LA20_3==EQ||LA20_3==FUNCTIONKEY||(LA20_3>=GT && LA20_3<=GTEQ)||LA20_3==INKEY||LA20_3==LBRACKET||(LA20_3>=LT && LA20_3<=MULT)||LA20_3==NOTEQ||LA20_3==OR||LA20_3==PLUS||LA20_3==RBRACKET||(LA20_3>=RKEY && LA20_3<=SEMI)||(LA20_3>=THENKEY && LA20_3<=TOKEY)||LA20_3==TYPEKEY||LA20_3==VARKEY)) + { + alt20 = 3; + } + else if ((LA20_3==LPAREN)) + { + alt20 = 4; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 20, 3, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + break; + case IFKEY: + { + alt20 = 5; + } + break; + case FORKEY: + { + alt20 = 6; + } + break; + case LETKEY: + { + alt20 = 7; + } + break; + case LPAREN: + { + alt20 = 8; + } + break; + default: + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 20, 0, input); + DebugRecognitionException(nvae); + throw nvae; + } + } + + } finally { DebugExitDecision(20); } + switch (alt20) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:354:4: MINUS atom + { + DebugLocation(354, 4); + MINUS95=(IToken)Match(input,MINUS,Follow._MINUS_in_atom1986); if (state.failed) return retval; + if (state.backtracking == 0) stream_MINUS.Add(MINUS95); + + DebugLocation(354, 10); + PushFollow(Follow._atom_in_atom1988); + atom96=atom(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_atom.Add(atom96.Tree); + + + { + // AST REWRITE + // elements: atom + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 355:13: -> ^( NEG atom ) + { + DebugLocation(355, 16); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:355:16: ^( NEG atom ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(355, 18); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(NEG, "NEG"), root_1); + + DebugLocation(355, 22); + adaptor.AddChild(root_1, stream_atom.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:356:4: constant_value + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(356, 4); + PushFollow(Follow._constant_value_in_atom2013); + constant_value97=constant_value(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, constant_value97.Tree); + + } + break; + case 3: + DebugEnterAlt(3); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:357:4: lvalue + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(357, 4); + PushFollow(Follow._lvalue_in_atom2018); + lvalue98=lvalue(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, lvalue98.Tree); + + } + break; + case 4: + DebugEnterAlt(4); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:358:4: funcall + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(358, 4); + PushFollow(Follow._funcall_in_atom2023); + funcall99=funcall(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, funcall99.Tree); + + } + break; + case 5: + DebugEnterAlt(5); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:359:4: if_then_expr + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(359, 4); + PushFollow(Follow._if_then_expr_in_atom2028); + if_then_expr100=if_then_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, if_then_expr100.Tree); + + } + break; + case 6: + DebugEnterAlt(6); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:360:4: for_expr + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(360, 4); + PushFollow(Follow._for_expr_in_atom2033); + for_expr101=for_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, for_expr101.Tree); + + } + break; + case 7: + DebugEnterAlt(7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:361:4: let_expr + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(361, 4); + PushFollow(Follow._let_expr_in_atom2038); + let_expr102=let_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) adaptor.AddChild(root_0, let_expr102.Tree); + + } + break; + case 8: + DebugEnterAlt(8); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:362:4: LPAREN expr_seq RPAREN + { + DebugLocation(362, 4); + LPAREN103=(IToken)Match(input,LPAREN,Follow._LPAREN_in_atom2043); if (state.failed) return retval; + if (state.backtracking == 0) stream_LPAREN.Add(LPAREN103); + + DebugLocation(362, 11); + PushFollow(Follow._expr_seq_in_atom2045); + expr_seq104=expr_seq(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr_seq.Add(expr_seq104.Tree); + DebugLocation(362, 20); + RPAREN105=(IToken)Match(input,RPAREN,Follow._RPAREN_in_atom2047); if (state.failed) return retval; + if (state.backtracking == 0) stream_RPAREN.Add(RPAREN105); + + + + { + // AST REWRITE + // elements: expr_seq + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 363:4: -> expr_seq + { + DebugLocation(363, 7); + adaptor.AddChild(root_0, stream_expr_seq.NextTree()); + + } + + retval.Tree = root_0; + } + } + + } + break; + + } + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("atom", 24); + LeaveRule("atom", 24); + LeaveRule_atom(); + } + DebugLocation(364, 1); + } finally { DebugExitRule(GrammarFileName, "atom"); } + return retval; + + } + // $ANTLR end "atom" + + partial void EnterRule_constant_value(); + partial void LeaveRule_constant_value(); + + // $ANTLR start "constant_value" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:366:1: constant_value : ( STRING | INT | NILKEY ); + [GrammarRule("constant_value")] + private AstParserRuleReturnScope constant_value() + { + EnterRule_constant_value(); + EnterRule("constant_value", 25); + TraceIn("constant_value", 25); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken set106 = default(IToken); + + object set106_tree = default(object); + try { DebugEnterRule(GrammarFileName, "constant_value"); + DebugLocation(366, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:367:2: ( STRING | INT | NILKEY ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g: + { + root_0 = (object)adaptor.Nil(); + + DebugLocation(367, 2); + + set106=(IToken)input.LT(1); + if (input.LA(1)==INT||input.LA(1)==NILKEY||input.LA(1)==STRING) + { + input.Consume(); + if (state.backtracking == 0) adaptor.AddChild(root_0, (object)adaptor.Create(set106)); + state.errorRecovery=false;state.failed=false; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + MismatchedSetException mse = new MismatchedSetException(null,input); + DebugRecognitionException(mse); + throw mse; + } + + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("constant_value", 25); + LeaveRule("constant_value", 25); + LeaveRule_constant_value(); + } + DebugLocation(370, 1); + } finally { DebugExitRule(GrammarFileName, "constant_value"); } + return retval; + + } + // $ANTLR end "constant_value" + + partial void EnterRule_if_then_expr(); + partial void LeaveRule_if_then_expr(); + + // $ANTLR start "if_then_expr" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:372:1: if_then_expr : IFKEY conditional= disjunction_expr THENKEY then_expr= expr ( ELSEKEY else_expr= expr )? -> ^( IF $conditional $then_expr ( $else_expr)? ) ; + [GrammarRule("if_then_expr")] + private AstParserRuleReturnScope if_then_expr() + { + EnterRule_if_then_expr(); + EnterRule("if_then_expr", 26); + TraceIn("if_then_expr", 26); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken IFKEY107 = default(IToken); + IToken THENKEY108 = default(IToken); + IToken ELSEKEY109 = default(IToken); + AstParserRuleReturnScope conditional = default(AstParserRuleReturnScope); + AstParserRuleReturnScope then_expr = default(AstParserRuleReturnScope); + AstParserRuleReturnScope else_expr = default(AstParserRuleReturnScope); + + object IFKEY107_tree = default(object); + object THENKEY108_tree = default(object); + object ELSEKEY109_tree = default(object); + RewriteRuleITokenStream stream_ELSEKEY=new RewriteRuleITokenStream(adaptor,"token ELSEKEY"); + RewriteRuleITokenStream stream_IFKEY=new RewriteRuleITokenStream(adaptor,"token IFKEY"); + RewriteRuleITokenStream stream_THENKEY=new RewriteRuleITokenStream(adaptor,"token THENKEY"); + RewriteRuleSubtreeStream stream_disjunction_expr=new RewriteRuleSubtreeStream(adaptor,"rule disjunction_expr"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "if_then_expr"); + DebugLocation(372, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:373:2: ( IFKEY conditional= disjunction_expr THENKEY then_expr= expr ( ELSEKEY else_expr= expr )? -> ^( IF $conditional $then_expr ( $else_expr)? ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:373:4: IFKEY conditional= disjunction_expr THENKEY then_expr= expr ( ELSEKEY else_expr= expr )? + { + DebugLocation(373, 4); + IFKEY107=(IToken)Match(input,IFKEY,Follow._IFKEY_in_if_then_expr2086); if (state.failed) return retval; + if (state.backtracking == 0) stream_IFKEY.Add(IFKEY107); + + DebugLocation(373, 21); + PushFollow(Follow._disjunction_expr_in_if_then_expr2090); + conditional=disjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_disjunction_expr.Add(conditional.Tree); + DebugLocation(373, 39); + THENKEY108=(IToken)Match(input,THENKEY,Follow._THENKEY_in_if_then_expr2092); if (state.failed) return retval; + if (state.backtracking == 0) stream_THENKEY.Add(THENKEY108); + + DebugLocation(373, 56); + PushFollow(Follow._expr_in_if_then_expr2096); + then_expr=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(then_expr.Tree); + DebugLocation(373, 62); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:373:62: ( ELSEKEY else_expr= expr )? + int alt21=2; + try { DebugEnterSubRule(21); + try { DebugEnterDecision(21, false); + int LA21_0 = input.LA(1); + + if ((LA21_0==ELSEKEY)) + { + alt21 = 1; + } + } finally { DebugExitDecision(21); } + switch (alt21) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:373:63: ELSEKEY else_expr= expr + { + DebugLocation(373, 63); + ELSEKEY109=(IToken)Match(input,ELSEKEY,Follow._ELSEKEY_in_if_then_expr2099); if (state.failed) return retval; + if (state.backtracking == 0) stream_ELSEKEY.Add(ELSEKEY109); + + DebugLocation(373, 80); + PushFollow(Follow._expr_in_if_then_expr2103); + else_expr=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(else_expr.Tree); + + } + break; + + } + } finally { DebugExitSubRule(21); } + + + + { + // AST REWRITE + // elements: else_expr, conditional, then_expr + // token labels: + // rule labels: else_expr, conditional, then_expr, retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_else_expr=new RewriteRuleSubtreeStream(adaptor,"rule else_expr",else_expr!=null?else_expr.Tree:null); + RewriteRuleSubtreeStream stream_conditional=new RewriteRuleSubtreeStream(adaptor,"rule conditional",conditional!=null?conditional.Tree:null); + RewriteRuleSubtreeStream stream_then_expr=new RewriteRuleSubtreeStream(adaptor,"rule then_expr",then_expr!=null?then_expr.Tree:null); + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 374:4: -> ^( IF $conditional $then_expr ( $else_expr)? ) + { + DebugLocation(374, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:374:7: ^( IF $conditional $then_expr ( $else_expr)? ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(374, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(IF, "IF"), root_1); + + DebugLocation(374, 13); + adaptor.AddChild(root_1, stream_conditional.NextTree()); + DebugLocation(374, 26); + adaptor.AddChild(root_1, stream_then_expr.NextTree()); + DebugLocation(374, 37); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:374:37: ( $else_expr)? + if (stream_else_expr.HasNext) + { + DebugLocation(374, 37); + adaptor.AddChild(root_1, stream_else_expr.NextTree()); + + } + stream_else_expr.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("if_then_expr", 26); + LeaveRule("if_then_expr", 26); + LeaveRule_if_then_expr(); + } + DebugLocation(375, 1); + } finally { DebugExitRule(GrammarFileName, "if_then_expr"); } + return retval; + + } + // $ANTLR end "if_then_expr" + + partial void EnterRule_while_stat(); + partial void LeaveRule_while_stat(); + + // $ANTLR start "while_stat" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:377:1: while_stat : WHILEKEY cond= disjunction_expr DOKEY do_expr= expr -> ^( WHILE $cond $do_expr) ; + [GrammarRule("while_stat")] + private AstParserRuleReturnScope while_stat() + { + EnterRule_while_stat(); + EnterRule("while_stat", 27); + TraceIn("while_stat", 27); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken WHILEKEY110 = default(IToken); + IToken DOKEY111 = default(IToken); + AstParserRuleReturnScope cond = default(AstParserRuleReturnScope); + AstParserRuleReturnScope do_expr = default(AstParserRuleReturnScope); + + object WHILEKEY110_tree = default(object); + object DOKEY111_tree = default(object); + RewriteRuleITokenStream stream_WHILEKEY=new RewriteRuleITokenStream(adaptor,"token WHILEKEY"); + RewriteRuleITokenStream stream_DOKEY=new RewriteRuleITokenStream(adaptor,"token DOKEY"); + RewriteRuleSubtreeStream stream_disjunction_expr=new RewriteRuleSubtreeStream(adaptor,"rule disjunction_expr"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "while_stat"); + DebugLocation(377, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:378:2: ( WHILEKEY cond= disjunction_expr DOKEY do_expr= expr -> ^( WHILE $cond $do_expr) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:378:4: WHILEKEY cond= disjunction_expr DOKEY do_expr= expr + { + DebugLocation(378, 4); + WHILEKEY110=(IToken)Match(input,WHILEKEY,Follow._WHILEKEY_in_while_stat2136); if (state.failed) return retval; + if (state.backtracking == 0) stream_WHILEKEY.Add(WHILEKEY110); + + DebugLocation(378, 17); + PushFollow(Follow._disjunction_expr_in_while_stat2140); + cond=disjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_disjunction_expr.Add(cond.Tree); + DebugLocation(378, 35); + DOKEY111=(IToken)Match(input,DOKEY,Follow._DOKEY_in_while_stat2142); if (state.failed) return retval; + if (state.backtracking == 0) stream_DOKEY.Add(DOKEY111); + + DebugLocation(378, 48); + PushFollow(Follow._expr_in_while_stat2146); + do_expr=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(do_expr.Tree); + + + { + // AST REWRITE + // elements: cond, do_expr + // token labels: + // rule labels: do_expr, cond, retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_do_expr=new RewriteRuleSubtreeStream(adaptor,"rule do_expr",do_expr!=null?do_expr.Tree:null); + RewriteRuleSubtreeStream stream_cond=new RewriteRuleSubtreeStream(adaptor,"rule cond",cond!=null?cond.Tree:null); + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 379:4: -> ^( WHILE $cond $do_expr) + { + DebugLocation(379, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:379:7: ^( WHILE $cond $do_expr) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(379, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(WHILE, "WHILE"), root_1); + + DebugLocation(379, 16); + adaptor.AddChild(root_1, stream_cond.NextTree()); + DebugLocation(379, 22); + adaptor.AddChild(root_1, stream_do_expr.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("while_stat", 27); + LeaveRule("while_stat", 27); + LeaveRule_while_stat(); + } + DebugLocation(380, 1); + } finally { DebugExitRule(GrammarFileName, "while_stat"); } + return retval; + + } + // $ANTLR end "while_stat" + + partial void EnterRule_let_expr(); + partial void LeaveRule_let_expr(); + + // $ANTLR start "let_expr" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:382:1: let_expr : LETKEY ( decl )+ INKEY expr_seq ENDKEY -> ^( LET ^( DECL_BLOCK ( decl )+ ) expr_seq ) ; + [GrammarRule("let_expr")] + private AstParserRuleReturnScope let_expr() + { + EnterRule_let_expr(); + EnterRule("let_expr", 28); + TraceIn("let_expr", 28); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken LETKEY112 = default(IToken); + IToken INKEY114 = default(IToken); + IToken ENDKEY116 = default(IToken); + AstParserRuleReturnScope decl113 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope expr_seq115 = default(AstParserRuleReturnScope); + + object LETKEY112_tree = default(object); + object INKEY114_tree = default(object); + object ENDKEY116_tree = default(object); + RewriteRuleITokenStream stream_INKEY=new RewriteRuleITokenStream(adaptor,"token INKEY"); + RewriteRuleITokenStream stream_LETKEY=new RewriteRuleITokenStream(adaptor,"token LETKEY"); + RewriteRuleITokenStream stream_ENDKEY=new RewriteRuleITokenStream(adaptor,"token ENDKEY"); + RewriteRuleSubtreeStream stream_expr_seq=new RewriteRuleSubtreeStream(adaptor,"rule expr_seq"); + RewriteRuleSubtreeStream stream_decl=new RewriteRuleSubtreeStream(adaptor,"rule decl"); + try { DebugEnterRule(GrammarFileName, "let_expr"); + DebugLocation(382, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:383:2: ( LETKEY ( decl )+ INKEY expr_seq ENDKEY -> ^( LET ^( DECL_BLOCK ( decl )+ ) expr_seq ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:383:4: LETKEY ( decl )+ INKEY expr_seq ENDKEY + { + DebugLocation(383, 4); + LETKEY112=(IToken)Match(input,LETKEY,Follow._LETKEY_in_let_expr2172); if (state.failed) return retval; + if (state.backtracking == 0) stream_LETKEY.Add(LETKEY112); + + DebugLocation(383, 11); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:383:11: ( decl )+ + int cnt22=0; + try { DebugEnterSubRule(22); + while (true) + { + int alt22=2; + try { DebugEnterDecision(22, false); + int LA22_0 = input.LA(1); + + if ((LA22_0==FUNCTIONKEY||LA22_0==TYPEKEY||LA22_0==VARKEY)) + { + alt22 = 1; + } + + + } finally { DebugExitDecision(22); } + switch (alt22) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:383:11: decl + { + DebugLocation(383, 11); + PushFollow(Follow._decl_in_let_expr2174); + decl113=decl(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_decl.Add(decl113.Tree); + + } + break; + + default: + if (cnt22 >= 1) + goto loop22; + + if (state.backtracking>0) {state.failed=true; return retval;} + EarlyExitException eee22 = new EarlyExitException( 22, input ); + DebugRecognitionException(eee22); + throw eee22; + } + cnt22++; + } + loop22: + ; + + } finally { DebugExitSubRule(22); } + + DebugLocation(383, 17); + INKEY114=(IToken)Match(input,INKEY,Follow._INKEY_in_let_expr2177); if (state.failed) return retval; + if (state.backtracking == 0) stream_INKEY.Add(INKEY114); + + DebugLocation(383, 23); + PushFollow(Follow._expr_seq_in_let_expr2179); + expr_seq115=expr_seq(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr_seq.Add(expr_seq115.Tree); + DebugLocation(383, 32); + ENDKEY116=(IToken)Match(input,ENDKEY,Follow._ENDKEY_in_let_expr2181); if (state.failed) return retval; + if (state.backtracking == 0) stream_ENDKEY.Add(ENDKEY116); + + + + { + // AST REWRITE + // elements: expr_seq, decl + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 384:4: -> ^( LET ^( DECL_BLOCK ( decl )+ ) expr_seq ) + { + DebugLocation(384, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:384:7: ^( LET ^( DECL_BLOCK ( decl )+ ) expr_seq ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(384, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(LET, "LET"), root_1); + + DebugLocation(384, 13); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:384:13: ^( DECL_BLOCK ( decl )+ ) + { + object root_2 = (object)adaptor.Nil(); + DebugLocation(384, 15); + root_2 = (object)adaptor.BecomeRoot((object)adaptor.Create(DECL_BLOCK, "DECL_BLOCK"), root_2); + + DebugLocation(384, 26); + if (!(stream_decl.HasNext)) + { + throw new RewriteEarlyExitException(); + } + while ( stream_decl.HasNext ) + { + DebugLocation(384, 26); + adaptor.AddChild(root_2, stream_decl.NextTree()); + + } + stream_decl.Reset(); + + adaptor.AddChild(root_1, root_2); + } + DebugLocation(384, 33); + adaptor.AddChild(root_1, stream_expr_seq.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("let_expr", 28); + LeaveRule("let_expr", 28); + LeaveRule_let_expr(); + } + DebugLocation(385, 1); + } finally { DebugExitRule(GrammarFileName, "let_expr"); } + return retval; + + } + // $ANTLR end "let_expr" + + partial void EnterRule_lvalue(); + partial void LeaveRule_lvalue(); + + // $ANTLR start "lvalue" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:387:1: lvalue : type_id ( lvalue_access )? -> ^( VAR_ACCESS type_id ( lvalue_access )? ) ; + [GrammarRule("lvalue")] + private AstParserRuleReturnScope lvalue() + { + EnterRule_lvalue(); + EnterRule("lvalue", 29); + TraceIn("lvalue", 29); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + AstParserRuleReturnScope type_id117 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope lvalue_access118 = default(AstParserRuleReturnScope); + + RewriteRuleSubtreeStream stream_type_id=new RewriteRuleSubtreeStream(adaptor,"rule type_id"); + RewriteRuleSubtreeStream stream_lvalue_access=new RewriteRuleSubtreeStream(adaptor,"rule lvalue_access"); + try { DebugEnterRule(GrammarFileName, "lvalue"); + DebugLocation(387, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:388:2: ( type_id ( lvalue_access )? -> ^( VAR_ACCESS type_id ( lvalue_access )? ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:388:4: type_id ( lvalue_access )? + { + DebugLocation(388, 4); + PushFollow(Follow._type_id_in_lvalue2211); + type_id117=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id117.Tree); + DebugLocation(388, 12); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:388:12: ( lvalue_access )? + int alt23=2; + try { DebugEnterSubRule(23); + try { DebugEnterDecision(23, false); + int LA23_0 = input.LA(1); + + if ((LA23_0==DOT||LA23_0==LBRACKET)) + { + alt23 = 1; + } + } finally { DebugExitDecision(23); } + switch (alt23) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:388:12: lvalue_access + { + DebugLocation(388, 12); + PushFollow(Follow._lvalue_access_in_lvalue2213); + lvalue_access118=lvalue_access(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_lvalue_access.Add(lvalue_access118.Tree); + + } + break; + + } + } finally { DebugExitSubRule(23); } + + + + { + // AST REWRITE + // elements: lvalue_access, type_id + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 388:27: -> ^( VAR_ACCESS type_id ( lvalue_access )? ) + { + DebugLocation(388, 30); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:388:30: ^( VAR_ACCESS type_id ( lvalue_access )? ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(388, 32); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(VAR_ACCESS, "VAR_ACCESS"), root_1); + + DebugLocation(388, 43); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + DebugLocation(388, 51); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:388:51: ( lvalue_access )? + if (stream_lvalue_access.HasNext) + { + DebugLocation(388, 51); + adaptor.AddChild(root_1, stream_lvalue_access.NextTree()); + + } + stream_lvalue_access.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("lvalue", 29); + LeaveRule("lvalue", 29); + LeaveRule_lvalue(); + } + DebugLocation(389, 1); + } finally { DebugExitRule(GrammarFileName, "lvalue"); } + return retval; + + } + // $ANTLR end "lvalue" + + partial void EnterRule_lvalue_access(); + partial void LeaveRule_lvalue_access(); + + // $ANTLR start "lvalue_access" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:391:1: 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 )? ) ); + [GrammarRule("lvalue_access")] + private AstParserRuleReturnScope lvalue_access() + { + EnterRule_lvalue_access(); + EnterRule("lvalue_access", 30); + TraceIn("lvalue_access", 30); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken DOT119 = default(IToken); + IToken LBRACKET122 = default(IToken); + IToken RBRACKET124 = default(IToken); + AstParserRuleReturnScope type_id120 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope lvalue_access121 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope disjunction_expr123 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope lvalue_access125 = default(AstParserRuleReturnScope); + + object DOT119_tree = default(object); + object LBRACKET122_tree = default(object); + object RBRACKET124_tree = default(object); + RewriteRuleITokenStream stream_DOT=new RewriteRuleITokenStream(adaptor,"token DOT"); + RewriteRuleITokenStream stream_LBRACKET=new RewriteRuleITokenStream(adaptor,"token LBRACKET"); + RewriteRuleITokenStream stream_RBRACKET=new RewriteRuleITokenStream(adaptor,"token RBRACKET"); + RewriteRuleSubtreeStream stream_type_id=new RewriteRuleSubtreeStream(adaptor,"rule type_id"); + RewriteRuleSubtreeStream stream_disjunction_expr=new RewriteRuleSubtreeStream(adaptor,"rule disjunction_expr"); + RewriteRuleSubtreeStream stream_lvalue_access=new RewriteRuleSubtreeStream(adaptor,"rule lvalue_access"); + try { DebugEnterRule(GrammarFileName, "lvalue_access"); + DebugLocation(391, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:392:2: ( DOT type_id ( lvalue_access )? -> ^( FIELD_ACCESS type_id ( lvalue_access )? ) | LBRACKET disjunction_expr RBRACKET ( lvalue_access )? -> ^( ARRAY_ACCESS disjunction_expr ( lvalue_access )? ) ) + int alt26=2; + try { DebugEnterDecision(26, false); + int LA26_0 = input.LA(1); + + if ((LA26_0==DOT)) + { + alt26 = 1; + } + else if ((LA26_0==LBRACKET)) + { + alt26 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 26, 0, input); + DebugRecognitionException(nvae); + throw nvae; + } + } finally { DebugExitDecision(26); } + switch (alt26) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:392:4: DOT type_id ( lvalue_access )? + { + DebugLocation(392, 4); + DOT119=(IToken)Match(input,DOT,Follow._DOT_in_lvalue_access2236); if (state.failed) return retval; + if (state.backtracking == 0) stream_DOT.Add(DOT119); + + DebugLocation(392, 8); + PushFollow(Follow._type_id_in_lvalue_access2238); + type_id120=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id120.Tree); + DebugLocation(392, 16); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:392:16: ( lvalue_access )? + int alt24=2; + try { DebugEnterSubRule(24); + try { DebugEnterDecision(24, false); + int LA24_0 = input.LA(1); + + if ((LA24_0==DOT||LA24_0==LBRACKET)) + { + alt24 = 1; + } + } finally { DebugExitDecision(24); } + switch (alt24) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:392:16: lvalue_access + { + DebugLocation(392, 16); + PushFollow(Follow._lvalue_access_in_lvalue_access2240); + lvalue_access121=lvalue_access(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_lvalue_access.Add(lvalue_access121.Tree); + + } + break; + + } + } finally { DebugExitSubRule(24); } + + + + { + // AST REWRITE + // elements: lvalue_access, type_id + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 393:13: -> ^( FIELD_ACCESS type_id ( lvalue_access )? ) + { + DebugLocation(393, 16); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:393:16: ^( FIELD_ACCESS type_id ( lvalue_access )? ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(393, 18); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(FIELD_ACCESS, "FIELD_ACCESS"), root_1); + + DebugLocation(393, 31); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + DebugLocation(393, 39); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:393:39: ( lvalue_access )? + if (stream_lvalue_access.HasNext) + { + DebugLocation(393, 39); + adaptor.AddChild(root_1, stream_lvalue_access.NextTree()); + + } + stream_lvalue_access.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:394:4: LBRACKET disjunction_expr RBRACKET ( lvalue_access )? + { + DebugLocation(394, 4); + LBRACKET122=(IToken)Match(input,LBRACKET,Follow._LBRACKET_in_lvalue_access2269); if (state.failed) return retval; + if (state.backtracking == 0) stream_LBRACKET.Add(LBRACKET122); + + DebugLocation(394, 13); + PushFollow(Follow._disjunction_expr_in_lvalue_access2271); + disjunction_expr123=disjunction_expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_disjunction_expr.Add(disjunction_expr123.Tree); + DebugLocation(394, 30); + RBRACKET124=(IToken)Match(input,RBRACKET,Follow._RBRACKET_in_lvalue_access2273); if (state.failed) return retval; + if (state.backtracking == 0) stream_RBRACKET.Add(RBRACKET124); + + DebugLocation(394, 39); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:394:39: ( lvalue_access )? + int alt25=2; + try { DebugEnterSubRule(25); + try { DebugEnterDecision(25, false); + int LA25_0 = input.LA(1); + + if ((LA25_0==DOT||LA25_0==LBRACKET)) + { + alt25 = 1; + } + } finally { DebugExitDecision(25); } + switch (alt25) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:394:39: lvalue_access + { + DebugLocation(394, 39); + PushFollow(Follow._lvalue_access_in_lvalue_access2275); + lvalue_access125=lvalue_access(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_lvalue_access.Add(lvalue_access125.Tree); + + } + break; + + } + } finally { DebugExitSubRule(25); } + + + + { + // AST REWRITE + // elements: lvalue_access, disjunction_expr + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 395:4: -> ^( ARRAY_ACCESS disjunction_expr ( lvalue_access )? ) + { + DebugLocation(395, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:395:7: ^( ARRAY_ACCESS disjunction_expr ( lvalue_access )? ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(395, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(ARRAY_ACCESS, "ARRAY_ACCESS"), root_1); + + DebugLocation(395, 22); + adaptor.AddChild(root_1, stream_disjunction_expr.NextTree()); + DebugLocation(395, 39); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:395:39: ( lvalue_access )? + if (stream_lvalue_access.HasNext) + { + DebugLocation(395, 39); + adaptor.AddChild(root_1, stream_lvalue_access.NextTree()); + + } + stream_lvalue_access.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + + } + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("lvalue_access", 30); + LeaveRule("lvalue_access", 30); + LeaveRule_lvalue_access(); + } + DebugLocation(396, 1); + } finally { DebugExitRule(GrammarFileName, "lvalue_access"); } + return retval; + + } + // $ANTLR end "lvalue_access" + + partial void EnterRule_funcall(); + partial void LeaveRule_funcall(); + + // $ANTLR start "funcall" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:398:1: funcall : type_id LPAREN ( arg_list )? RPAREN -> ^( FUN_CALL type_id ( arg_list )? ) ; + [GrammarRule("funcall")] + private AstParserRuleReturnScope funcall() + { + EnterRule_funcall(); + EnterRule("funcall", 31); + TraceIn("funcall", 31); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken LPAREN127 = default(IToken); + IToken RPAREN129 = default(IToken); + AstParserRuleReturnScope type_id126 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope arg_list128 = default(AstParserRuleReturnScope); + + object LPAREN127_tree = default(object); + object RPAREN129_tree = default(object); + RewriteRuleITokenStream stream_LPAREN=new RewriteRuleITokenStream(adaptor,"token LPAREN"); + RewriteRuleITokenStream stream_RPAREN=new RewriteRuleITokenStream(adaptor,"token RPAREN"); + RewriteRuleSubtreeStream stream_type_id=new RewriteRuleSubtreeStream(adaptor,"rule type_id"); + RewriteRuleSubtreeStream stream_arg_list=new RewriteRuleSubtreeStream(adaptor,"rule arg_list"); + try { DebugEnterRule(GrammarFileName, "funcall"); + DebugLocation(398, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:399:2: ( type_id LPAREN ( arg_list )? RPAREN -> ^( FUN_CALL type_id ( arg_list )? ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:399:4: type_id LPAREN ( arg_list )? RPAREN + { + DebugLocation(399, 4); + PushFollow(Follow._type_id_in_funcall2301); + type_id126=type_id(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_type_id.Add(type_id126.Tree); + DebugLocation(399, 12); + LPAREN127=(IToken)Match(input,LPAREN,Follow._LPAREN_in_funcall2303); if (state.failed) return retval; + if (state.backtracking == 0) stream_LPAREN.Add(LPAREN127); + + DebugLocation(399, 19); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:399:19: ( arg_list )? + int alt27=2; + try { DebugEnterSubRule(27); + try { DebugEnterDecision(27, false); + int LA27_0 = input.LA(1); + + if ((LA27_0==BREAKKEY||LA27_0==FORKEY||LA27_0==ID||LA27_0==IFKEY||(LA27_0>=INT && LA27_0<=INTKEY)||LA27_0==LETKEY||LA27_0==LPAREN||LA27_0==MINUS||LA27_0==NILKEY||(LA27_0>=STRING && LA27_0<=STRINGKEY)||LA27_0==WHILEKEY)) + { + alt27 = 1; + } + } finally { DebugExitDecision(27); } + switch (alt27) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:399:19: arg_list + { + DebugLocation(399, 19); + PushFollow(Follow._arg_list_in_funcall2305); + arg_list128=arg_list(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_arg_list.Add(arg_list128.Tree); + + } + break; + + } + } finally { DebugExitSubRule(27); } + + DebugLocation(399, 29); + RPAREN129=(IToken)Match(input,RPAREN,Follow._RPAREN_in_funcall2308); if (state.failed) return retval; + if (state.backtracking == 0) stream_RPAREN.Add(RPAREN129); + + + + { + // AST REWRITE + // elements: arg_list, type_id + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 400:4: -> ^( FUN_CALL type_id ( arg_list )? ) + { + DebugLocation(400, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:400:7: ^( FUN_CALL type_id ( arg_list )? ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(400, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(FUN_CALL, "FUN_CALL"), root_1); + + DebugLocation(400, 18); + adaptor.AddChild(root_1, stream_type_id.NextTree()); + DebugLocation(400, 26); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:400:26: ( arg_list )? + if (stream_arg_list.HasNext) + { + DebugLocation(400, 26); + adaptor.AddChild(root_1, stream_arg_list.NextTree()); + + } + stream_arg_list.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("funcall", 31); + LeaveRule("funcall", 31); + LeaveRule_funcall(); + } + DebugLocation(401, 1); + } finally { DebugExitRule(GrammarFileName, "funcall"); } + return retval; + + } + // $ANTLR end "funcall" + + partial void EnterRule_expr_seq(); + partial void LeaveRule_expr_seq(); + + // $ANTLR start "expr_seq" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:403:1: expr_seq : ( expr ( SEMI expr )* -> ^( EXPR_SEQ ( expr )+ ) | -> ^( EXPR_SEQ ) ); + [GrammarRule("expr_seq")] + private AstParserRuleReturnScope expr_seq() + { + EnterRule_expr_seq(); + EnterRule("expr_seq", 32); + TraceIn("expr_seq", 32); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken SEMI131 = default(IToken); + AstParserRuleReturnScope expr130 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope expr132 = default(AstParserRuleReturnScope); + + object SEMI131_tree = default(object); + RewriteRuleITokenStream stream_SEMI=new RewriteRuleITokenStream(adaptor,"token SEMI"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "expr_seq"); + DebugLocation(403, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:404:2: ( expr ( SEMI expr )* -> ^( EXPR_SEQ ( expr )+ ) | -> ^( EXPR_SEQ ) ) + int alt29=2; + try { DebugEnterDecision(29, false); + int LA29_0 = input.LA(1); + + if ((LA29_0==BREAKKEY||LA29_0==FORKEY||LA29_0==ID||LA29_0==IFKEY||(LA29_0>=INT && LA29_0<=INTKEY)||LA29_0==LETKEY||LA29_0==LPAREN||LA29_0==MINUS||LA29_0==NILKEY||(LA29_0>=STRING && LA29_0<=STRINGKEY)||LA29_0==WHILEKEY)) + { + alt29 = 1; + } + else if ((LA29_0==ENDKEY||LA29_0==RPAREN)) + { + alt29 = 2; + } + else + { + if (state.backtracking>0) {state.failed=true; return retval;} + NoViableAltException nvae = new NoViableAltException("", 29, 0, input); + DebugRecognitionException(nvae); + throw nvae; + } + } finally { DebugExitDecision(29); } + switch (alt29) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:404:4: expr ( SEMI expr )* + { + DebugLocation(404, 4); + PushFollow(Follow._expr_in_expr_seq2334); + expr130=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr130.Tree); + DebugLocation(404, 9); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:404:9: ( SEMI expr )* + try { DebugEnterSubRule(28); + while (true) + { + int alt28=2; + try { DebugEnterDecision(28, false); + int LA28_0 = input.LA(1); + + if ((LA28_0==SEMI)) + { + alt28 = 1; + } + + + } finally { DebugExitDecision(28); } + switch ( alt28 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:404:10: SEMI expr + { + DebugLocation(404, 10); + SEMI131=(IToken)Match(input,SEMI,Follow._SEMI_in_expr_seq2337); if (state.failed) return retval; + if (state.backtracking == 0) stream_SEMI.Add(SEMI131); + + DebugLocation(404, 15); + PushFollow(Follow._expr_in_expr_seq2339); + expr132=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr132.Tree); + + } + break; + + default: + goto loop28; + } + } + + loop28: + ; + + } finally { DebugExitSubRule(28); } + + + + { + // AST REWRITE + // elements: expr + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 405:4: -> ^( EXPR_SEQ ( expr )+ ) + { + DebugLocation(405, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:405:7: ^( EXPR_SEQ ( expr )+ ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(405, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(EXPR_SEQ, "EXPR_SEQ"), root_1); + + DebugLocation(405, 18); + if (!(stream_expr.HasNext)) + { + throw new RewriteEarlyExitException(); + } + while ( stream_expr.HasNext ) + { + DebugLocation(405, 18); + adaptor.AddChild(root_1, stream_expr.NextTree()); + + } + stream_expr.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + case 2: + DebugEnterAlt(2); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:406:9: + { + + { + // AST REWRITE + // elements: + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 406:9: -> ^( EXPR_SEQ ) + { + DebugLocation(406, 12); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:406:12: ^( EXPR_SEQ ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(406, 14); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(EXPR_SEQ, "EXPR_SEQ"), root_1); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + break; + + } + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("expr_seq", 32); + LeaveRule("expr_seq", 32); + LeaveRule_expr_seq(); + } + DebugLocation(407, 1); + } finally { DebugExitRule(GrammarFileName, "expr_seq"); } + return retval; + + } + // $ANTLR end "expr_seq" + + partial void EnterRule_arg_list(); + partial void LeaveRule_arg_list(); + + // $ANTLR start "arg_list" + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:409:1: arg_list : expr ( COMMA expr )* -> ^( ARGS_FIELDS ( expr )+ ) ; + [GrammarRule("arg_list")] + private AstParserRuleReturnScope arg_list() + { + EnterRule_arg_list(); + EnterRule("arg_list", 33); + TraceIn("arg_list", 33); + AstParserRuleReturnScope retval = new AstParserRuleReturnScope(); + retval.Start = (IToken)input.LT(1); + + object root_0 = default(object); + + IToken COMMA134 = default(IToken); + AstParserRuleReturnScope expr133 = default(AstParserRuleReturnScope); + AstParserRuleReturnScope expr135 = default(AstParserRuleReturnScope); + + object COMMA134_tree = default(object); + RewriteRuleITokenStream stream_COMMA=new RewriteRuleITokenStream(adaptor,"token COMMA"); + RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr"); + try { DebugEnterRule(GrammarFileName, "arg_list"); + DebugLocation(409, 1); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:410:2: ( expr ( COMMA expr )* -> ^( ARGS_FIELDS ( expr )+ ) ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:410:4: expr ( COMMA expr )* + { + DebugLocation(410, 4); + PushFollow(Follow._expr_in_arg_list2381); + expr133=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr133.Tree); + DebugLocation(410, 9); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:410:9: ( COMMA expr )* + try { DebugEnterSubRule(30); + while (true) + { + int alt30=2; + try { DebugEnterDecision(30, false); + int LA30_0 = input.LA(1); + + if ((LA30_0==COMMA)) + { + alt30 = 1; + } + + + } finally { DebugExitDecision(30); } + switch ( alt30 ) + { + case 1: + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:410:10: COMMA expr + { + DebugLocation(410, 10); + COMMA134=(IToken)Match(input,COMMA,Follow._COMMA_in_arg_list2384); if (state.failed) return retval; + if (state.backtracking == 0) stream_COMMA.Add(COMMA134); + + DebugLocation(410, 16); + PushFollow(Follow._expr_in_arg_list2386); + expr135=expr(); + PopFollow(); + if (state.failed) return retval; + if (state.backtracking == 0) stream_expr.Add(expr135.Tree); + + } + break; + + default: + goto loop30; + } + } + + loop30: + ; + + } finally { DebugExitSubRule(30); } + + + + { + // AST REWRITE + // elements: expr + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if (state.backtracking == 0) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); + + root_0 = (object)adaptor.Nil(); + // 411:4: -> ^( ARGS_FIELDS ( expr )+ ) + { + DebugLocation(411, 7); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:411:7: ^( ARGS_FIELDS ( expr )+ ) + { + object root_1 = (object)adaptor.Nil(); + DebugLocation(411, 9); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(ARGS_FIELDS, "ARGS_FIELDS"), root_1); + + DebugLocation(411, 21); + if (!(stream_expr.HasNext)) + { + throw new RewriteEarlyExitException(); + } + while ( stream_expr.HasNext ) + { + DebugLocation(411, 21); + adaptor.AddChild(root_1, stream_expr.NextTree()); + + } + stream_expr.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0; + } + } + + } + + retval.Stop = (IToken)input.LT(-1); + + if (state.backtracking == 0) { + retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + retval.Tree = (object)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); + + } + finally + { + TraceOut("arg_list", 33); + LeaveRule("arg_list", 33); + LeaveRule_arg_list(); + } + DebugLocation(412, 1); + } finally { DebugExitRule(GrammarFileName, "arg_list"); } + return retval; + + } + // $ANTLR end "arg_list" + + partial void EnterRule_synpred1_tiger_fragment(); + partial void LeaveRule_synpred1_tiger_fragment(); + + // $ANTLR start synpred1_tiger + public void synpred1_tiger_fragment() + { + EnterRule_synpred1_tiger_fragment(); + EnterRule("synpred1_tiger_fragment", 34); + TraceIn("synpred1_tiger_fragment", 34); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:223:4: ( ID LBRACKET disjunction_expr RBRACKET OFKEY ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:223:5: ID LBRACKET disjunction_expr RBRACKET OFKEY + { + DebugLocation(223, 5); + Match(input,ID,Follow._ID_in_synpred1_tiger1172); if (state.failed) return; + DebugLocation(223, 8); + Match(input,LBRACKET,Follow._LBRACKET_in_synpred1_tiger1174); if (state.failed) return; + DebugLocation(223, 17); + PushFollow(Follow._disjunction_expr_in_synpred1_tiger1176); + disjunction_expr(); + PopFollow(); + if (state.failed) return; + DebugLocation(223, 34); + Match(input,RBRACKET,Follow._RBRACKET_in_synpred1_tiger1178); if (state.failed) return; + DebugLocation(223, 43); + Match(input,OFKEY,Follow._OFKEY_in_synpred1_tiger1180); if (state.failed) return; + + } + + } + finally + { + TraceOut("synpred1_tiger_fragment", 34); + LeaveRule("synpred1_tiger_fragment", 34); + LeaveRule_synpred1_tiger_fragment(); + } + } + // $ANTLR end synpred1_tiger + + partial void EnterRule_synpred2_tiger_fragment(); + partial void LeaveRule_synpred2_tiger_fragment(); + + // $ANTLR start synpred2_tiger + public void synpred2_tiger_fragment() + { + EnterRule_synpred2_tiger_fragment(); + EnterRule("synpred2_tiger_fragment", 35); + TraceIn("synpred2_tiger_fragment", 35); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:224:4: ( lvalue ASSIGN ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:224:5: lvalue ASSIGN + { + DebugLocation(224, 5); + PushFollow(Follow._lvalue_in_synpred2_tiger1191); + lvalue(); + PopFollow(); + if (state.failed) return; + DebugLocation(224, 12); + Match(input,ASSIGN,Follow._ASSIGN_in_synpred2_tiger1193); if (state.failed) return; + + } + + } + finally + { + TraceOut("synpred2_tiger_fragment", 35); + LeaveRule("synpred2_tiger_fragment", 35); + LeaveRule_synpred2_tiger_fragment(); + } + } + // $ANTLR end synpred2_tiger + + partial void EnterRule_synpred3_tiger_fragment(); + partial void LeaveRule_synpred3_tiger_fragment(); + + // $ANTLR start synpred3_tiger + public void synpred3_tiger_fragment() + { + EnterRule_synpred3_tiger_fragment(); + EnterRule("synpred3_tiger_fragment", 36); + TraceIn("synpred3_tiger_fragment", 36); + try + { + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:238:6: ( ID LBRACKET disjunction_expr RBRACKET OFKEY ) + DebugEnterAlt(1); + // D:\\~Compilador\\!yatc\\Grammar\\tiger.g:238:7: ID LBRACKET disjunction_expr RBRACKET OFKEY + { + DebugLocation(238, 7); + Match(input,ID,Follow._ID_in_synpred3_tiger1279); if (state.failed) return; + DebugLocation(238, 10); + Match(input,LBRACKET,Follow._LBRACKET_in_synpred3_tiger1281); if (state.failed) return; + DebugLocation(238, 19); + PushFollow(Follow._disjunction_expr_in_synpred3_tiger1283); + disjunction_expr(); + PopFollow(); + if (state.failed) return; + DebugLocation(238, 36); + Match(input,RBRACKET,Follow._RBRACKET_in_synpred3_tiger1285); if (state.failed) return; + DebugLocation(238, 45); + Match(input,OFKEY,Follow._OFKEY_in_synpred3_tiger1287); if (state.failed) return; + + } + + } + finally + { + TraceOut("synpred3_tiger_fragment", 36); + LeaveRule("synpred3_tiger_fragment", 36); + LeaveRule_synpred3_tiger_fragment(); + } + } + // $ANTLR end synpred3_tiger + #endregion Rules + + #region Synpreds + private bool EvaluatePredicate(System.Action fragment) + { + bool success = false; + state.backtracking++; + try { DebugBeginBacktrack(state.backtracking); + int start = input.Mark(); + try + { + fragment(); + } + catch ( RecognitionException re ) + { + System.Console.Error.WriteLine("impossible: "+re); + } + success = !state.failed; + input.Rewind(start); + } finally { DebugEndBacktrack(state.backtracking, success); } + state.backtracking--; + state.failed=false; + return success; + } + #endregion Synpreds + + + #region DFA + private DFA2 dfa2; + + protected override void InitDFAs() + { + base.InitDFAs(); + dfa2 = new DFA2( this, SpecialStateTransition2 ); + } + + private class DFA2 : DFA + { + private const string DFA2_eotS = + "\x4D\xFFFF"; + private const string DFA2_eofS = + "\x1\xFFFF\x2\x3\x4A\xFFFF"; + private const string DFA2_minS = + "\x1\xF\x2\x5\x8\xFFFF\x1\x24\x1\xFFFF\x1\x2C\x16\xFFFF\x1\x2C\x1\x24"+ + "\x16\xFFFF\x10\x0\x1\xFFFF"; + private const string DFA2_maxS = + "\x1\x5A\x2\x56\x8\xFFFF\x1\x4E\x1\xFFFF\x1\x4E\x16\xFFFF\x2\x4E\x16\xFFFF"+ + "\x10\x0\x1\xFFFF"; + private const string DFA2_acceptS = + "\x3\xFFFF\x1\x3\x5\xFFFF\x1\x5\x1\x6\x1\xFFFF\x1\x4\x1\xFFFF\x1\x2\x17"+ + "\xFFFF\x1\x2\x25\xFFFF\x1\x1"; + private const string DFA2_specialS = + "\x1\xFFFF\x1\x0\x1\x1\x39\xFFFF\x1\x2\x1\x3\x1\x4\x1\x5\x1\x6\x1\x7\x1"+ + "\x8\x1\x9\x1\xA\x1\xB\x1\xC\x1\xD\x1\xE\x1\xF\x1\x10\x1\x11\x1\xFFFF}>"; + private static readonly string[] DFA2_transitionS = + { + "\x1\xA\x14\xFFFF\x1\x3\x7\xFFFF\x1\x1\x1\xFFFF\x1\x3\x1\xFFFF\x1\x3"+ + "\x1\x2\x2\xFFFF\x1\x3\x2\xFFFF\x1\x3\x2\xFFFF\x1\x3\x3\xFFFF\x1\x3\xE"+ + "\xFFFF\x1\x3\x1\x2\xB\xFFFF\x1\x9", + "\x1\x3\x6\xFFFF\x1\xE\x4\xFFFF\x1\x3\x3\xFFFF\x2\x3\x1\xD\x2\x3\x1"+ + "\xFFFF\x1\x3\x9\xFFFF\x1\x3\x4\xFFFF\x2\x3\x3\xFFFF\x1\x3\x2\xFFFF\x1"+ + "\xB\x3\xFFFF\x1\xC\x5\x3\x3\xFFFF\x1\x3\x1\xFFFF\x1\x3\x1\xFFFF\x1\x3"+ + "\x3\xFFFF\x1\x3\x2\xFFFF\x3\x3\x2\xFFFF\x2\x3\x1\xFFFF\x1\x3\x3\xFFFF"+ + "\x1\x3", + "\x1\x3\x6\xFFFF\x1\x26\x4\xFFFF\x1\x3\x3\xFFFF\x2\x3\x1\x24\x2\x3\x1"+ + "\xFFFF\x1\x3\x9\xFFFF\x1\x3\x4\xFFFF\x2\x3\x3\xFFFF\x1\x3\x2\xFFFF\x1"+ + "\x25\x4\xFFFF\x5\x3\x3\xFFFF\x1\x3\x1\xFFFF\x1\x3\x1\xFFFF\x1\x3\x3"+ + "\xFFFF\x1\x3\x2\xFFFF\x3\x3\x2\xFFFF\x2\x3\x1\xFFFF\x1\x3\x3\xFFFF\x1"+ + "\x3", + "", + "", + "", + "", + "", + "", + "", + "", + "\x1\x40\x7\xFFFF\x1\x3E\x1\xFFFF\x1\x3F\x1\xFFFF\x1\x3D\x1\x3E\x2\xFFFF"+ + "\x1\x41\x2\xFFFF\x1\x42\x2\xFFFF\x1\x3C\x3\xFFFF\x1\x3D\xE\xFFFF\x1"+ + "\x3D\x1\x3E", + "", + "\x1\x43\x4\xFFFF\x1\x43\x1C\xFFFF\x1\x43", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\x1\x44\x4\xFFFF\x1\x44\x1C\xFFFF\x1\x44", + "\x1\x49\x7\xFFFF\x1\x47\x1\xFFFF\x1\x48\x1\xFFFF\x1\x46\x1\x47\x2\xFFFF"+ + "\x1\x4A\x2\xFFFF\x1\x4B\x2\xFFFF\x1\x45\x3\xFFFF\x1\x46\xE\xFFFF\x1"+ + "\x46\x1\x47", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "\x1\xFFFF", + "" + }; + + private static readonly short[] DFA2_eot = DFA.UnpackEncodedString(DFA2_eotS); + private static readonly short[] DFA2_eof = DFA.UnpackEncodedString(DFA2_eofS); + private static readonly char[] DFA2_min = DFA.UnpackEncodedStringToUnsignedChars(DFA2_minS); + private static readonly char[] DFA2_max = DFA.UnpackEncodedStringToUnsignedChars(DFA2_maxS); + private static readonly short[] DFA2_accept = DFA.UnpackEncodedString(DFA2_acceptS); + private static readonly short[] DFA2_special = DFA.UnpackEncodedString(DFA2_specialS); + private static readonly short[][] DFA2_transition; + + static DFA2() + { + int numStates = DFA2_transitionS.Length; + DFA2_transition = new short[numStates][]; + for ( int i=0; i < numStates; i++ ) + { + DFA2_transition[i] = DFA.UnpackEncodedString(DFA2_transitionS[i]); + } + } + + public DFA2( BaseRecognizer recognizer, SpecialStateTransitionHandler specialStateTransition ) + : base(specialStateTransition) + { + this.recognizer = recognizer; + this.decisionNumber = 2; + this.eot = DFA2_eot; + this.eof = DFA2_eof; + this.min = DFA2_min; + this.max = DFA2_max; + this.accept = DFA2_accept; + this.special = DFA2_special; + this.transition = DFA2_transition; + } + + public override string Description { get { return "222:1: expr : ( ( ID LBRACKET disjunction_expr RBRACKET OFKEY )=> array_inst | ( lvalue ASSIGN )=> assignment | disjunction_expr | record_inst | while_stat | BREAKKEY -> BREAK );"; } } + + public override void Error(NoViableAltException nvae) + { + DebugRecognitionException(nvae); + } + } + + private int SpecialStateTransition2(DFA dfa, int s, IIntStream _input) + { + ITokenStream input = (ITokenStream)_input; + int _s = s; + switch (s) + { + case 0: + int LA2_1 = input.LA(1); + + + int index2_1 = input.Index; + input.Rewind(); + s = -1; + if ((LA2_1==LBRACKET)) {s = 11;} + + else if ((LA2_1==LKEY)) {s = 12;} + + else if ((LA2_1==DOT)) {s = 13;} + + else if ((LA2_1==ASSIGN) && (EvaluatePredicate(synpred2_tiger_fragment))) {s = 14;} + + else if ((LA2_1==EOF||LA2_1==AND||LA2_1==COMMA||(LA2_1>=DIV && LA2_1<=DOKEY)||(LA2_1>=ELSEKEY && LA2_1<=ENDKEY)||LA2_1==EQ||LA2_1==FUNCTIONKEY||(LA2_1>=GT && LA2_1<=GTEQ)||LA2_1==INKEY||(LA2_1>=LPAREN && LA2_1<=MULT)||LA2_1==NOTEQ||LA2_1==OR||LA2_1==PLUS||LA2_1==RBRACKET||(LA2_1>=RKEY && LA2_1<=SEMI)||(LA2_1>=THENKEY && LA2_1<=TOKEY)||LA2_1==TYPEKEY||LA2_1==VARKEY)) {s = 3;} + + + input.Seek(index2_1); + if (s >= 0) return s; + break; + + case 1: + int LA2_2 = input.LA(1); + + + int index2_2 = input.Index; + input.Rewind(); + s = -1; + if ((LA2_2==DOT)) {s = 36;} + + else if ((LA2_2==LBRACKET)) {s = 37;} + + else if ((LA2_2==ASSIGN) && (EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((LA2_2==EOF||LA2_2==AND||LA2_2==COMMA||(LA2_2>=DIV && LA2_2<=DOKEY)||(LA2_2>=ELSEKEY && LA2_2<=ENDKEY)||LA2_2==EQ||LA2_2==FUNCTIONKEY||(LA2_2>=GT && LA2_2<=GTEQ)||LA2_2==INKEY||(LA2_2>=LPAREN && LA2_2<=MULT)||LA2_2==NOTEQ||LA2_2==OR||LA2_2==PLUS||LA2_2==RBRACKET||(LA2_2>=RKEY && LA2_2<=SEMI)||(LA2_2>=THENKEY && LA2_2<=TOKEY)||LA2_2==TYPEKEY||LA2_2==VARKEY)) {s = 3;} + + + input.Seek(index2_2); + if (s >= 0) return s; + break; + + case 2: + int LA2_60 = input.LA(1); + + + int index2_60 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred1_tiger_fragment))) {s = 76;} + + else if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_60); + if (s >= 0) return s; + break; + + case 3: + int LA2_61 = input.LA(1); + + + int index2_61 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred1_tiger_fragment))) {s = 76;} + + else if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_61); + if (s >= 0) return s; + break; + + case 4: + int LA2_62 = input.LA(1); + + + int index2_62 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred1_tiger_fragment))) {s = 76;} + + else if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_62); + if (s >= 0) return s; + break; + + case 5: + int LA2_63 = input.LA(1); + + + int index2_63 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred1_tiger_fragment))) {s = 76;} + + else if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_63); + if (s >= 0) return s; + break; + + case 6: + int LA2_64 = input.LA(1); + + + int index2_64 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred1_tiger_fragment))) {s = 76;} + + else if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_64); + if (s >= 0) return s; + break; + + case 7: + int LA2_65 = input.LA(1); + + + int index2_65 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred1_tiger_fragment))) {s = 76;} + + else if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_65); + if (s >= 0) return s; + break; + + case 8: + int LA2_66 = input.LA(1); + + + int index2_66 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred1_tiger_fragment))) {s = 76;} + + else if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_66); + if (s >= 0) return s; + break; + + case 9: + int LA2_67 = input.LA(1); + + + int index2_67 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_67); + if (s >= 0) return s; + break; + + case 10: + int LA2_68 = input.LA(1); + + + int index2_68 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_68); + if (s >= 0) return s; + break; + + case 11: + int LA2_69 = input.LA(1); + + + int index2_69 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_69); + if (s >= 0) return s; + break; + + case 12: + int LA2_70 = input.LA(1); + + + int index2_70 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_70); + if (s >= 0) return s; + break; + + case 13: + int LA2_71 = input.LA(1); + + + int index2_71 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_71); + if (s >= 0) return s; + break; + + case 14: + int LA2_72 = input.LA(1); + + + int index2_72 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_72); + if (s >= 0) return s; + break; + + case 15: + int LA2_73 = input.LA(1); + + + int index2_73 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_73); + if (s >= 0) return s; + break; + + case 16: + int LA2_74 = input.LA(1); + + + int index2_74 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_74); + if (s >= 0) return s; + break; + + case 17: + int LA2_75 = input.LA(1); + + + int index2_75 = input.Index; + input.Rewind(); + s = -1; + if ((EvaluatePredicate(synpred2_tiger_fragment))) {s = 38;} + + else if ((true)) {s = 3;} + + + input.Seek(index2_75); + if (s >= 0) return s; + break; + } + if (state.backtracking > 0) {state.failed=true; return -1;} + NoViableAltException nvae = new NoViableAltException(dfa.Description, 2, _s, input); + dfa.Error(nvae); + throw nvae; + } + + #endregion DFA + + #region Follow sets + private static class Follow + { + public static readonly BitSet _expr_in_a_program1145 = new BitSet(new ulong[]{0x0UL}); + public static readonly BitSet _EOF_in_a_program1149 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _array_inst_in_expr1185 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _assignment_in_expr1198 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _disjunction_expr_in_expr1203 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _record_inst_in_expr1209 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _while_stat_in_expr1214 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _BREAKKEY_in_expr1219 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _conjunction_expr_in_disjunction_expr1248 = new BitSet(new ulong[]{0x2UL,0x2UL}); + public static readonly BitSet _OR_in_disjunction_expr1251 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _conjunction_expr_in_disjunction_expr1254 = new BitSet(new ulong[]{0x2UL,0x2UL}); + public static readonly BitSet _lvalue_in_assignment1267 = new BitSet(new ulong[]{0x1000UL}); + public static readonly BitSet _ASSIGN_in_assignment1269 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _array_inst_in_assignment1292 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _disjunction_expr_in_assignment1300 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _record_inst_in_assignment1308 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _ID_in_record_inst1325 = new BitSet(new ulong[]{0x40000000000000UL}); + public static readonly BitSet _LKEY_in_record_inst1327 = new BitSet(new ulong[]{0x100000000000UL,0x400UL}); + public static readonly BitSet _field_inst_list_in_record_inst1329 = new BitSet(new ulong[]{0x0UL,0x400UL}); + public static readonly BitSet _RKEY_in_record_inst1332 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _FORKEY_in_for_expr1359 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_id_in_for_expr1361 = new BitSet(new ulong[]{0x1000UL}); + public static readonly BitSet _ASSIGN_in_for_expr1363 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _disjunction_expr_in_for_expr1365 = new BitSet(new ulong[]{0x0UL,0x10000UL}); + public static readonly BitSet _TOKEY_in_for_expr1367 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _disjunction_expr_in_for_expr1369 = new BitSet(new ulong[]{0x400000UL}); + public static readonly BitSet _DOKEY_in_for_expr1371 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_for_expr1373 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _ID_in_array_inst1401 = new BitSet(new ulong[]{0x4000000000000UL}); + public static readonly BitSet _LBRACKET_in_array_inst1403 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _disjunction_expr_in_array_inst1405 = new BitSet(new ulong[]{0x0UL,0x80UL}); + public static readonly BitSet _RBRACKET_in_array_inst1407 = new BitSet(new ulong[]{0x0UL,0x1UL}); + public static readonly BitSet _OFKEY_in_array_inst1409 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_array_inst1411 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _relational_expr_in_conjunction_expr1437 = new BitSet(new ulong[]{0x22UL}); + public static readonly BitSet _AND_in_conjunction_expr1440 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _relational_expr_in_conjunction_expr1443 = new BitSet(new ulong[]{0x22UL}); + public static readonly BitSet _arith_expr_in_relational_expr1459 = new BitSet(new ulong[]{0x83000C0008000002UL}); + public static readonly BitSet _set_in_relational_expr1462 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _arith_expr_in_relational_expr1488 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _term_expr_in_arith_expr1502 = new BitSet(new ulong[]{0x400000000000002UL,0x8UL}); + public static readonly BitSet _set_in_arith_expr1505 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _term_expr_in_arith_expr1514 = new BitSet(new ulong[]{0x400000000000002UL,0x8UL}); + public static readonly BitSet _atom_in_term_expr1527 = new BitSet(new ulong[]{0x800000000200002UL}); + public static readonly BitSet _set_in_term_expr1530 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _atom_in_term_expr1539 = new BitSet(new ulong[]{0x800000000200002UL}); + public static readonly BitSet _record_field_inst_in_field_inst_list1553 = new BitSet(new ulong[]{0x20002UL}); + public static readonly BitSet _COMMA_in_field_inst_list1557 = new BitSet(new ulong[]{0x100000000000UL}); + public static readonly BitSet _record_field_inst_in_field_inst_list1559 = new BitSet(new ulong[]{0x20002UL}); + public static readonly BitSet _ID_in_record_field_inst1586 = new BitSet(new ulong[]{0x8000000UL}); + public static readonly BitSet _EQ_in_record_field_inst1588 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_record_field_inst1590 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _type_decl_in_decl1615 = new BitSet(new ulong[]{0x2UL,0x40000UL}); + public static readonly BitSet _var_decl_in_decl1633 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _fun_decl_in_decl1638 = new BitSet(new ulong[]{0x2000000002UL}); + public static readonly BitSet _TYPEKEY_in_type_decl1662 = new BitSet(new ulong[]{0x100000000000UL}); + public static readonly BitSet _ID_in_type_decl1664 = new BitSet(new ulong[]{0x8000000UL}); + public static readonly BitSet _EQ_in_type_decl1666 = new BitSet(new ulong[]{0x42100000000080UL,0x4000UL}); + public static readonly BitSet _type_in_type_decl1668 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _VARKEY_in_var_decl1692 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_id_in_var_decl1694 = new BitSet(new ulong[]{0x10000UL}); + public static readonly BitSet _COLON_in_var_decl1696 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_id_in_var_decl1698 = new BitSet(new ulong[]{0x1000UL}); + public static readonly BitSet _ASSIGN_in_var_decl1700 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_var_decl1702 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _VARKEY_in_var_decl1723 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_id_in_var_decl1725 = new BitSet(new ulong[]{0x1000UL}); + public static readonly BitSet _ASSIGN_in_var_decl1727 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_var_decl1729 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _FUNCTIONKEY_in_fun_decl1755 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_id_in_fun_decl1757 = new BitSet(new ulong[]{0x80000000000000UL}); + public static readonly BitSet _LPAREN_in_fun_decl1759 = new BitSet(new ulong[]{0x2100000000000UL,0x4800UL}); + public static readonly BitSet _type_fields_in_fun_decl1761 = new BitSet(new ulong[]{0x0UL,0x800UL}); + public static readonly BitSet _RPAREN_in_fun_decl1764 = new BitSet(new ulong[]{0x8010000UL}); + public static readonly BitSet _COLON_in_fun_decl1767 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_id_in_fun_decl1769 = new BitSet(new ulong[]{0x8000000UL}); + public static readonly BitSet _EQ_in_fun_decl1773 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_fun_decl1775 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _type_id_in_type1834 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _array_decl_in_type1859 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _record_decl_in_type1865 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _LKEY_in_record_decl1876 = new BitSet(new ulong[]{0x2100000000000UL,0x4400UL}); + public static readonly BitSet _type_fields_in_record_decl1878 = new BitSet(new ulong[]{0x0UL,0x400UL}); + public static readonly BitSet _RKEY_in_record_decl1881 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _ARRAYKEY_in_array_decl1904 = new BitSet(new ulong[]{0x0UL,0x1UL}); + public static readonly BitSet _OFKEY_in_array_decl1906 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_id_in_array_decl1908 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _type_field_in_type_fields1931 = new BitSet(new ulong[]{0x20002UL}); + public static readonly BitSet _COMMA_in_type_fields1934 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_field_in_type_fields1936 = new BitSet(new ulong[]{0x20002UL}); + public static readonly BitSet _type_id_in_type_field1957 = new BitSet(new ulong[]{0x10000UL}); + public static readonly BitSet _COLON_in_type_field1959 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_id_in_type_field1961 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _MINUS_in_atom1986 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _atom_in_atom1988 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _constant_value_in_atom2013 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _lvalue_in_atom2018 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _funcall_in_atom2023 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _if_then_expr_in_atom2028 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _for_expr_in_atom2033 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _let_expr_in_atom2038 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _LPAREN_in_atom2043 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006800UL}); + public static readonly BitSet _expr_seq_in_atom2045 = new BitSet(new ulong[]{0x0UL,0x800UL}); + public static readonly BitSet _RPAREN_in_atom2047 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _IFKEY_in_if_then_expr2086 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _disjunction_expr_in_if_then_expr2090 = new BitSet(new ulong[]{0x0UL,0x8000UL}); + public static readonly BitSet _THENKEY_in_if_then_expr2092 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_if_then_expr2096 = new BitSet(new ulong[]{0x1000002UL}); + public static readonly BitSet _ELSEKEY_in_if_then_expr2099 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_if_then_expr2103 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _WHILEKEY_in_while_stat2136 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _disjunction_expr_in_while_stat2140 = new BitSet(new ulong[]{0x400000UL}); + public static readonly BitSet _DOKEY_in_while_stat2142 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_while_stat2146 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _LETKEY_in_let_expr2172 = new BitSet(new ulong[]{0x2000000000UL,0x440000UL}); + public static readonly BitSet _decl_in_let_expr2174 = new BitSet(new ulong[]{0x802000000000UL,0x440000UL}); + public static readonly BitSet _INKEY_in_let_expr2177 = new BitSet(new ulong[]{0x4493501002008000UL,0x4006000UL}); + public static readonly BitSet _expr_seq_in_let_expr2179 = new BitSet(new ulong[]{0x2000000UL}); + public static readonly BitSet _ENDKEY_in_let_expr2181 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _type_id_in_lvalue2211 = new BitSet(new ulong[]{0x4000000800002UL}); + public static readonly BitSet _lvalue_access_in_lvalue2213 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _DOT_in_lvalue_access2236 = new BitSet(new ulong[]{0x2100000000000UL,0x4000UL}); + public static readonly BitSet _type_id_in_lvalue_access2238 = new BitSet(new ulong[]{0x4000000800002UL}); + public static readonly BitSet _lvalue_access_in_lvalue_access2240 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _LBRACKET_in_lvalue_access2269 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _disjunction_expr_in_lvalue_access2271 = new BitSet(new ulong[]{0x0UL,0x80UL}); + public static readonly BitSet _RBRACKET_in_lvalue_access2273 = new BitSet(new ulong[]{0x4000000800002UL}); + public static readonly BitSet _lvalue_access_in_lvalue_access2275 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _type_id_in_funcall2301 = new BitSet(new ulong[]{0x80000000000000UL}); + public static readonly BitSet _LPAREN_in_funcall2303 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006800UL}); + public static readonly BitSet _arg_list_in_funcall2305 = new BitSet(new ulong[]{0x0UL,0x800UL}); + public static readonly BitSet _RPAREN_in_funcall2308 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _expr_in_expr_seq2334 = new BitSet(new ulong[]{0x2UL,0x1000UL}); + public static readonly BitSet _SEMI_in_expr_seq2337 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_expr_seq2339 = new BitSet(new ulong[]{0x2UL,0x1000UL}); + public static readonly BitSet _expr_in_arg_list2381 = new BitSet(new ulong[]{0x20002UL}); + public static readonly BitSet _COMMA_in_arg_list2384 = new BitSet(new ulong[]{0x4493501000008000UL,0x4006000UL}); + public static readonly BitSet _expr_in_arg_list2386 = new BitSet(new ulong[]{0x20002UL}); + public static readonly BitSet _ID_in_synpred1_tiger1172 = new BitSet(new ulong[]{0x4000000000000UL}); + public static readonly BitSet _LBRACKET_in_synpred1_tiger1174 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _disjunction_expr_in_synpred1_tiger1176 = new BitSet(new ulong[]{0x0UL,0x80UL}); + public static readonly BitSet _RBRACKET_in_synpred1_tiger1178 = new BitSet(new ulong[]{0x0UL,0x1UL}); + public static readonly BitSet _OFKEY_in_synpred1_tiger1180 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _lvalue_in_synpred2_tiger1191 = new BitSet(new ulong[]{0x1000UL}); + public static readonly BitSet _ASSIGN_in_synpred2_tiger1193 = new BitSet(new ulong[]{0x2UL}); + public static readonly BitSet _ID_in_synpred3_tiger1279 = new BitSet(new ulong[]{0x4000000000000UL}); + public static readonly BitSet _LBRACKET_in_synpred3_tiger1281 = new BitSet(new ulong[]{0x4493501000000000UL,0x6000UL}); + public static readonly BitSet _disjunction_expr_in_synpred3_tiger1283 = new BitSet(new ulong[]{0x0UL,0x80UL}); + public static readonly BitSet _RBRACKET_in_synpred3_tiger1285 = new BitSet(new ulong[]{0x0UL,0x1UL}); + public static readonly BitSet _OFKEY_in_synpred3_tiger1287 = new BitSet(new ulong[]{0x2UL}); + } + #endregion Follow sets +} + +} // namespace YATC.Grammar diff --git a/LICENSE b/LICENSE index c92daee..340d026 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Juan Carlos Pujol Mainegra +Copyright (C) 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 diff --git a/README.md b/README.md new file mode 100644 index 0000000..016c3a7 --- /dev/null +++ b/README.md @@ -0,0 +1,502 @@ +TL;DR +===== + +- **YATC** (Yet Another Tiger Compiler) is a **Tiger** compiler that generates +**.Net framework** managed binaries. + +- YATC was made in 2014 as part of an undergrad Computer Science project by +**Damian Valdés Santiago** and **Juan Carlos Pujol Mainegra**. + +- **Tiger** is a relatively simple and imperative language that features +nested functions, records, arrays, integral variables and strings. + +- Tiger was defined by **Andrew Appel** in 1998 for *Modern Compiler +Implementation in Java* (Cambridge University Press, 1998) + +- This report will explain the architecture and implementation of a Tiger +compiler using **ANTLR 3.3.4** for the grammar definition, **C\# 5.0** in .Net +Framework 4.5 for the construction of the Abstract Syntax Tree (AST) and the +Dynamic Language Runtime (DLR) for the generation of the CIL/MSIL (Common +Intermediary Language/Microsoft Intermediary Language) code. + +- **YATC** se presenta *tal cual* y no es mantenido de ninguna forma por sus +autores. + +Resumen +------- + +- **YATC** (Yet Another Tiger Compiler) es un compilador de **Tiger** que +genera binarios gestionados para **.Net framework**. + +- YATC fue realizado en 2014 como parte de un proyecto de pregrado de Ciencias +de la Computación por **Damian Valdés Santiago** y **Juan Carlos Pujol +Mainegra**. + +- **Tiger** es un lenguaje relativamente sencillo e imperativo con +funciones anidadas, records, arrays y variables enteras y de tipo cadena +*string*. + +- Tiger fue definido por **Andrew Appel** en 1998 para *Modern Compiler +Implementation in Java* (Cambridge University Press, 1998) + +- En este informe se explicará la arquitectura e implementación de un +compilador para el lenguaje Tiger usando **ANTLR 3.3.4** para la definición de +la gramática, **C\# 5.0** en .Net Framework 4.5 para la construcción del +*Árbol de Sintaxis Abstracta* (AST) y *Dynamic Language Runtime* (DLR) para la +generación de código CIL/MSIL (Common Intermediary Language/Microsoft +Intermediary Language). + +- **YATC** se presenta *tal cual* y no es mantenido de ninguna forma por sus +autores. + +License +======= +Yet Another Tiger Compiler (YATC) + +Copyright (C) 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. + +Sobre el proceso de compilación +=============================== + +YATC se inscribe en el clásico proceso para compilar un programa, +dividiendo el mismo en cuatro fases en relación de dependencia: + +- **Análisis Lexicográfico**: identifica subsecuencias de caracteres + significativas separando el flujo de entrada en estructuras lógicas + llamadas *tokens*. Tokens podrían ser identificadores, palabras + claves, operaciones, etc. del lenguaje que se desea implementar. La + componente de software que realiza esta operación se llama *lexer*. + En resumen, el lexer transforma una cadena de caracteres en una + secuencia de tokens. + +- **Análisis sintáctico**: garantiza que la secuencia de tokens tenga + un sentido según las especificaciones del lenguaje, construyendo un + árbol de derivación (DT), que es una representación de las + secuencias de derivaciones de la gramática, para obtener un programa + en Tiger. La componente de software que realiza esta operación se + llama *parser* En resumen, el parser recibe como entrada una + secuencia de tokens y emite un AST como resultado del proceso. + +- **Análisis o chequeo semántico**: verifica que en el lenguaje se + tengan sentencias con sentido obteniéndose un AST. En resumen, se + transforma de un DT a un AST. + +- **Generación de código**: el AST se convierte en un árbol de + sintaxis concreta y se genera código para las instrucciones del + programa en cuestión. + +#### + +Cuando se compila un programa en Tiger se intenta transformar el mismo +en una secuencia de tokens válida para Tiger, de lo contrario se produce +un error sintáctico. Luego, se construye el AST correspondiente según la +jerarquía de clases implementadas y el patrón *TreeAdaptor* de ANTLR que +conecta la fase anterior con la actual (chequeo semántico). Se verifica +que no existan problemas y se pasa a la generación de código. De lo +contrario se reporta error semántico y se detiene el proceso de +compilación. + +Herramientas para la implementación +=================================== + +En la implementación de YATC se utilizaron los siguientes softwares y +lenguajes: + +- ANTLR, ANTLWorks y JRE para la definición de la gramática de Tiger + (entiéndase reglas del lexer y del parser), su prueba y proceso de + *debug* para la detección de fallas. + +- Lenguaje .NET C\# en Microsoft Visual Studio 2012 para la jerarquía + de nodos del AST, la realización del chequeo semántico y la + generación de código a través de DLR cuya elección se justificará + más adelante. + +- PeVerify suministrado por el SDK de .Net para la corrección del + ensamblado. + +- TigerTester 1.2 para la realización de pruebas. + +Análisis lexicográfico y sintáctico +=================================== + +Comentarios anidados +-------------------- + +Para lograr el anidamiento de los comentarios, primero se crearon las +reglas del lexer que se muestran a continuación continuación: + +```antlr +fragment BEGIN_COMMENT : '/*'; +fragment END_COMMENT : '*/' ; +COMMENTARY : BEGIN_COMMENT ( options {greedy=false;} : COMMENTARY | . )*  +       END_COMMENT {$channel = Hidden;}; +``` + +Esta regla es engañosa: al probar un código con comentarios anidados +como el que se muestra no se produce error (lo cual es correcto), sin +embargo al crear un código con comentarios anidados y desbalanceados, no +se produce tampoco error y esto sí es incorrecto desde el punto de vista +sintáctico. + +```antlr + /* Comment1 /* Comment2 */ Comment3 */ +``` + +El comportamiento por defecto de ANTLR al intentar realizar *match* a +una secuencia es consumirla entera. En ocasiones (como la que se +discute) esto no se desea. Este propósito se logra con *options +{greedy=false;}*. El operador *wildcard* ($\cdot$) representa a +cualquier caracter y por tanto, aunque se coloque en la regla `options +{greedy=false;} : COMMENTARY | $\cdot$`, ANTLR no es capaz de +diferenciar que el `COMMENTARY` no debe estar incluido en lo reconocido +por el operador *wildcard*. + +Luego de notar estos errores se redefinen las reglas, obligando a que se +consuman caracteres hasta encontrar un bloque de comentarios seguido de +cualquier secuencia de caracteres. + +```antlr +COMMENTARY : BEGIN_COMMENT ( options {greedy=false;} : . )*  +       (COMMENTARY ( options {greedy=false;} : . )* )*  +       END_COMMENT {$channel = Hidden;} +``` + +Los programa vacíos también son programas +----------------------------------------- + +Un programa en Tiger es una expresión. Un programa que no tenga código +escrito también debe reconocerse y no debe presentar ningún tipo de +error. Esto se logra permitiendo que la regla principal, que produce una +expresión, permita que esta no esté a través del operador el operador +$?$. + + +```antlr +public a_program : expr ? EOF; +``` + +`a = b = c` es ilegal +--------------------- + +Sea la siguiente regla del parser: + +```antlr +relational_expr : arith_expr ((EQ | NOTEQ | GT | LT | GTEQ | LTEQ ) arith_expr)?; +``` + +El operador `?` al final de la regla le da la no asociatividad requerida +a los operadores de comparación (notar que en `arith_expr` y +`term_expr` se usa `*` para anidar estas expresiones en una lista). Con +esta regla no se permite `a = b = c`, pero si `a = (b = c)` como está +especificado. + +Ayudando al chequeo semántico del for +------------------------------------- + +Según las especificaciones del lenguaje Tiger, en un for solo se pueden +evaluar condiciones que retornen valor, por ello se exige en la regla +correspondiente que la primera y segunda expresiones sean +`disjunction_expr`. + +```antlr +for_expr : FORKEY ID ASSIGN disjunction_expr TOKEY disjunction_expr DOKEY expr; +``` + +Reescritura de reglas +--------------------- + +La mayoría de las reglas del parser se reescriben creando nodos +“ficticios” en la sección tokens que se usarán para generar nodos +homólogos del AST a través del TreeAdaptor. Un ejemplo representativo es +la creación de un token para el operador de negación (menos unario). +Esto permite además eliminar del DT del programa, tokens innecesarios +para la próxima fase, como los paréntesis, las palabras claves, las +comas, los punto y coma, etc. + +Análisis semántico +================== + +Jerarquía de nodos del AST +-------------------------- + +Para que el TreeAdaptor funcione correctamente, se crean las clases +correspondientes a los nodos que desean comprobarse semánticamente. Cada +nodo tiene, además de sus propiedades estructurales, dos métodos + +```csharp +public abstract void CheckSemantics(TigerScope scope, Report report); +internal abstract void GenerateCode(ModuleBuilder moduleBuilder); +``` + +El primero (fundamental en esta fase) chequea la semántica del nodo en +cuestión, siguiendo un patrón de gramática atributada: un nodo está bien +si sus hijos lo están y la información brindada por sus hijos o hermanos +en la jerarquía no produce error en su funcionamiento. Estas +informaciones se modelan a través de las clases herederas de +`TigerInfo`, que dejan información conectada para la generación de +código, p.e *bindings* de variables, información relativa a la funciones +(nombre, tipo y cantidad de parámetros), etc. + +Notar que el nodo `UnknownNode` se usa para homologar tokens que, si +bien no introducen error en el chequeo semántico, ayudan en la +comprensión y organización del AST. Ejemplos de token que se mapean como +UnknownNode son `FIELDS_INST`, `PARAM_DECL`, `FUN_TYPE_WRAPPER`, +`DECL_BLOCK` y `ARGS_FIELDS`. + +Scope +----- + +Al usar una variable, un `type` o una función, ¿cómo se sabe si fueron +declaradas antes? Esta información se obtiene de la clase `TigerScope` +que almacena nombres, con sus respectivos objetos, al que se refieren +(variables, *types* o funciones) como una tabla de símbolos. Además, +esta clase permite, mediante un árbol de scopes, anidar funciones y +expresiones `let`, de forma que solo pueda tenerse acceso a las +variables o funciones que están declaradas en ese ámbito o en el ámbito +del nodo padre. Esta clase además se encarga del binding de las +variables. Esta estructura permite que, en caso de que en un scope +interno se cree un `type` o variable de igual nombre que un `type` o +variable de un scope ancestro del actual, entonces se reescriba el valor +antiguo del `type` o variable por el nuevo y se lanzará una advertencia. + +Nil +--- + +En el chequeo semántico de la expresión `if cond_expr then then_expr +else else_expr` se realizan las siguientes comprobaciones. Se realiza +el chequeo semántico de `cond_expr` y luego el de `then_expr`. Si +ambas expresiones están correctas se comprueba que la `cond_expr` tenga +algún valor (no sea `void`) y luego se comprueba que este valor sea +entero. De lo contrario se lanzan errores. En el caso que exista parte +`else` el chequeo es más arduo. Primero se chequea que el nodo +`else_expr` esté correcto. Luego se verifica que el tipo de +`else_expr` sea asignable, o sea, `int`, `string`, `record`, `array`. +De lo contrario, se reporta error. En este punto es donde se chequean +los casos críticos del `nil` expuestos en las especificaciones de Tiger. + +Secuencia de declaraciones de tipo +---------------------------------- + +La construcción y verificación de las secuencias de declaraciones de +tipos dentro de un `let` se realiza mediante tres pasadas a cada uno de +los nodos hijos de cada una de ellas, dígase a los `TypeDeclNode` que +están contenidos dentro de cada `TypeDeclSeqNode`, encargado de agrupar +las mismas. Esto se consigue mediante la regla del parser + +```antlr +decl : type_decl+ | var_decl | fun_decl+; +``` + +Esta regla está contenida dentro de un iterador + **EBNF** (*Extended +Backus-Naur Form*), leyéndose finalmente + +```antlr +let_expr : LETKEY decl+ INKEY expr_seq ENDKEY; +``` + +Aunque esta última pareja constituya una ambigüedad, se usa a propósito +para realizar dicha agrupación, de forma análoga a la selección de a qué +`if` pertenece un determinado `else`, esto es, al de mayor anidamiento. +Esto facilita sobremanera cualquier operación posterior que se realice +sobre los conjuntos de declaraciones, ya sean de tipos o de funciones. +Las variables se tratan como conjuntos *singleton*. + +Dada una declaración de tipo + +```antlr +type_decl : TYPEKEY ID EQ type; +``` + +se le dice parte izquierda o cabeza al token ID, que corresponde al +nombre del tipo que se quiere declarar. La parte derecha corresponde a +la regla `type`, que puede ser `type_id`, `array_decl` o +`record_decl`. + +Los pasos son los siguientes: + +1. Se agregan las cabezas de los tipos, es decir, la parte izquierda de +la declaración de cada uno de ellos, con el sólo propósito de comprobar +que no exista una redeclaración dentro de una secuencia, o de forma +local y global, agregándolo a una estructura que contiene cada +`TypeDeclNode` como llave del nombre del tipo. Este paso incluye +detectar renombramientos de los nombres de los tipos primitivos como +tipos de usuario, esto es, no cambiar a `int` o `string`, por ejemplo. +En este paso se llama al `CheckHeader(TigerScope scope, Report report, +string name)` de cada hijo. + +2. Para detectar eventuales ciclos es necesario construir un grafo +dirigido $G \langle V,E \rangle$ con + + $$V = \{ \text{nodos de declaración de tipos} \}$$ + + $$E = \{ (u,v) | ParteIzquierda(u) \and BaseType(u, v) \in { Alias V Array } \and ParteDerecha(v), u, v \in V \}$$ + + Dicha construcción asegura que las aristas se establezcan sólo entre + nodos de declaraciones de tipos que estén conectados como parte + izquierda y derecha del *statement*, que sea de base `Array` o `Alias`, es + decir, un tipo cuyo tipo, valga la redundancia, sea alguno de los + anteriores. Estos se agregan a una estructura + `Dictionary>` + donde `Node` es una representación de nodos en un + grafo, con soporte para realizar operaciones de orden topológico además + de detectar ciclos y su composición. Esta estructura permite conectar + los `TypeDeclNode` en el grafo con aquellos otros de la secuencia que se + requiera, y evitar repetir nodos en el grafo que correspondan a una + misma declaración. Esto podría suceder dado que un mismo tipo puede + estar varias veces en parte derecha, y a lo sumo una vez en parte + izquierda si se ha llegado a este paso (el anterior elimina que esté más + de una vez). De esta forma no se tenderá una arista entre un tipo + `aliasInt` que sea alias de `int`, dado que la parte derecha no estará + en primer lugar en la secuencia, y por tanto no puede referenciar hacia + adelante, de forma que no hay peligro de recursión cíclica. + +3. Al grafo construido se le realiza un DFS (*Depth-First Search*) con +marcado de nodos, en los que se detecta una arista back-edge, o de +retroceso, si se en la navegación se llega a un nodo marcado como gris +\[ver *Intro To Algorithms*, Cormen et al., alrededor de la 614\]. La prueba +del Teorema 22.12 acompaña el resultado. Si existe un ciclo se detecta +sus nodos componentes y se imprime. De no existir, se recorre el orden +topológico de los nodos resultantes, cuyo valor contenido son las +declaraciones de nodos, y se llama a `CheckSemantics` de cada uno en +dicho orden. La generación de código también se realiza por dicho orden. +Esto evita tener que realizar múltiples búsquedas si para construir +finalmente un tipo, aunque se conozca que está correcto. + +#### + +El último paso, detectar un ciclo, y después navegar por el orden +topológico dado, devuelto en forma de lista enlazada, es vital para la +realización de las operaciones de construcción de tipos, que se realizan +de forma transparente para los hijos, los cuales no requieren búsquedas +adicionales para la determinación completa de los mismos, como se había +dicho. Para ellos se habilita que los nodos que así lo requieran no +contengan una referencia directa al tipo, dado que en el momento de +declaración y comprobación semántica, aunque este sea correcto, puede no +estar determinado, sencillamente porque es el tipo de un record. Uno de +estos casos se analiza a continuación. + +#### + +Supongamos que deseamos comprobar y construir los tipos del siguiente +programa: + +```antlr +let + type a = b +  type b = { x: c } +  type c = a +in +end +``` + +El programa está correcto, dado que los tipos `a`, `b` y `c` están bien +determinados por un ciclo que pasa por al menos un tipo record (`b`). El +tipo básico de `a` es el mismo que el de `c`, que es alias. El orden +topológico podrá arrojar una sola forma de navegarlo para la +construcción. Sea esta $b \rightarrow a \rightarrow c$. Al comprobar +semánticamente a `b` el tipo no está bien determinado, dado que tiene un +campo `x` de un tipo desconocido `c`, pero se conoce que la declaración +esta correcta, dado que `c` existe y está correcto, por lo que `b` está +bien determinado. Su definición, no obstante, no es completa. Por lo +tanto se almacena una referencia a la referencia a la definición del +mismo, de forma que esta pueda se alterada, es decir se puede completar, +y todos los nodos que dependían de esta queden bien. + +#### + +Finalmente los tipos alias no se analiza semánticamente, es decir, son +indistinguibles las definiciones originales de `a`, `b` y `c`, a efectos +del resto del programa. + +Generación de código +==================== + +La generación de código es el proceso mediante el cual un compilador +convierte la información proveniente de las fases anteriores en código +que puede ser ejecutado por una computadora. La ejecución del código +generado la realiza, en este compilador, el *Common Language Runtime* +(CLR) de la plataforma .NET. El CLR usa una estructura basada en un +modelo de pila para modelar la ejecución de código, así como un lenguaje +ensamblador propio llamado *Intermediate Language* (IL). Nuestro +compilador utiliza una componente de la biblioteca de clase de la +plataforma .NET llamada `System.Reflection.Emit` que permite crear un +ejecutable en .NET y agregarle código según se desee; y para generar +código IL se usa *Dynamic Language Runtime* (DLR). + +¿Por qué usar DLR? +------------------ + +El DLR proporciona servicios para implementar lenguajes dinámicos sobre +el CLR. DLR facilita el desarrollo de lenguajes para ejecutar programas +sobre .NET Framework. Los lenguajes por el tipo del objeto que los +representa en tiempo de ejecución, que se especifica en tiempo de diseño +en un lenguaje estáticamnete tipado como C\#. + +DLR permite a los programadores implementar lexers, parsers, +analizadores semánticos y generadores de código y la generación de +código se realiza de forma declarativa mediante árboles de expresiones +lo que hace más fácil esta etapa. + +Funciones recursivas +-------------------- + +En la generación de código de las secuencias de funciones se realizan +tres etapas. + +1. Se recorren todos las definiciones (`headers`) de las funciones en + la secuencia y se introducen en una lista de `ParameterExpression` + que después se le pasará a la segunda fase. + +2. Por cada llamado a la propia función (recursión) o a otra, se crea + una `Expression` ficticia en el que luego se sustituirá el código + del llamado a la función. + +3. Se recorren las declaraciones de funciones en la secuencia y se le + asigna a la `Expression` ficticia el código del llamado a la función + correspondiente. + +Para más información +==================== + +- Edwards, Stephen - *Tiger Language Reference Manual*, Columbia + University. + +- Appel, Andrew and Ginsburg, Maia - *Modern Compiler Implementation + in C*, Press Syndicate of the University of Cambridge, 1998. + +- Parr, Terrence - *The Definitive ANTLR Reference*, The Pragmatic + Programmers, May 2007. + +- Parr, Terrence - *The Definitive ANTLR 4 Reference*, The Pragmatic + Programmers, Jan 2013. + +- Parr, Terrence - *Language Implementation Patterns*, The Pragmatic + Programmers, 2010. + +- Wu, Chaur - *Pro DLR in .NET 4*, Apress, 2010. + +- Chiles, Bill - *Expression Trees v2 Spec* (DRAFT). + +- Cormen, Thomas *et al.* - *Introduction to algorithms*, 3rd ed, + Massachusetts Institute of Technology, 2009. + +- [https://docs.microsoft.com/](https://docs.microsoft.com/ "MSDN") + diff --git a/YATC.Compiler/App.config b/YATC.Compiler/App.config new file mode 100644 index 0000000..8e15646 --- /dev/null +++ b/YATC.Compiler/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/YATC.Compiler/Program.cs b/YATC.Compiler/Program.cs new file mode 100644 index 0000000..2435ff4 --- /dev/null +++ b/YATC.Compiler/Program.cs @@ -0,0 +1,253 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using Antlr.Runtime.Tree; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using YATC.ASTNodes; +using YATC.Grammar; + +namespace YATC.Compiler +{ + static class Program + { + enum ErrorKind { Fatal, Syntax, Semantic } + + public static readonly string FileName = Assembly.GetExecutingAssembly().GetName().Name; + public const string Name = "Yet Another Tiger Compiler"; + public const string Copyright = "Copyright D. Valdes Santiago & Juan C. Pujol Mainegra (c) 2013-2014"; + public const string ShortName = "YATC"; + + private static TextWriterTraceListener _textListener = null; + private const string MessageFormatHead = "({0}, {1}): "; + private const string MessageFormatBody = "{0} {1}: {2}"; + + private const string Usage = + "Usage :" + + "\ttiger.exe path_to_program_file.tig" + ; + + static void Write(int line, int column, ErrorKind errorKind, Level level, string message, params object[] objects) + { + string msg = string.Format(message, objects); + string wrappedMsg = string.Format(MessageFormatHead, line, column); + Trace.Write(wrappedMsg); + + ConsoleColor lastColor = Console.ForegroundColor; + switch (level) + { + case Level.Info: + Console.ForegroundColor = ConsoleColor.Gray; + break; + case Level.Warning: + Console.ForegroundColor = ConsoleColor.White; + break; + case Level.Error: + Console.ForegroundColor = ConsoleColor.Yellow; + break; + } + + wrappedMsg = string.Format(MessageFormatBody, errorKind, level, msg); + Trace.WriteLine(wrappedMsg); + + Console.ForegroundColor = lastColor; + } + + static void PrintUsage() + { + Trace.WriteLine(Usage); + } + + static void PrintWelcome() + { + Trace.WriteLine(Name + " version " + Assembly.GetExecutingAssembly().GetName().Version + '\n' + Copyright); + } + + static void PrintBlank() + { + Trace.WriteLine(string.Empty); + } + + static void Flush() + { + Trace.Flush(); + Debug.Flush(); + if (_textListener != null) + { + _textListener.Flush(); + _textListener.Close(); + } + } + + static int ExitBad(string programName) + { + Flush(); + Write(0, 0, ErrorKind.Fatal, Level.Error, + "Could not generate executable for program '{0}': One or more errors were found.", + programName); + PrintBlank(); + return 1; + } + + static int Main(string[] args) + { + try + { + _textListener = new TextWriterTraceListener(FileName + ".log"); + Trace.Listeners.Add(_textListener); + + _textListener.WriteLine(string.Empty.PadLeft(79, '=')); + _textListener.WriteLine(string.Format("Tracing log for program '{0}' on '{1}'.", + args.Length >= 1 ? args[0] : "not specified", DateTime.Now.ToString(CultureInfo.InvariantCulture))); +#if DEBUG + _textListener.WriteLine("Debug mode is ON."); +#else + _textListener.WriteLine("Debug mode is OFF."); +#endif + _textListener.WriteLine(string.Empty.PadLeft(79, '=')); + } + catch + { + } + Trace.Listeners.Add(new ConsoleTraceListener()); + + PrintWelcome(); + PrintBlank(); + + if (args.Length != 1) + { + Write(0, 0, ErrorKind.Fatal, Level.Error, + "Wrong number of argument: expecting one and {0} found.", + args.Length); + return ExitBad(string.Empty); + } + + ProgramNode programNode; + try + { + ICharStream charStream = new ANTLRFileStream(args[0]); + var lexer = new tigerLexer(charStream); + var tokenStream = new CommonTokenStream(lexer); + var parser = new tigerParser(tokenStream) + { + TraceDestination = Console.Out, + TreeAdaptor = new TigerTreeAdaptor() + }; + + programNode = parser.a_program().Tree as ProgramNode; + } + catch (ParsingException e) + { + Write(e.RecognitionError.Line, e.RecognitionError.CharPositionInLine, + ErrorKind.Syntax, Level.Error, "Parsing input file: '{0}'", e.Message); + return ExitBad(args[0]); + } + catch (DirectoryNotFoundException) + { + Write(0, 0, + ErrorKind.Fatal, Level.Error, "Directory '{0}' could not be found.", + Path.GetDirectoryName(args[0])); + return ExitBad(args[0]); + } + catch (FileNotFoundException fileNotFound) + { + Write(0, 0, + ErrorKind.Fatal, Level.Error, "File '{0}' could not be found.", + fileNotFound.FileName); + return ExitBad(args[0]); + } + + if (programNode == null) + return ExitBad(args[0]); + + Print(programNode); + programNode.CheckSemantics(); + + foreach (var item in programNode.Report) + { + Write(item.Line, item.Column, ErrorKind.Semantic, item.Level, item.Text); + } + + if (programNode.Report.Level != Level.Error) + { + string name = Path.HasExtension(args[0]) ? + Path.GetFileNameWithoutExtension(args[0]) : + args[0]; + + string fileName = Path.HasExtension(args[0]) + ? Path.ChangeExtension(Path.GetFileName(args[0]), "exe") + : args[0] + ".exe"; + + string directory = Path.GetDirectoryName(args[0]); + + AssemblyBuilder programAssembly = programNode.GenerateCode( + name, + fileName, + directory == string.Empty ? null : directory); + programAssembly.Save(fileName); + } + else + return ExitBad(args[0]); + + Flush(); + PrintBlank(); + return programNode.Report.Level != Level.Error ? 0 : 1; + } + + static void Print(CommonTree tree) + { +#if DEBUG + Debug.IndentSize = 4; + foreach (var child in PrintTree(tree)) + { + Debug.IndentLevel = child.Item2; + Debug.WriteLine( + /*(child.Item1.ChildCount != 0 ? "+ " : " ") +*/ + child.Item1.Text + "\t" + child.Item1.GetType() + ); + } + Debug.IndentLevel = 0; +#endif + } + + static IEnumerable> PrintTree(BaseTree tree, int level = 0) + { + yield return new Tuple(tree, level); + if (tree.Children == null) + yield break; + + foreach (var child in tree.Children.Cast()) + foreach (var grandChild in PrintTree(child, level + 1)) + yield return grandChild; + } + } +} diff --git a/YATC.Compiler/Properties/AssemblyInfo.cs b/YATC.Compiler/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..de22dc4 --- /dev/null +++ b/YATC.Compiler/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("YATC")] +[assembly: AssemblyDescription("Yet Another Tiger Compiler")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("YATC")] +[assembly: AssemblyCopyright("Copyright Damian Valdes Santiago & Juan Carlos Pujol Mainegra © 2013-2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f8cf7ad4-d691-4fc6-8302-a2216c6a8b77")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/YATC.Compiler/Tiger.csproj b/YATC.Compiler/Tiger.csproj new file mode 100644 index 0000000..a7e4f49 --- /dev/null +++ b/YATC.Compiler/Tiger.csproj @@ -0,0 +1,67 @@ + + + + + Debug + AnyCPU + {8B1FA297-B497-4F06-A6AE-87D73920AA57} + Exe + Properties + YATC.Compiler + tiger + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\Antlr3.Runtime.dll + + + + + + + + + + + + + + + + + + + {d62da087-4724-49a3-91b5-83689f442747} + YATC + + + + + \ No newline at end of file diff --git a/YATC.Compiler/Tiger.idc b/YATC.Compiler/Tiger.idc new file mode 100644 index 0000000..9efd5bc --- /dev/null +++ b/YATC.Compiler/Tiger.idc @@ -0,0 +1 @@ + diff --git a/YATC.sln b/YATC.sln new file mode 100644 index 0000000..6097d16 --- /dev/null +++ b/YATC.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YATC", "YATC\YATC.csproj", "{D62DA087-4724-49A3-91B5-83689F442747}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tiger", "YATC.Compiler\Tiger.csproj", "{8B1FA297-B497-4F06-A6AE-87D73920AA57}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D62DA087-4724-49A3-91B5-83689F442747}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D62DA087-4724-49A3-91B5-83689F442747}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D62DA087-4724-49A3-91B5-83689F442747}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D62DA087-4724-49A3-91B5-83689F442747}.Release|Any CPU.Build.0 = Release|Any CPU + {8B1FA297-B497-4F06-A6AE-87D73920AA57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B1FA297-B497-4F06-A6AE-87D73920AA57}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B1FA297-B497-4F06-A6AE-87D73920AA57}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B1FA297-B497-4F06-A6AE-87D73920AA57}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/AliasDeclNode.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/AliasDeclNode.cs new file mode 100644 index 0000000..59b3a5b --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/AliasDeclNode.cs @@ -0,0 +1,69 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class AliasDeclNode : DeclarationNode + { + public AliasDeclNode(IToken payload) + : base(payload) + { + } + + public TypeNode TypeNode { get { return (TypeNode)TigerChildren[0]; } } + + public override bool CheckHeader(TigerScope scope, Report report, string name) + { + this.TigerTypeInfo = new TigerTypeInfo(name, new TigerTypeHolder(), false); + scope.Add(this.TigerTypeInfo); + return true; + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + // type is an alias of another type, then follow. + TigerTypeInfo aliasTo = scope.FindTypeInfo(this.TypeNode.Name, false); + + if (aliasTo == null) + { + report.AddError(this.Line, this.Column, "Alias to undeclared type: '{0}'.", this.TypeNode.Name); + this.IsOK = false; + return; + } + + this.TigerTypeInfo.Holder.TigerType = aliasTo.Holder.TigerType; + this.IsOK = true; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + // do nothing + } + } +} diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/ArrayDeclNode.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/ArrayDeclNode.cs new file mode 100644 index 0000000..c81ffa8 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/ArrayDeclNode.cs @@ -0,0 +1,70 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + internal class ArrayDeclNode: DeclarationNode + { + public ArrayDeclNode(IToken payload) + : base(payload) + { + } + + private ArrayType _arrayType; + public TypeNode ElementTypeNode { get { return (TypeNode)TigerChildren[0]; } } + + public override bool CheckHeader(TigerScope scope, Report report, string name) + { + this.TigerTypeInfo = new TigerTypeInfo(name, new TigerTypeHolder(), false); + scope.Add(this.TigerTypeInfo); + return true; + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + TigerTypeInfo elementTigerTypeInfo = scope.FindTypeInfo(this.ElementTypeNode.Name, false); + + if (elementTigerTypeInfo == null) + { + report.AddError(this.Line, this.Column, "Undeclared type: array element '{0}'.", this.ElementTypeNode.Name); + this.IsOK = false; + return; + } + + + this.TigerTypeInfo.Holder.TigerType = _arrayType = new ArrayType(this.TigerTypeInfo.Name, elementTigerTypeInfo.Holder); + this.IsOK = true; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + _arrayType.CLRType = _arrayType.ElementTypeHolder.TigerType.GetCLRType().MakeArrayType(); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/DeclarationNode.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/DeclarationNode.cs new file mode 100644 index 0000000..bc65328 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/DeclarationNode.cs @@ -0,0 +1,50 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + abstract class DeclarationNode : LocalNode + { + protected DeclarationNode(IToken payload) + : base(payload) + { + } + + public TigerTypeInfo TigerTypeInfo { get; protected set; } + + public virtual bool CheckHeader(TigerScope scope, Report report, string name) + { + return true; + } + + /// + /// Por defecto es false + /// + public bool IsOK { get; set; } + } +} diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/FunDeclSeqNode.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/FunDeclSeqNode.cs new file mode 100644 index 0000000..900d396 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/FunDeclSeqNode.cs @@ -0,0 +1,154 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + internal class FunDeclSeqNode : DeclarationNode + { + public FunDeclSeqNode(IToken payload) + : base(payload) + { + } + + public FunDeclNode[] FunDeclNodes { get { return TigerChildren.Cast().ToArray(); } } + + public ParameterExpression[] FunctionClousures { get; private set; } + public Expression[] FunctionAssigns { get; private set; } + + public override void CheckSemantics(TigerScope scope, Report report) + { + for (int index = 0; index < FunDeclNodes.Length; index++) + { + var funDeclNode = FunDeclNodes[index]; + + if (scope.CanFindFunVarInfo(funDeclNode.Name, true)) + { + report.AddError(this.Line, this.Column, + "Redeclared local function or variable name: '{0}'.", funDeclNode.Name); + this.IsOK = false; + return; + } + + FunctionInfo outerFunction = scope.FindFunctionInfo(funDeclNode.Name, false); + if (outerFunction != null) + if (outerFunction.IsStandard) + { + report.AddError(this.Line, this.Column, + "Redeclared standard function or procedure: '{0}'.", funDeclNode.Name); + this.IsOK = false; + return; + } + else + report.AddWarning(this.Line, this.Column, + "Function name hides outer scope variable or function: '{0}'.", + funDeclNode.Name); + + // Checking not repiting parameter names + var parameterNames = new HashSet(); + var parameterInfo = new VariableInfo[funDeclNode.Params.Length]; + for (int i = 0; i < parameterInfo.Length; i++) + { + var parameter = funDeclNode.Params[i]; + if (!parameterNames.Add(parameter.Name)) + { + report.AddError(this.Line, this.Column, + "Redeclared function or procedure formal parameter name: '{0}'.", parameter.Name); + this.IsOK = false; + return; + } + + parameter.TypeNode.CheckSemantics(scope, report); + TigerTypeInfo paramInfo = scope.FindTypeInfo(parameter.TypeNode.Name, false); + + if (paramInfo == null) + { + report.AddError(this.Line, this.Column, + "Undeclared type: Function or procedure parameter: " + + "'{0}' of formal parameter '{1}'.", parameter.TypeNode.Name, parameter.Name); + this.IsOK = false; + return; + } + + parameterInfo[i] = new VariableInfo(parameter.Name, paramInfo.Holder, true); + } + + // Checking return type + TigerType returnType; + if (funDeclNode.TypeNode != null) + { + TigerTypeInfo returnInfo = scope.FindTypeInfo(funDeclNode.TypeNode.Name, false); + if (returnInfo == null) + { + report.AddError(this.Line, this.Column, + "Undeclared function or procedure return type: {0}", funDeclNode.TypeNode.Name); + this.IsOK = false; + return; + } + returnType = returnInfo.Holder.TigerType; + } + else + returnType = TigerType.Void; + + var functionInfo = new FunctionInfo(funDeclNode.Name, parameterInfo, new TigerTypeHolder(returnType), false); + scope.Add(functionInfo); + } + + // Checking children + bool areAllOk = true; + foreach (var funDeclNode in FunDeclNodes) + { + funDeclNode.CheckSemantics(scope, report); + if (!funDeclNode.IsOK) + areAllOk = false; + } + + this.IsOK = areAllOk; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + FunctionClousures = new ParameterExpression[this.FunDeclNodes.Length]; + FunctionAssigns = new Expression[this.FunDeclNodes.Length]; + for (int i = 0; i < this.FunDeclNodes.Length; i++) + FunctionClousures[i] = this.FunDeclNodes[i].GenerateHeaderCode(); + + for (int i = 0; i < this.FunDeclNodes.Length; i++) + this.FunDeclNodes[i].GenerateCode(moduleBuilder); + + for (int i = 0; i < this.FunDeclNodes.Length; i++) + FunctionAssigns[i] = Expression.Assign( + this.FunDeclNodes[i].FunctionInfo.LambdaExpression, + this.FunDeclNodes[i].VmExpression + ); + } + } +} \ No newline at end of file diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/FundeclNode.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/FundeclNode.cs new file mode 100644 index 0000000..4964691 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/FundeclNode.cs @@ -0,0 +1,144 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class FunDeclNode : DeclarationNode + { + public FunDeclNode(IToken payload) + : base(payload) + { + } + + public TypeNode IdNode { get { return (TypeNode)TigerChildren[0]; } } + public TypeFieldNode[] Params + { + get { return TigerChildren[1].TigerChildren.Cast().ToArray(); } + } + public TypeNode TypeNode + { + get { return TigerChildren[2].TigerChildren.Length > 0 ? + (TypeNode)TigerChildren[2].TigerChildren[0] : + null; } + } + public ExpressionNode ExpressionBodyNode { get { return (ExpressionNode)TigerChildren[3]; } } + + public string Name { get { return this.IdNode.Name; } } + public FunctionInfo FunctionInfo; + + public override void CheckSemantics(TigerScope scope, Report report) + { + FunctionInfo = scope.FindFunctionInfo(this.Name, true); + + if (FunctionInfo == null) + throw new NullReferenceException(); + + var innerScope = scope.CreateChildScope(); + foreach (var parameterInfo in FunctionInfo.ParameterInfo) + { + if (innerScope.CanFindFunVarInfo(parameterInfo.Name, false)) + report.AddWarning(this.Line, this.Column, + "Parameter name hides outer scope variable or function in '{0}': '{1}'.", + this.Name, parameterInfo.Name); + innerScope.Add(parameterInfo); + } + + this.ExpressionBodyNode.CheckSemantics(innerScope, report); + + // chequeando que el tipo de retorno sea el mismo que el tipo de la expresion, + // no se hace salvedad en el caso de los procedures. + if (!this.ExpressionBodyNode.TigerType.IsAssignableTo(FunctionInfo.Holder.TigerType)) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Function or procedure return and expression types in '{0}': " + + "Expecting '{1}' and '{2}' found.", + this.Name, FunctionInfo.Holder.TigerType.Name, this.ExpressionBodyNode.TigerType.Name); + this.IsOK = false; + return; + } + + this.IsOK = true; + } + + public Type DelegateType; + + internal ParameterExpression GenerateHeaderCode() + { + bool funRets = FunctionInfo.Holder.TigerType.Basetype != BaseType.Void; + + Type[] paramTypes = new Type[this.FunctionInfo.ParameterInfo.Length + (funRets ? 1 : 0)]; + for (int i = 0; i < this.FunctionInfo.ParameterInfo.Length; i++) + paramTypes[i] = this.FunctionInfo.ParameterInfo[i].Holder.TigerType.GetCLRType(); + + if (funRets) + paramTypes[this.Params.Length] = this.FunctionInfo.Holder.TigerType.GetCLRType(); + + DelegateType = funRets + ? Expression.GetFuncType(paramTypes) + : Expression.GetActionType(paramTypes); + + var paramExpr = Expression.Parameter(DelegateType); + + FunctionInfo.LambdaExpression = paramExpr; + return paramExpr; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + var paramsExprs = new ParameterExpression[this.Params.Length]; + for (int i = 0; i < Params.Length; i++) + { + paramsExprs[i] = Expression.Parameter(this.FunctionInfo.ParameterInfo[i].Holder.TigerType.GetCLRType()); + FunctionInfo.ParameterInfo[i].ParameterExpression = paramsExprs[i]; + } + + this.ExpressionBodyNode.GenerateCode(moduleBuilder); + + Expression bodyExpr = this.FunctionInfo.Holder.TigerType.Basetype == BaseType.Void + ? Expression.Block( + this.ExpressionBodyNode.VmExpression, + Expression.Empty() + ) + : (Expression)Expression.Convert( + ExpressionBodyNode.VmExpression, + this.FunctionInfo.Holder.TigerType.GetCLRType() + ); + + this.VmExpression = Expression.Lambda( + //DelegateType, + bodyExpr, + this.Name, + paramsExprs + ); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/Node.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/Node.cs new file mode 100644 index 0000000..a869f28 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/Node.cs @@ -0,0 +1,117 @@ +/* + * 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. + * + */ +using System.Collections.Generic; +using System.Linq; + +namespace YATC.ASTNodes +{ + internal class Node + { + public enum ColorCode + { + White = 0, + Unvisited = 0, + Black = 1, + Done = 1, + Gray = 2, + StillNotDone = 2 + } + + public ColorCode Color { get; private set; } + public Node Parent { get; private set; } + public readonly T Value; + + public Node(T value) + { + this.Value = value; + } + + private readonly LinkedList> _pred = new LinkedList>(); + private readonly LinkedList> _succ = new LinkedList>(); + + public IEnumerable> Pred { get { return _pred; } } + public IEnumerable> Succ { get { return _succ; } } + public IEnumerable> Adj { get { return _pred.Concat(_succ); } } + + public void AddSucc(Node node) { _succ.AddLast(node); } + public void AddPred(Node node) { _pred.AddLast(node); } + + private static Node DFS(IEnumerable> nodes, bool checkCycles, out LinkedList> linkedList) + { + int time = 0; + linkedList = new LinkedList>(); + foreach (var node in nodes.Where(node => node.Color == ColorCode.White)) + { + var cycleEnd = node.Visit(ref time, checkCycles, linkedList); + if (cycleEnd != null) + return cycleEnd; + } + + return null; + } + + private Node Visit(ref int time, bool checkCycles, LinkedList> topologicalSort) + { + this.Color = ColorCode.Gray; + foreach (var node in this.Succ) + { + // by the Proof of Theorem 22.12, page 614, (u,v) is a back edge iff v is Gray + // from Cormen et al. - Introduction To Algorithms, 3rd edition + if (node.Color == ColorCode.Gray && checkCycles) + return this; + + if (node.Color == ColorCode.White) + { + node.Parent = this; + var cycleEnd = node.Visit(ref time, checkCycles, topologicalSort); + if (cycleEnd != null) + return cycleEnd; + } + } + this.Color = ColorCode.Black; + topologicalSort.AddFirst(this); + + return null; + } + + public static Node TopologicalSort(IEnumerable> nodes, out LinkedList> linkedList) + { + return DFS(nodes, true, out linkedList); + } + + public class NodeValueEqualityComparer : IEqualityComparer> + { + public bool Equals(Node x, Node y) + { + return x.Value.Equals(y.Value); + } + + public int GetHashCode(Node obj) + { + return obj.Value.GetHashCode(); + } + } + } +} \ No newline at end of file diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/RecordDeclNode.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/RecordDeclNode.cs new file mode 100644 index 0000000..6c7d8cc --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/RecordDeclNode.cs @@ -0,0 +1,125 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + internal class RecordDeclNode : DeclarationNode + { + public RecordDeclNode(IToken payload) + : base(payload) + { + } + + public TypeFieldNode[] TypeFieldNodes + { + get + { + return TigerChildren.Length > 0 ? TigerChildren.Cast().ToArray() : new TypeFieldNode[] {}; + } + } + + public TypeBuilder TypeBuilder { get; private set; } + + public override bool CheckHeader(TigerScope scope, Report report, string name) + { + this.TigerTypeInfo = new TigerTypeInfo(name, new TigerTypeHolder(), false); + scope.Add(this.TigerTypeInfo); + return true; + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + var hash = new HashSet(); + foreach (var typeFieldNode in this.TypeFieldNodes) + { + typeFieldNode.TypeNode.CheckSemantics(scope, report); + + if (!typeFieldNode.TypeNode.IsOk) + { + this.TigerTypeInfo.Holder.TigerType = TigerType.Error; + this.IsOK = false; + return; + } + + string name = typeFieldNode.IdNode.Name; + if (!hash.Add(name)) + { + report.AddError(this.Line, this.Column, "Redeclared field name: '{0}'.", name); + this.TigerTypeInfo.Holder.TigerType = TigerType.Error; + this.IsOK = false; + return; + } + } + + VariableInfo[] fieldInfos = new VariableInfo[this.TypeFieldNodes.Length]; + + for (int i = 0; i < fieldInfos.Length; i++) + { + TigerTypeInfo fieldTigerTypeInfo = scope.FindTypeInfo(this.TypeFieldNodes[i].TypeNode.Name, false); + if (fieldTigerTypeInfo == null) + { + report.AddError(this.Line, this.Column, "Undeclared field type: '{0}'.", + this.TypeFieldNodes[i].TypeNode.Name); + this.TigerTypeInfo.Holder.TigerType = TigerType.Error; + this.IsOK = false; + return; + } + + fieldInfos[i] = new VariableInfo(this.TypeFieldNodes[i].Name, fieldTigerTypeInfo.Holder, false); + } + + this.TigerTypeInfo.Holder.TigerType = new RecordType(this.TigerTypeInfo.Name, fieldInfos); + this.IsOK = true; + } + + public void GenerateHeaderCode(ModuleBuilder moduleBuilder) + { + string name = string.Format("{0}_{1}", this.TigerTypeInfo.Name, ProgramNode.RecordNumber++); + this.TigerTypeInfo.Holder.TigerType.CLRType = + this.TypeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public); + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + foreach (var variableInfo in ((RecordType)this.TigerTypeInfo.Holder.TigerType).FieldInfos) + { + this.TypeBuilder.DefineField( + variableInfo.Name, + variableInfo.Holder.TigerType.GetCLRType(), + FieldAttributes.Public); + } + + // Finish the type. + this.TigerTypeInfo.Holder.TigerType.CLRType = this.TypeBuilder.CreateType(); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/TypeDeclSeqNode.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/TypeDeclSeqNode.cs new file mode 100644 index 0000000..815ba21 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/TypeDeclSeqNode.cs @@ -0,0 +1,190 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection.Emit; +using System.Text; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + internal class TypeDeclSeqNode : DeclarationNode + { + private LinkedList> _topologicalSort; + + public TypeDeclSeqNode(IToken payload) + : base(payload) + { + } + + public IEnumerable TypeDeclNodes { get { return TigerChildren.Cast(); } } + + /// + /// Por pasos: + /// 1ro : Agregar cabezas de tipos + /// 2do : Construir grafo y revisar orden topologico + /// 3ro : En el orden dado hacer chequeo semantico + /// + /// + /// + public override void CheckSemantics(TigerScope scope, Report report) + { + var checkedNodes = new Dictionary(); + + // 1. agregar cabezas de tipos + foreach (var typeDeclNode in TypeDeclNodes) + { + if (!checkedNodes.ContainsKey(typeDeclNode.Name)) + checkedNodes.Add(typeDeclNode.Name, typeDeclNode); + else + { + report.AddError(this.Line, this.Column, + "Redeclared name in type declaration sequence: '{0}'.", typeDeclNode.Name); + this.IsOK = false; + return; + } + + // chequeamos el header, mayormente por problemas de redeclaracion local + // o global pero de tipos standard + if (!typeDeclNode.CheckHeader(scope, report, string.Empty)) + { + this.IsOK = false; + return; + } + } + + // 2. DAG + + // 2.1 construir grafo + + var graph = new Dictionary>(); + + foreach (var typeDeclNode in TypeDeclNodes) + { + string edgeNameTo = string.Empty; + if (typeDeclNode.IsAliasNode) + edgeNameTo = ((AliasDeclNode)typeDeclNode.DeclarationNode).TypeNode.Name; + else if (typeDeclNode.IsArrayNode) + edgeNameTo = ((ArrayDeclNode)typeDeclNode.DeclarationNode).ElementTypeNode.Name; + + Node thisNode; + if (!graph.TryGetValue(typeDeclNode, out thisNode)) + { + thisNode = new Node(typeDeclNode); + graph.Add(typeDeclNode, thisNode); + } + + if (edgeNameTo == string.Empty) + continue; + + TypeDeclNode edgeTo; + if (checkedNodes.TryGetValue(edgeNameTo, out edgeTo)) + { + Node node; + if (!graph.TryGetValue(edgeTo, out node)) + { + node = new Node(edgeTo); + graph.Add(edgeTo, node); + } + + node.AddSucc(thisNode); + } + } + + // 2.2 obtener orden topologico (detectando ciclos) + +#if DEBUG + foreach (var edge in graph.Values) + { + var from = edge.Succ.Any() ? edge.Succ.FirstOrDefault().Value.IdNode.ToString() : ""; + var to = edge.Value.IdNode; + Debug.WriteLine("{0} -> {1}", from, to); + } +#endif + + var cycleEnd = Node.TopologicalSort(graph.Values, out _topologicalSort); + +#if DEBUG + foreach (var node in _topologicalSort) + Debug.WriteLine("Adding {0}", node.Value.IdNode); +#endif + + if (cycleEnd != null) + { + var sb = new StringBuilder(); + for (var current = cycleEnd; current != null; current = current.Parent) + sb.Append(current.Value.IdNode.Name + " -> "); + + sb.Append(cycleEnd.Value.IdNode.Name); + report.AddError(this.Line, this.Column, + "Undetected record in recursive type declaration sequence. Cycle definition is: {0}", + sb.ToString()); + this.IsOK = false; + return; + } + + // 3. chequear semantica de los nodos en el orden topologico + foreach (var node in _topologicalSort) + { + Debug.WriteLine("Checking {0}", node.Value.IdNode); + node.Value.CheckSemantics(scope, report); + if (!node.Value.IsOK) + { + this.IsOK = false; + return; + } + } + + //foreach (var node in linkedList) + //{ + // node. + //} + + this.IsOK = true; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + // records go first + + IEnumerable recordDeclNodes = + _topologicalSort.Select(x => x.Value). + Where(x => x.DeclarationNode is RecordDeclNode). + Select(x => x.DeclarationNode). + Cast(); + + foreach (var recordDeclNode in recordDeclNodes) + recordDeclNode.GenerateHeaderCode(moduleBuilder); + + // everything + + foreach (var declarationNode in _topologicalSort.Select(x => x.Value)) + declarationNode.GenerateCode(moduleBuilder); + } + } +} \ No newline at end of file diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/TypedeclNode.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/TypedeclNode.cs new file mode 100644 index 0000000..42c8bcc --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/TypedeclNode.cs @@ -0,0 +1,84 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class TypeDeclNode : DeclarationNode + { + public TypeDeclNode(IToken payload) + : base(payload) + { + } + + public string Name { get { return this.IdNode.Name; } } + + public IdNode IdNode { get { return (IdNode)TigerChildren[0]; } } + public DeclarationNode DeclarationNode { get { return (DeclarationNode)TigerChildren[1]; } } + + public bool IsAliasNode { get { return this.DeclarationNode is AliasDeclNode; } } + public bool IsRecordNode { get { return this.DeclarationNode is RecordDeclNode; } } + public bool IsArrayNode { get { return this.DeclarationNode is ArrayDeclNode; } } + + public override bool CheckHeader(TigerScope scope, Report report, string name) + { + if (scope.CanFindTypeInfo(this.Name, true)) + { + report.AddError(this.Line, this.Column, "Redeclared local type: '{0}'.", this.Name); + this.IsOK = false; + return false; + } + + TigerTypeInfo outerTypeInfo = scope.FindTypeInfo(this.Name, false); + if (outerTypeInfo != null) + if (outerTypeInfo.IsStandard) + { + report.AddError(this.Line, this.Column, + "Redeclared standard type: '{0}'.", + this.Name); + this.IsOK = false; + return false; + } + else + report.AddWarning(this.Line, this.Column, "Type name hides outer scope type: '{0}'.", this.Name); + + return this.DeclarationNode.CheckHeader(scope, report, this.IdNode.Name); + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.DeclarationNode.CheckSemantics(scope, report); + this.IsOK = this.DeclarationNode.IsOK; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.DeclarationNode.GenerateCode(moduleBuilder); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/DeclarationNode/VardeclNode.cs b/YATC/ASTNodes/LocalNode/DeclarationNode/VardeclNode.cs new file mode 100644 index 0000000..a99d920 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/DeclarationNode/VardeclNode.cs @@ -0,0 +1,140 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class VarDeclNode : DeclarationNode + { + public VarDeclNode(IToken payload) + : base(payload) + { + } + + public TypeNode IdNode { get { return (TypeNode)TigerChildren[0]; } } + public TypeNode TypeNode { get { return (TypeNode)TigerChildren[1]; } } + public ExpressionNode RightExpressionNode { get { return (ExpressionNode)TigerChildren[2]; } } + + public VariableInfo VariableInfo { get; set; } + public bool IsAutoVariable { get { return this.TypeNode is FillInTypeNode; } } + + public override void CheckSemantics(TigerScope scope, Report report) + { + string name = this.IdNode.Name; + + if (scope.CanFindFunVarInfo(name, true)) + { + report.AddError(this.Line, this.Column, + "Redeclared local variable or function: '{0}'.", + name); + this.IsOK = false; + return; + } + + FunctionInfo outerfunctionInfo = scope.FindFunctionInfo(name, false); + if (outerfunctionInfo != null) + { + if (outerfunctionInfo.IsStandard) + { + report.AddError(this.Line, this.Column, + "Cannot define variable name with standard function: '{0}'.", + name); + this.IsOK = false; + return; + } + else + report.AddWarning(this.Line, this.Column, + "Variable name hides outer scope variable or function: '{0}'.", + name); + } + this.RightExpressionNode.CheckSemantics(scope, report); + + if (!this.RightExpressionNode.IsOk) + { + this.IsOK = false; + return; + } + + if (this.RightExpressionNode.TigerType.Equals(TigerType.Void)) + { + report.AddError(this.Line, this.Column, "Right hand side expression must evaluate to a returning value."); + this.IsOK = false; + return; + } + + this.TypeNode.CheckSemantics(scope, report); + TigerType returnType = this.RightExpressionNode.TigerType; + + if (!this.IsAutoVariable) + { + TigerTypeInfo tigerTypeInfo = scope.FindTypeInfo(this.TypeNode.Name, false); + if (tigerTypeInfo == null) + { + report.AddError(this.Line, this.Column, "Undeclared type: '{0}'.", this.TypeNode.Name); + this.IsOK = false; + return; + } + + /* Assignment */ + if (!this.RightExpressionNode.TigerType.IsAssignableTo(tigerTypeInfo.Holder.TigerType)) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Variable declaration and expression do not match " + + "for '{0}': expecting '{1}' and '{2}' found.", + name, tigerTypeInfo.Holder.TigerType.Name, this.RightExpressionNode.TigerType.Name); + this.IsOK = false; + return; + } + + returnType = tigerTypeInfo.Holder.TigerType; + } + else + { + if (returnType.Basetype == BaseType.Nil) + { + report.AddError(this.Line, this.Column, + "An automatic variable cannot be declared from nil expression."); + this.IsOK = false; + return; + } + } + + this.VariableInfo = new VariableInfo(name, new TigerTypeHolder(returnType), false); + scope.Add(VariableInfo); + this.IsOK = true; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.RightExpressionNode.GenerateCode(moduleBuilder); + this.VariableInfo.ParameterExpression = + Expression.Parameter(this.VariableInfo.Holder.TigerType.GetCLRType()); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/ArrayInstNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/ArrayInstNode.cs new file mode 100644 index 0000000..da86340 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/ArrayInstNode.cs @@ -0,0 +1,144 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class ArrayInstNode : ExpressionNode + { + private ArrayType _arrayType; + + public ArrayInstNode(IToken payload) + : base(payload) + { + } + + public IdNode IdNode { get { return (IdNode)TigerChildren[0]; } } + public ExpressionNode IndexExpressionNode { get { return (ExpressionNode)TigerChildren[1]; } } + public ExpressionNode OfExpressionNode { get { return (ExpressionNode)TigerChildren[2]; } } + + public override void CheckSemantics(TigerScope scope, Report report) + { + TigerTypeInfo arrayInfo = scope.FindTypeInfo(this.IdNode.Name, false); + if (arrayInfo == null || arrayInfo.Holder == null || arrayInfo.Holder.TigerType == null) + { + report.AddError(this.Line, this.Column, "Undeclared array type: '{0}'.", this.IdNode.Name); + this.TigerType = TigerType.Error; + return; + } + + if (arrayInfo.Holder.TigerType.Basetype != BaseType.Array) + { + report.AddError(this.Line, this.Column, "Given type is not an array: {0}", this.IdNode.Name); + this.TigerType = TigerType.Error; + return; + } + + _arrayType = arrayInfo.Holder.TigerType as ArrayType; + if (_arrayType == null) + throw new NullReferenceException(); + + this.IndexExpressionNode.CheckSemantics(scope, report); + if (!this.IndexExpressionNode.IsOk) + { + this.TigerType = TigerType.Error; + return; + } + + if (this.IndexExpressionNode.TigerType.Basetype != BaseType.Int) + { + report.AddError(this.Line, this.Column, "Type mismatch: Given index expression is not an integer: {0}", this.IndexExpressionNode.TigerType.Name); + this.TigerType = TigerType.Error; + return; + } + + this.OfExpressionNode.CheckSemantics(scope, report); + if (!this.OfExpressionNode.IsOk) + { + this.TigerType = TigerType.Error; + return; + } + + if (!this.OfExpressionNode.TigerType.IsAssignableTo(_arrayType.ElementTypeHolder.TigerType)) + { + report.AddError(this.Line, this.Column, "Type mismatch: Array element and expression types: '{0}' and '{1}'", + _arrayType.ElementTypeHolder.TigerType.Name, this.OfExpressionNode.TigerType.Name); + this.TigerType = TigerType.Error; + return; + } + + this.TigerType = _arrayType; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.IndexExpressionNode.GenerateCode(moduleBuilder); + this.OfExpressionNode.GenerateCode(moduleBuilder); + + Type elementType = _arrayType.ElementTypeHolder.TigerType.GetCLRType(); + Type arrayType = elementType.MakeArrayType(); + ParameterExpression arrayParamExpr = Expression.Parameter(arrayType); + ParameterExpression counterExpr = Expression.Parameter(typeof(int)); + + var arrayInitExpr = Expression.NewArrayBounds(elementType, this.IndexExpressionNode.VmExpression); + + LabelTarget breakLabel = Expression.Label(); + + BlockExpression blockInitExpression = Expression.Block( + new ParameterExpression[] { arrayParamExpr, counterExpr }, + new Expression[] + { + Expression.Assign(arrayParamExpr, arrayInitExpr), + Expression.Assign(counterExpr, Expression.Constant(0)), + Expression.Loop( + Expression.Block( + Expression.IfThenElse( + Expression.LessThan( + counterExpr, + this.IndexExpressionNode.VmExpression), + Expression.Assign( + Expression.ArrayAccess(arrayParamExpr, counterExpr), + Expression.Convert( + this.OfExpressionNode.VmExpression, + elementType + ) + ), + Expression.Break(breakLabel) + ), + Expression.Assign(counterExpr, Expression.Increment(counterExpr)) + ), breakLabel), + arrayParamExpr + } + ); + + this.VmExpression = blockInitExpression; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AccessNode/AccessNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AccessNode/AccessNode.cs new file mode 100644 index 0000000..ceeb2fe --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AccessNode/AccessNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + public abstract class AccessNode: AtomicNode + { + protected AccessNode(IToken payload) + : base(payload) + { + } + + public TigerType ParentType { get; set; } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AccessNode/ArrayAccess.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AccessNode/ArrayAccess.cs new file mode 100644 index 0000000..e0d1118 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AccessNode/ArrayAccess.cs @@ -0,0 +1,99 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + public class ArrayAccessNode : AccessNode + { + public ArrayAccessNode(IToken payload) + : base(payload) + { + } + + public ExpressionNode IndexExpressionNode { get { return (ExpressionNode) TigerChildren[0]; } } + public AccessNode AccessNode { get { return TigerChildren.Length > 1 ? (AccessNode)TigerChildren[1] : null; } } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.IndexExpressionNode.CheckSemantics(scope, report); + if (!this.IndexExpressionNode.IsOk) + { + this.TigerType = TigerType.Error; + return; + } + + if (this.IndexExpressionNode.TigerType.Basetype != BaseType.Int) + { + this.TigerType = TigerType.Error; + report.AddError(this.Line, this.Column, + "Type mismatch: Cannot index with a non-integer expression: '{0}' was found.", + this.IndexExpressionNode.TigerType.Name); + return; + } + + if (this.ParentType.Basetype != BaseType.Array) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Variable or field is not an array: '{0}' was found.", + this.ParentType.Name); + this.TigerType = TigerType.Error; + return; + } + + TigerType parentType = ((ArrayType)this.ParentType).ElementTypeHolder.TigerType; + if (this.AccessNode == null) + { + this.TigerType = parentType; + } + else + { + this.AccessNode.ParentType = parentType; + this.AccessNode.CheckSemantics(scope, report); + this.TigerType = AccessNode.TigerType; + } + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.IndexExpressionNode.GenerateCode(moduleBuilder); + this.VmExpression = Expression.ArrayAccess( + this.VmExpression, + this.IndexExpressionNode.VmExpression + ); + + if (this.AccessNode == null) + return; + + this.AccessNode.VmExpression = this.VmExpression; + this.AccessNode.GenerateCode(moduleBuilder); + this.VmExpression = this.AccessNode.VmExpression; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AccessNode/FieldAccessNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AccessNode/FieldAccessNode.cs new file mode 100644 index 0000000..6125399 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AccessNode/FieldAccessNode.cs @@ -0,0 +1,107 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class FieldAccessNode : AccessNode + { + private TigerType _parentType; + + public FieldAccessNode(IToken payload) + : base(payload) + { + } + + public TypeNode IdNode { get { return (TypeNode)TigerChildren[0]; } } + public AccessNode AccessNode { get { return TigerChildren.Length > 1 ? (AccessNode)TigerChildren[1] : null; } } + + public override void CheckSemantics(TigerScope scope, Report report) + { + if (this.ParentType.Basetype != BaseType.Record) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Variable or field is not a record: '{0}' was found.", + this.ParentType.Name); + this.TigerType = TigerType.Error; + return; + } + + VariableInfo[] fieldInfos = ((RecordType)this.ParentType).FieldInfos; + if (fieldInfos.Length == 0) + { + report.AddError(this.Line, this.Column, + "Cannot access field on empty record type '{0}': '{1}'", + this.ParentType.Name, this.IdNode.Name); + this.TigerType = TigerType.Error; + return; + } + + var fieldInfo = fieldInfos.FirstOrDefault(x => x.Name == this.IdNode.Name); + + if (fieldInfo == null) + { + report.AddError(this.Line, this.Column, + "Record type '{0}' does not contain a definition for '{1}'.", + this.ParentType.Name, this.IdNode.Name); + this.TigerType = TigerType.Error; + return; + } + + _parentType = fieldInfo.Holder.TigerType; + + if (this.AccessNode == null) + { + this.TigerType = _parentType; + } + else + { + this.AccessNode.ParentType = _parentType; + this.AccessNode.CheckSemantics(scope, report); + this.TigerType = AccessNode.TigerType; + } + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.VmExpression = Expression.MakeMemberAccess( + this.VmExpression, + this.ParentType.GetCLRType().GetMember(this.IdNode.Name)[0] + ); + + if (this.AccessNode == null) + return; + + this.AccessNode.VmExpression = this.VmExpression; + this.AccessNode.GenerateCode(moduleBuilder); + this.VmExpression = this.AccessNode.VmExpression; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AtomicNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AtomicNode.cs new file mode 100644 index 0000000..528fb70 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/AtomicNode.cs @@ -0,0 +1,37 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; + +namespace YATC.ASTNodes +{ + public abstract class AtomicNode : ExpressionNode + { + protected AtomicNode(IToken payload) + : base(payload) + { + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/ExprSeqNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/ExprSeqNode.cs new file mode 100644 index 0000000..cc5f839 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/ExprSeqNode.cs @@ -0,0 +1,89 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class ExprSeqNode : AtomicNode + { + public ExprSeqNode(IToken payload) + : base(payload) + { + } + + /// + /// Says whether the node contains a BreakNode, that is not within the control of a cycle control structure. + /// + public bool HasBreakInside { get; internal set; } + + public ExpressionNode[] ExpressionNodes + { + get { return TigerChildren.Length > 0 ? + TigerChildren.Cast().ToArray() : null; } + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + if (this.ExpressionNodes == null) + { + this.TigerType = TigerType.Void; + return; + } + + bool allOk = true; + foreach (var expressionNode in this.ExpressionNodes) + { + expressionNode.CheckSemantics(scope, report); + if (!expressionNode.IsOk) + allOk = false; + } + + this.TigerType = allOk + ? ((this.HasBreakInside || ExpressionNodes.Length == 0) + ? TigerType.Void + : ExpressionNodes[ExpressionNodes.Length - 1].TigerType) + : TigerType.Error; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + if (this.ExpressionNodes != null) + { + foreach (var expressionNode in this.ExpressionNodes) + expressionNode.GenerateCode(moduleBuilder); + + this.VmExpression = Expression.Block(new ParameterExpression[] { }, + this.ExpressionNodes.Select(x => x.VmExpression ?? Expression.Empty())); + } + else + this.VmExpression = Expression.Empty(); + } + } +} \ No newline at end of file diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/FuncallNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/FuncallNode.cs new file mode 100644 index 0000000..0c30965 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/FuncallNode.cs @@ -0,0 +1,137 @@ +/* + * 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. + * + */ + +using System; +using Antlr.Runtime; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class FunCallNode : AtomicNode + { + public FunCallNode(IToken payload) + : base(payload) + { + } + + public TypeNode IdNode { get { return (TypeNode)TigerChildren[0]; } } + + public ExpressionNode[] ActualParametersNodes + { + get + { + return TigerChildren.Length > 1 ? + TigerChildren[1].TigerChildren.Cast().ToArray() : + new ExpressionNode[] {}; + } + } + + public FunctionInfo FunctionInfo { get; set; } + + public override void CheckSemantics(TigerScope scope, Report report) + { + FunctionInfo functionInfo = scope.FindFunctionInfo(this.IdNode.Name, false); + this.FunctionInfo = functionInfo; + + if (functionInfo == null) + { + report.AddError(this.Line, this.Column, "Undeclared function: '{0}'.", this.IdNode.Name); + this.TigerType = TigerType.Error; + return; + } + + if (this.ActualParametersNodes == null && functionInfo.ParameterInfo.Length > 0 || + this.ActualParametersNodes != null && this.ActualParametersNodes.Length != functionInfo.ParameterInfo.Length) + { + report.AddError(this.Line, this.Column, + "Length of formal and actual parameters differ for function or procedure '{0}': " + + "Expecting {1} and found {2} arguments.", + this.IdNode.Name, + functionInfo.ParameterInfo.Length, + this.ActualParametersNodes != null ? this.ActualParametersNodes.Length : 0); + this.TigerType = TigerType.Error; + return; + } + + if (this.ActualParametersNodes != null) + { + for (int i = 0; i < functionInfo.ParameterInfo.Length; i++) + { + this.ActualParametersNodes[i].CheckSemantics(scope, report); + if (!this.ActualParametersNodes[i].IsOk) + { + this.TigerType = TigerType.Error; + return; + } + + if (!this.ActualParametersNodes[i].TigerType.IsAssignableTo(functionInfo.ParameterInfo[i].Holder.TigerType)) + { + report.AddError(this.Line, this.Column, + "Types mismatch: Formal and actual parameter types differ for argument number {0} whilst calling " + + "function or procedure '{3}': Expecting '{1}' and found '{2}'.", + i, + functionInfo.ParameterInfo[i].Holder.TigerType.Name, + this.ActualParametersNodes[i].TigerType.Name, + this.IdNode.Name); + this.TigerType = TigerType.Error; + return; + } + } + } + + this.TigerType = functionInfo.Holder.TigerType; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + Expression[] arguments = new Expression[this.ActualParametersNodes.Length]; + for (int i = 0; i < this.ActualParametersNodes.Length; i++) + { + ExpressionNode argument = this.ActualParametersNodes[i]; + argument.GenerateCode(moduleBuilder); + + arguments[i] = Expression.Convert( + argument.VmExpression, + this.FunctionInfo.ParameterInfo[i].Holder.TigerType.GetCLRType() + ); + } + + if (this.FunctionInfo.Name == "exit") + { + var exit = ((Action)Environment.Exit).Method; + this.VmExpression = Expression.Call(exit, arguments[0]); + return; + } + + if (this.FunctionInfo.MethodInfo != null) + this.VmExpression = Expression.Call(this.FunctionInfo.MethodInfo, arguments); + else + this.VmExpression = Expression.Invoke(this.FunctionInfo.LambdaExpression, arguments); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/IfNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/IfNode.cs new file mode 100644 index 0000000..56dafdd --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/IfNode.cs @@ -0,0 +1,138 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class IfNode : AtomicNode + { + public IfNode(IToken payload) + : base(payload) + { + } + + public ExpressionNode ConditionNode { get { return (ExpressionNode)TigerChildren[0]; } } + public ExpressionNode ThenExpressionNode { get { return (ExpressionNode)TigerChildren[1]; } } + public ExpressionNode ElseExpressionNode + { + get + { + return TigerChildren.Length > 2 ? (ExpressionNode)TigerChildren[2] : null; + } + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.ConditionNode.CheckSemantics(scope, report); + this.ThenExpressionNode.CheckSemantics(scope, report); + bool allOk = this.ConditionNode.IsOk && this.ThenExpressionNode.IsOk; + + if (this.ConditionNode.IsOk) + { + if (this.ConditionNode.TigerType.Basetype == BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of if condition with a non-valued expression.", + this.ConditionNode.TigerType.Name); + this.TigerType = TigerType.Error; + allOk = false; + } + else + if (this.ConditionNode.TigerType.Basetype != BaseType.Int) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of if condition with a non-int expression: '{0}' was found.", + this.ConditionNode.TigerType.Name); + this.TigerType = TigerType.Error; + allOk = false; + } + } + + TigerType returnType = this.ThenExpressionNode.TigerType; + + if (this.ElseExpressionNode != null) + { + this.ElseExpressionNode.CheckSemantics(scope, report); + allOk &= this.ElseExpressionNode.IsOk; + + bool isThenAssignable = + this.ThenExpressionNode.TigerType.IsAssignableTo(this.ElseExpressionNode.TigerType); + + returnType = isThenAssignable ? this.ElseExpressionNode.TigerType : this.ThenExpressionNode.TigerType; + + /* facilita que se puede asignar record y nil, con independencia del orden en que aparezca */ + if (!isThenAssignable && !this.ElseExpressionNode.TigerType.IsAssignableTo(this.ThenExpressionNode.TigerType)) + { + report.AddError(this.Line, this.Column, + "Type mismatch: The then and else expression types of an if-then-else differ: " + + "'{0}' and '{1}' were found.", + this.ThenExpressionNode.TigerType.Name, this.ElseExpressionNode.TigerType.Name); + this.TigerType = TigerType.Error; + return; + } + } + else + { + if (this.ThenExpressionNode.TigerType.Basetype != BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: The then expression at a if-then statement must not return a value: " + + "Found '{0}' whilst expecting void.", + this.ThenExpressionNode.TigerType.Name); + this.TigerType = TigerType.Error; + return; + } + } + + this.TigerType = allOk ? returnType : TigerType.Error; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.ConditionNode.GenerateCode(moduleBuilder); + this.ThenExpressionNode.GenerateCode(moduleBuilder); + + if (this.ElseExpressionNode != null) + { + this.ElseExpressionNode.GenerateCode(moduleBuilder); + + this.VmExpression = Expression.Condition( + Expression.NotEqual(this.ConditionNode.VmExpression, Expression.Constant(0)), + this.ThenExpressionNode.VmExpression, + this.ElseExpressionNode.VmExpression); + } + else + { + this.VmExpression = Expression.IfThen( + Expression.NotEqual(this.ConditionNode.VmExpression, Expression.Constant(0)), + this.ThenExpressionNode.VmExpression); + } + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/IntNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/IntNode.cs new file mode 100644 index 0000000..1cd9199 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/IntNode.cs @@ -0,0 +1,58 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class IntNode : AtomicNode + { + public IntNode(IToken payload) + : base(payload) + { + } + + public int Value { get { return int.Parse(this.Text); } } + + public override void CheckSemantics(TigerScope scope, Report report) + { + int value; + if (!int.TryParse(this.Text, out value)) + { + report.AddError(this.Line, this.Column, "Integer literal value is out of range."); + this.TigerType = TigerType.Error; + } + else this.TigerType = TigerType.Int; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.VmExpression = Expression.Constant(this.Value); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/LetNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/LetNode.cs new file mode 100644 index 0000000..a730101 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/LetNode.cs @@ -0,0 +1,131 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class LetNode : AtomicNode + { + public LetNode(IToken payload) + : base(payload) + { + } + + public IEnumerable DeclarationNodes { get { return TigerChildren[0].TigerChildren.Cast(); } } + public ExprSeqNode ExprSeqNode + { + get + { + return (ExprSeqNode)TigerChildren[1]; + } + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + TigerScope innerScope = scope.CreateChildScope(); + + foreach (var declarationNode in this.DeclarationNodes) + { + declarationNode.CheckSemantics(innerScope, report); + if (!declarationNode.IsOK) + { + this.TigerType = TigerType.Error; + return; + } + } + + this.ExprSeqNode.CheckSemantics(innerScope, report); + if (!this.ExprSeqNode.IsOk || scope.ContainsType(this.ExprSeqNode.TigerType, false)) + this.TigerType = this.ExprSeqNode.TigerType; + else + { + report.AddError(this.Line, this.Column, + "Type mismatch: Type '{0}' returned from let declaration is not " + + "defined in an outer scope, or it is a different definition.", + this.ExprSeqNode.TigerType.Name); + this.TigerType = TigerType.Error; + } + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + foreach (var declarationNode in DeclarationNodes) + declarationNode.GenerateCode(moduleBuilder); + + if (this.ExprSeqNode.ExpressionNodes != null) + foreach (var expressionNode in this.ExprSeqNode.ExpressionNodes) + expressionNode.GenerateCode(moduleBuilder); + + // variables + IEnumerable varDeclNodes = + this.DeclarationNodes.Where(x => x is VarDeclNode).Cast(); + + IEnumerable variables = + varDeclNodes.Select(x => x.VariableInfo.ParameterExpression); + + IEnumerable initVariablesExpressions = + varDeclNodes.Select(varDeclNode => + Expression.Assign( + varDeclNode.VariableInfo.ParameterExpression, + Expression.Convert( + varDeclNode.RightExpressionNode.VmExpression, + varDeclNode.VariableInfo.Holder.TigerType.GetCLRType() + ) + ) + ); + + // fundeclseq + IEnumerable funDeclSeqNodes = + this.DeclarationNodes.Where(x => x is FunDeclSeqNode).Cast(); + + // final + IEnumerable blockExpressions = initVariablesExpressions.Concat( + this.ExprSeqNode.ExpressionNodes != null ? + (this.ExprSeqNode.ExpressionNodes.Select(x => x.VmExpression)) : + new Expression[] { Expression.Empty() } + ); + + var functionClousures = new List(); + var functionAssigns = new List(); + foreach (var funDeclSeqNode in funDeclSeqNodes) + { + functionClousures.AddRange(funDeclSeqNode.FunctionClousures); + functionAssigns.AddRange(funDeclSeqNode.FunctionAssigns); + } + + this.VmExpression = Expression.Block( + functionClousures.Concat(variables), + functionAssigns.Concat(blockExpressions)); + + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/NilNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/NilNode.cs new file mode 100644 index 0000000..b5d145f --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/NilNode.cs @@ -0,0 +1,50 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class NilNode: AtomicNode + { + public NilNode(IToken payload) + : base(payload) + { + this.VmExpression = Expression.Constant(null); + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.TigerType = TigerType.Nil; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/StringNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/StringNode.cs new file mode 100644 index 0000000..c5d6273 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/StringNode.cs @@ -0,0 +1,64 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System; +using System.Linq.Expressions; +using System.Reflection.Emit; +using System.Text.RegularExpressions; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class StringNode : AtomicNode + { + public StringNode(IToken payload) + : base(payload) + { + string tmp = Text.Substring(1, Text.Length - 2); + tmp = Regex.Replace(tmp, @"\\(\n|\r|\t|\s)+\\", string.Empty); + tmp = Regex.Replace(tmp, @"(\\\d\d\d)", ToAscii); + Value = Regex.Unescape(tmp); + } + + public string Value { get; private set; } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.TigerType = TigerType.String; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.VmExpression = Expression.Constant(this.Value); + } + + private string ToAscii(Match m) + { + var a = int.Parse(m.Groups[0].Value.Substring(1)); + return Convert.ToChar(a).ToString(); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/VaraccessNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/VaraccessNode.cs new file mode 100644 index 0000000..8f95c9e --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/AtomicNode/VaraccessNode.cs @@ -0,0 +1,78 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + internal class VarAccessNode : AtomicNode + { + public VarAccessNode(IToken payload) + : base(payload) + { + } + + public TypeNode IdNode { get { return (TypeNode)TigerChildren[0]; } } + public AccessNode AccessNode { get { return TigerChildren.Length > 1 ? (AccessNode)TigerChildren[1] : null; } } + + public string Name { get { return IdNode.Text; } } + public VariableInfo VariableInfo { get; set; } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.VariableInfo = scope.FindVariableInfo(this.Name, false); + if (this.VariableInfo == null) + { + report.AddError(this.Line, this.Column, "Undeclared variable: '{0}'.", this.Name); + this.TigerType = TigerType.Error; + return; + } + + if (this.AccessNode != null) + { + this.AccessNode.ParentType = this.VariableInfo.Holder.TigerType; + this.AccessNode.CheckSemantics(scope, report); + this.TigerType = this.AccessNode.TigerType; + return; + } + + this.TigerType = VariableInfo.Holder.TigerType; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.VmExpression = this.VariableInfo.ParameterExpression; + + if (this.AccessNode == null) + return; + + this.AccessNode.VmExpression = this.VmExpression; + this.AccessNode.GenerateCode(moduleBuilder); + this.VmExpression = this.AccessNode.VmExpression; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/ArithmeticNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/ArithmeticNode.cs new file mode 100644 index 0000000..aa4996a --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/ArithmeticNode.cs @@ -0,0 +1,85 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + abstract class ArithmeticNode : BinaryNode + { + protected ArithmeticNode(IToken payload) + : base(payload) + { + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + base.CheckSemantics(scope, report); + bool bothOk = this.LeftOperandNode.IsOk && this.RightOperandNode.IsOk; + + if (this.LeftOperandNode.IsOk) + { + if (this.LeftOperandNode.TigerType.Basetype == BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary arithmetic operator with a non-valued left expression."); + this.TigerType = TigerType.Error; + bothOk = false; + } + else + if (this.LeftOperandNode.TigerType.Basetype != BaseType.Int) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary arithmetic operator with a non-int left expression: '{0}' was found.", + this.LeftOperandNode.TigerType.Name); + this.TigerType = TigerType.Error; + bothOk = false; + } + } + + if (this.RightOperandNode.IsOk) + { + if (this.RightOperandNode.TigerType.Basetype == BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary arithmetic operator with a non-valued right expression."); + this.TigerType = TigerType.Error; + bothOk = false; + } + else + if (this.RightOperandNode.TigerType.Basetype != BaseType.Int) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary arithmetic operator with a non-int right expression: '{0}' was found.", + this.RightOperandNode.TigerType.Name); + this.TigerType = TigerType.Error; + bothOk = false; + } + } + this.TigerType = bothOk ? TigerType.Int : TigerType.Error; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/DivNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/DivNode.cs new file mode 100644 index 0000000..425c448 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/DivNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using System; +using System.Linq.Expressions; +using Antlr.Runtime; + +namespace YATC.ASTNodes +{ + class DivNode : ArithmeticNode + { + public DivNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.Divide; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/MinusNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/MinusNode.cs new file mode 100644 index 0000000..378c887 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/MinusNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using System; +using System.Linq.Expressions; +using Antlr.Runtime; + +namespace YATC.ASTNodes +{ + class MinusNode : ArithmeticNode + { + public MinusNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.Subtract; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/MultNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/MultNode.cs new file mode 100644 index 0000000..c50e4d6 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/MultNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using System; +using System.Linq.Expressions; +using Antlr.Runtime; + +namespace YATC.ASTNodes +{ + class MultNode : ArithmeticNode + { + public MultNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.Multiply; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/PlusNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/PlusNode.cs new file mode 100644 index 0000000..2f328d1 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/ArithmeticNode/PlusNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using System; +using System.Linq.Expressions; +using Antlr.Runtime; + +namespace YATC.ASTNodes +{ + class PlusNode : ArithmeticNode + { + public PlusNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.Add; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/BinaryNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/BinaryNode.cs new file mode 100644 index 0000000..0b48981 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/BinaryNode.cs @@ -0,0 +1,66 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + abstract class BinaryNode : ExpressionNode + { + public BinaryNode(IToken payload) + : base(payload) + { + } + + protected ExpressionType ExpressionType; + + public ExpressionNode LeftOperandNode { get { return (ExpressionNode)TigerChildren[0]; } } + public ExpressionNode RightOperandNode { get { return (ExpressionNode)TigerChildren[1]; } } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.LeftOperandNode.CheckSemantics(scope, report); + this.RightOperandNode.CheckSemantics(scope, report); + + if (!this.LeftOperandNode.IsOk || !this.RightOperandNode.IsOk) + // No se reporta el error para evitar cascadas de errores + this.TigerType = TigerType.Error; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.LeftOperandNode.GenerateCode(moduleBuilder); + this.RightOperandNode.GenerateCode(moduleBuilder); + + this.VmExpression = Expression.MakeBinary(this.ExpressionType, + this.LeftOperandNode.VmExpression, + this.RightOperandNode.VmExpression + ); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/LogicNode/AndNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/LogicNode/AndNode.cs new file mode 100644 index 0000000..1e295e9 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/LogicNode/AndNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System; +using System.Linq.Expressions; + +namespace YATC.ASTNodes +{ + class AndNode : LogicNode + { + public AndNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.AndAlso; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/LogicNode/LogicNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/LogicNode/LogicNode.cs new file mode 100644 index 0000000..06c2f20 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/LogicNode/LogicNode.cs @@ -0,0 +1,106 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + abstract class LogicNode : BinaryNode + { + protected LogicNode(IToken payload) + : base(payload) + { + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + base.CheckSemantics(scope, report); + bool bothOk = this.LeftOperandNode.IsOk && this.RightOperandNode.IsOk; + + if (this.LeftOperandNode.IsOk) + { + if (this.LeftOperandNode.TigerType.Basetype == BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary logical operator with a non-valued left expression."); + this.TigerType = TigerType.Error; + bothOk = false; + } + else + if (this.LeftOperandNode.TigerType.Basetype != BaseType.Int) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary logical operator with a non-int left expression: '{0}' was found.", + this.LeftOperandNode.TigerType.Name); + this.TigerType = TigerType.Error; + bothOk = false; + } + } + + if (this.RightOperandNode.IsOk) + { + if (this.RightOperandNode.TigerType.Basetype == BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary logical operator with a non-valued right expression."); + this.TigerType = TigerType.Error; + bothOk = false; + } + else + if (this.RightOperandNode.TigerType.Basetype != BaseType.Int) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary logical operator with a non-int right expression: '{0}' was found.", + this.RightOperandNode.TigerType.Name); + this.TigerType = TigerType.Error; + bothOk = false; + } + } + + this.TigerType = bothOk ? TigerType.Int : TigerType.Error; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.LeftOperandNode.GenerateCode(moduleBuilder); + this.RightOperandNode.GenerateCode(moduleBuilder); + + this.LeftOperandNode.VmExpression = Expression.NotEqual(this.LeftOperandNode.VmExpression, + Expression.Constant(0)); + this.RightOperandNode.VmExpression = Expression.NotEqual(this.RightOperandNode.VmExpression, + Expression.Constant(0)); + + this.VmExpression = Expression.MakeBinary(this.ExpressionType, + this.LeftOperandNode.VmExpression, + this.RightOperandNode.VmExpression + ); + + this.VmExpression = Expression.Condition(this.VmExpression, Expression.Constant(1), Expression.Constant(0)); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/LogicNode/OrNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/LogicNode/OrNode.cs new file mode 100644 index 0000000..4236333 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/LogicNode/OrNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using System; +using System.Linq.Expressions; +using Antlr.Runtime; + +namespace YATC.ASTNodes +{ + class OrNode : LogicNode + { + public OrNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.OrElse; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/IdentityNode/EqNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/IdentityNode/EqNode.cs new file mode 100644 index 0000000..e5a89b2 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/IdentityNode/EqNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System; +using System.Linq.Expressions; + +namespace YATC.ASTNodes +{ + class EqNode : IdentityNode + { + public EqNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.Equal; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/IdentityNode/IdentityNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/IdentityNode/IdentityNode.cs new file mode 100644 index 0000000..99d1785 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/IdentityNode/IdentityNode.cs @@ -0,0 +1,83 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + abstract class IdentityNode : RelationalNode + { + protected IdentityNode(IToken payload) + : base(payload) + { + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + base.CheckSemantics(scope, report); + bool bothOk = this.LeftOperandNode.IsOk && this.RightOperandNode.IsOk; + + if (LeftOperandNode.IsOk && this.LeftOperandNode.TigerType.Basetype == BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary identity operator with a non-valued left expression."); + this.TigerType = TigerType.Error; + bothOk = false; + } + + if (this.RightOperandNode.IsOk && this.RightOperandNode.TigerType.Basetype == BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary identity operator with a non-valued right expression."); + this.TigerType = TigerType.Error; + bothOk = false; + } + + if (this.LeftOperandNode.TigerType.Basetype == BaseType.Nil && + this.RightOperandNode.TigerType.Basetype == BaseType.Nil) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary identity operator with two nils."); + this.TigerType = TigerType.Error; + bothOk = false; + } + + if (bothOk && + !LeftOperandNode.TigerType.IsAssignableTo(RightOperandNode.TigerType) && + !RightOperandNode.TigerType.IsAssignableTo(LeftOperandNode.TigerType)) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary identity operator with different types: '{0}' and '{1}' were found.", + this.LeftOperandNode.TigerType.Name, + this.RightOperandNode.TigerType.Name); + this.TigerType = TigerType.Error; + bothOk = false; + } + + this.TigerType = bothOk ? TigerType.Int : TigerType.Error; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/IdentityNode/NotEqNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/IdentityNode/NotEqNode.cs new file mode 100644 index 0000000..42a1c4c --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/IdentityNode/NotEqNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System; +using System.Linq.Expressions; + +namespace YATC.ASTNodes +{ + class NoteqNode : IdentityNode + { + public NoteqNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.NotEqual; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/GtEqNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/GtEqNode.cs new file mode 100644 index 0000000..f5a032a --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/GtEqNode.cs @@ -0,0 +1,42 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; + +namespace YATC.ASTNodes +{ + /// + /// Mayor o igual que ">=" + /// + class GteqNode : OrderNode + { + public GteqNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.GreaterThanOrEqual; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/GtNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/GtNode.cs new file mode 100644 index 0000000..0114b07 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/GtNode.cs @@ -0,0 +1,42 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; + +namespace YATC.ASTNodes +{ + /// + /// Mayor que ">" + /// + class GtNode : OrderNode + { + public GtNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.GreaterThan; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/LtEqNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/LtEqNode.cs new file mode 100644 index 0000000..e036555 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/LtEqNode.cs @@ -0,0 +1,42 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; + +namespace YATC.ASTNodes +{ + /// + /// Menor o igual "<=" + /// + class LteqNode : OrderNode + { + public LteqNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.LessThanOrEqual; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/LtNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/LtNode.cs new file mode 100644 index 0000000..925ddaf --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/LtNode.cs @@ -0,0 +1,42 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; + +namespace YATC.ASTNodes +{ + /// + /// Menor que "<" + /// + class LtNode : OrderNode + { + public LtNode(IToken payload) + : base(payload) + { + this.ExpressionType = ExpressionType.LessThan; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/OrderNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/OrderNode.cs new file mode 100644 index 0000000..92625c0 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/OrderNode/OrderNode.cs @@ -0,0 +1,153 @@ +/* + * 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. + * + */ + +using System; +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + abstract class OrderNode : RelationalNode + { + protected OrderNode(IToken payload) + : base(payload) + { + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + base.CheckSemantics(scope, report); + bool bothOk = this.LeftOperandNode.IsOk && this.RightOperandNode.IsOk; + + if (this.LeftOperandNode.IsOk) + { + if (this.LeftOperandNode.TigerType.Basetype == BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary order operator with a non-valued left expression."); + this.TigerType = TigerType.Error; + bothOk = false; + } + else + if (this.LeftOperandNode.TigerType.Basetype != BaseType.Int && + this.LeftOperandNode.TigerType.Basetype != BaseType.String) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary order operator with a non-int or non-string left expression: '{0}' was found.", + this.LeftOperandNode.TigerType.Name); + this.TigerType = TigerType.Error; + bothOk = false; + } + } + + if (this.RightOperandNode.IsOk) + { + if (this.RightOperandNode.TigerType.Basetype == BaseType.Void) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary order operator with a non-valued right expression."); + this.TigerType = TigerType.Error; + bothOk = false; + } + else + if (this.RightOperandNode.TigerType.Basetype != BaseType.Int && + this.RightOperandNode.TigerType.Basetype != BaseType.String) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary order operator with a non-int or non-string right expression: '{0}' was found.", + this.RightOperandNode.TigerType.Name); + this.TigerType = TigerType.Error; + bothOk = false; + } + } + + if (bothOk && this.LeftOperandNode.TigerType.Basetype != this.RightOperandNode.TigerType.Basetype) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Invalid use of binary order operator with string and int expressions."); + this.TigerType = TigerType.Error; + return; + } + + this.TigerType = bothOk ? TigerType.Int : TigerType.Error; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.LeftOperandNode.GenerateCode(moduleBuilder); + this.RightOperandNode.GenerateCode(moduleBuilder); + + if (this.LeftOperandNode.TigerType.Basetype == BaseType.String && + this.RightOperandNode.TigerType.Basetype == BaseType.String) + { + MethodInfo compareString = ((Func)String.Compare).Method; + + ParameterExpression value = Expression.Parameter(typeof (int)); + Expression compareCall = Expression.Call(compareString, + this.LeftOperandNode.VmExpression, + this.RightOperandNode.VmExpression); + + Expression condition = null; + switch (this.ExpressionType) + { + case ExpressionType.GreaterThan: + condition = Expression.GreaterThan(value, Expression.Constant(0)); + break; + case ExpressionType.GreaterThanOrEqual: + condition = Expression.GreaterThanOrEqual(value, Expression.Constant(0)); + break; + case ExpressionType.LessThan: + condition = Expression.LessThan(value, Expression.Constant(0)); + break; + case ExpressionType.LessThanOrEqual: + condition = Expression.LessThanOrEqual(value, Expression.Constant(0)); + break; + } + + Expression block = Expression.Block( + new ParameterExpression[] {value}, + new Expression[] + { + Expression.Assign(value, compareCall), + Expression.Condition(condition, Expression.Constant(1), Expression.Constant(0)) + } + ); + + this.VmExpression = block; + } + else + { + Expression opHolds = Expression.MakeBinary(this.ExpressionType, + this.LeftOperandNode.VmExpression, + this.RightOperandNode.VmExpression); + + this.VmExpression = Expression.Condition(opHolds, Expression.Constant(1), Expression.Constant(0)); + } + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/RelationalNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/RelationalNode.cs new file mode 100644 index 0000000..64c4d6a --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/BinaryNode/RelationalNode/RelationalNode.cs @@ -0,0 +1,46 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; + +namespace YATC.ASTNodes +{ + abstract class RelationalNode : BinaryNode + { + protected RelationalNode(IToken payload) + : base(payload) + { + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + base.GenerateCode(moduleBuilder); + + this.VmExpression = Expression.Condition(this.VmExpression, Expression.Constant(1), Expression.Constant(0)); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/ExpressionNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/ExpressionNode.cs new file mode 100644 index 0000000..02aefab --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/ExpressionNode.cs @@ -0,0 +1,54 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + public abstract class ExpressionNode : LocalNode + { + protected ExpressionNode(IToken payload) + : base(payload) + { + } + + private TigerType _tigerType = TigerType.Error; + + /// + /// Tipo resultante de la expresión + /// + public TigerType TigerType + { + get { return _tigerType; } + protected set { _tigerType = value; } + } + + /// + /// Dice si un nodo está o no bien + /// + public bool IsOk { get { return !TigerType.Equals(TigerType.Error); } } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/NegNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/NegNode.cs new file mode 100644 index 0000000..adb4d63 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/NegNode.cs @@ -0,0 +1,77 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + /// + /// Permite poner números negativos + /// + class NegNode : ExpressionNode + { + public NegNode(IToken payload) + : base(payload) + { + } + + protected ExpressionNode OperandNode { get { return (ExpressionNode)TigerChildren[0]; } } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.OperandNode.CheckSemantics(scope, report); + if (!this.OperandNode.IsOk) + { + this.TigerType = TigerType.Error; + return; + } + + if (OperandNode.TigerType.Basetype == BaseType.Void) + { + this.TigerType = TigerType.Error; + report.AddError(this.Line, this.Column, "Type mismatch: Invalid use of unary minus operator with a non-valued expression."); + return; + } + + if (OperandNode.TigerType.Basetype != BaseType.Int) + { + this.TigerType = TigerType.Error; + report.AddError(this.Line, this.Column, "Type mismatch: Invalid use of unary minus operator with a non-int expression."); + return; + } + + this.TigerType = TigerType.Int; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.OperandNode.GenerateCode(moduleBuilder); + this.VmExpression = Expression.Negate(this.OperandNode.VmExpression); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/RecordInstNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/RecordInstNode.cs new file mode 100644 index 0000000..11e5615 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/RecordInstNode.cs @@ -0,0 +1,154 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class RecordInstNode : ExpressionNode + { + public RecordInstNode(IToken payload) + : base(payload) + { + } + + public TypeNode IdNode { get { return (TypeNode)TigerChildren[0]; } } + public FieldInstNode[] FieldInstNodes + { + get + { + return TigerChildren.Length > 1 ? + TigerChildren[1].TigerChildren.Cast().ToArray() : + new FieldInstNode[] {}; + } + } + private RecordType _recordType; + + public override void CheckSemantics(TigerScope scope, Report report) + { + TigerTypeInfo recordInfo = scope.FindTypeInfo(this.IdNode.Name, false); + if (recordInfo == null) + { + report.AddError(this.Line, this.Column, + "Undeclared record type: '{0}'.", this.IdNode.Name); + this.TigerType = TigerType.Error; + return; + } + + if (recordInfo.Holder.TigerType.Basetype != BaseType.Record) + { + report.AddError(this.Line, this.Column, + "Type mismatch: given type is not a record: '{0}'.", this.IdNode.Name); + this.TigerType = TigerType.Error; + return; + } + + _recordType = recordInfo.Holder.TigerType as RecordType; + if (_recordType == null) + throw new NullReferenceException(); + + if (_recordType.FieldInfos.Length != this.FieldInstNodes.Length) + { + report.AddError(this.Line, this.Column, + "Record fields length mismatch '{0}': expecting {1} and {2} found.", + this.IdNode.Name, + _recordType.FieldInfos.Length, + this.FieldInstNodes.Length); + this.TigerType = TigerType.Error; + return; + } + + for (int i = 0; i < this.FieldInstNodes.Length; i++) + { + FieldInstNode field = this.FieldInstNodes[i]; + + if (field.IdNode.Name != _recordType.FieldInfos[i].Name) + { + report.AddError(this.Line, this.Column, + "Field name mismatch: field number {0} of type '{1}' should be called '{2}' instead of '{3}'.", + i.ToString(), + this.IdNode.Name, + _recordType.FieldInfos[i].Name, + field.IdNode.Name); + this.TigerType = TigerType.Error; + return; + } + + field.ExpressionNode.CheckSemantics(scope, report); + if (!field.ExpressionNode.IsOk) + { + this.TigerType = TigerType.Error; + return; + } + + if (!field.ExpressionNode.TigerType.IsAssignableTo(_recordType.FieldInfos[i].Holder.TigerType)) + { + report.AddError(this.Line, this.Column, + "Type mismatch: field '{1}' of type '{0}' should be of type '{2}' instead of '{3}'", + this.IdNode.Name, field.IdNode.Name, + _recordType.FieldInfos[i].Holder.TigerType.Name, field.ExpressionNode.TigerType.Name); + this.TigerType = TigerType.Error; + return; + } + } + + this.TigerType = _recordType; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + NewExpression ctor = Expression.New(this.TigerType.GetCLRType()); + ParameterExpression tmp = Expression.Parameter(this.TigerType.GetCLRType()); + var fieldBindings = new MemberBinding[_recordType.FieldInfos.Length]; + + for (int i = 0; i < FieldInstNodes.Length; i++) + { + this.FieldInstNodes[i].ExpressionNode.GenerateCode(moduleBuilder); + + fieldBindings[i] = Expression.Bind( + _recordType.GetCLRType().GetMember(_recordType.FieldInfos[i].Name)[0], + Expression.Convert( + this.FieldInstNodes[i].ExpressionNode.VmExpression, + _recordType.FieldInfos[i].Holder.TigerType.GetCLRType() + ) + ); + } + + Expression initializer = Expression.MemberInit(ctor, fieldBindings); + + var assign = Expression.Assign(tmp, initializer); + BlockExpression initBlockExpression = Expression.Block( + new ParameterExpression[] { tmp }, + new Expression[] { assign, tmp }); + + this.VmExpression = initBlockExpression; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/AssignNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/AssignNode.cs new file mode 100644 index 0000000..baf683e --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/AssignNode.cs @@ -0,0 +1,105 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class AssignNode : StatementNode + { + public AssignNode(IToken payload) + : base(payload) + { + } + + public VarAccessNode LeftValueNode { get { return (VarAccessNode)TigerChildren[0]; } } + public ExpressionNode RightExpressionNode { get { return (ExpressionNode)TigerChildren[1]; } } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.LeftValueNode.CheckSemantics(scope, report); + this.RightExpressionNode.CheckSemantics(scope, report); + + // No se reporta el error para evitar cascadas de errores + this.TigerType = this.LeftValueNode.IsOk && this.RightExpressionNode.IsOk + ? TigerType.Void + : TigerType.Error; + + if (!this.IsOk) + return; + + if (this.RightExpressionNode.TigerType.Equals(TigerType.Void)) + { + report.AddError(this.Line, this.Column, "Right hand side must evaluate to a returning value."); + this.TigerType = TigerType.Error; + return; + } + + /* Assignment */ + if (!this.RightExpressionNode.TigerType.IsAssignableTo(this.LeftValueNode.TigerType)) + { + report.AddError(this.Line, this.Column, + "Type mismatch: Types of variable declaration and expression do not match: '{0}' and '{1}'", + this.LeftValueNode.TigerType.Name, this.RightExpressionNode.TigerType.Name); + this.TigerType = TigerType.Error; + return; + } + + // checks if left variable is not read-only, i.e., it is not defined in a ForNode + // la segunda pregunta accessNode == null es por si se quiere agregar campos o arrays + if (this.LeftValueNode.VariableInfo.IsReadOnly && this.LeftValueNode.AccessNode == null) + { + this.TigerType = TigerType.Error; + report.AddError(this.Line, this.Column, + "Cannot assign to a read-only variable (it may be declared within a for control structure)."); + return; + } + + this.TigerType = TigerType.Void; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.LeftValueNode.GenerateCode(moduleBuilder); + this.RightExpressionNode.GenerateCode(moduleBuilder); + + //int isOK = (int)(34 < 342); + + this.VmExpression = + Expression.Block( + Expression.Assign( + this.LeftValueNode.VmExpression, + Expression.Convert( + this.RightExpressionNode.VmExpression, + this.LeftValueNode.TigerType.GetCLRType() + ) + ), + Expression.Empty()); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/BreakNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/BreakNode.cs new file mode 100644 index 0000000..825d058 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/BreakNode.cs @@ -0,0 +1,80 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class BreakNode : StatementNode + { + public BreakNode(IToken payload) + : base(payload) + { + } + + public IBreakeableNode Owner { get; set; } + + public override void CheckSemantics(TigerScope scope, Report report) + { + foreach (var node in this.GetNodesToRoot()) + { + var exprSeq = node as ExprSeqNode; + if (exprSeq != null) + exprSeq.HasBreakInside = true; + + var breakable = node as IBreakeableNode; + if (breakable != null) + { + this.Owner = breakable; + break; + } + + if (node is FunDeclNode) + { + report.AddError(this.Line, this.Column, + "Break loop control structure not found within function."); + break; + } + } + + if (this.Owner == null) + { + report.AddError(Line, Column, "Break does not have a matching loop control structure owner."); + this.TigerType = TigerType.Error; + return; + } + + this.TigerType = TigerType.Void; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + this.VmExpression = Expression.Break(this.Owner.BreakTarget); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/EmptyNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/EmptyNode.cs new file mode 100644 index 0000000..89e1b0e --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/EmptyNode.cs @@ -0,0 +1,49 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class EmptyNode : StatementNode + { + public EmptyNode(IToken payload) + : base(payload) + { + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.TigerType = TigerType.Void; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + // vacío a propósito + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/ForNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/ForNode.cs new file mode 100644 index 0000000..bf71716 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/ForNode.cs @@ -0,0 +1,127 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + /// + /// for id := expr_1 to expr_2 do expr_3; + /// + class ForNode : StatementNode, IBreakeableNode + { + public ForNode(IToken payload) + : base(payload) + { + } + + public TypeNode IdNode { get { return (TypeNode)TigerChildren[0]; } } + public ExpressionNode FromExpression { get { return (ExpressionNode)TigerChildren[1]; } } + public ExpressionNode ToExpression { get { return (ExpressionNode)TigerChildren[2]; } } + public ExpressionNode DoExpression { get { return (ExpressionNode)TigerChildren[3]; } } + + public LabelTarget BreakTarget { get; set; } + private VariableInfo _iterVarInfo; + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.FromExpression.CheckSemantics(scope, report); + this.ToExpression.CheckSemantics(scope, report); + + TigerScope innerScope = scope.CreateChildScope(); + + if (innerScope.CanFindFunVarInfo(this.IdNode.Name, false)) + report.AddWarning(this.Line, this.Column, + "Variable name hides outer scope variable or function: '{0}'.", + this.IdNode.Name); + + _iterVarInfo = new VariableInfo(this.IdNode.Name, new TigerTypeHolder(TigerType.Int), false) { IsReadOnly = true }; + innerScope.Add(_iterVarInfo); + + this.DoExpression.CheckSemantics(innerScope, report); + + if (!this.FromExpression.IsOk || !this.ToExpression.IsOk || !this.DoExpression.IsOk) + { + this.TigerType = TigerType.Error; + return; + } + + if (this.FromExpression.TigerType.Basetype != BaseType.Int || + this.ToExpression.TigerType.Basetype != BaseType.Int) + { + this.TigerType = TigerType.Error; + report.AddError(this.Line, this.Column, + "Type mismatch: Expecting integer (or alias) type on intervals expression: '{0}' and '{1}' were found.", + this.FromExpression.TigerType.Name, + this.ToExpression.TigerType.Name); + return; + } + + if (this.DoExpression.TigerType.Basetype != BaseType.Void) + { + this.TigerType = TigerType.Error; + report.AddError(this.Line, this.Column, + "Type mismatch: Expecting void return type in for expression: '{0}' was found.", + this.DoExpression.TigerType.Name); + return; + } + + this.TigerType = TigerType.Void; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + BreakTarget = Expression.Label(); + ParameterExpression iter = _iterVarInfo.ParameterExpression = + Expression.Parameter(typeof(int), "iter"); + ParameterExpression fromExpr = Expression.Parameter(typeof(int), "fromExpr"); + ParameterExpression toExpr = Expression.Parameter(typeof(int), "toExpr"); + + this.FromExpression.GenerateCode(moduleBuilder); + this.ToExpression.GenerateCode(moduleBuilder); + this.DoExpression.GenerateCode(moduleBuilder); + + BlockExpression blockExpression = Expression.Block( + new ParameterExpression[] { iter, fromExpr, toExpr }, + new Expression[] + { + Expression.Assign(fromExpr, this.FromExpression.VmExpression), + Expression.Assign(toExpr, this.ToExpression.VmExpression), + Expression.Assign(iter, fromExpr), + Expression.Loop(Expression.Block( + Expression.IfThen(Expression.GreaterThan(iter, toExpr), + Expression.Break(BreakTarget)), + this.DoExpression.VmExpression, + Expression.PostIncrementAssign(iter) + ), BreakTarget) + }); + + this.VmExpression = blockExpression; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/IBreakebleNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/IBreakebleNode.cs new file mode 100644 index 0000000..af6d4af --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/IBreakebleNode.cs @@ -0,0 +1,34 @@ +/* + * 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. + * + */ + +using System.Linq.Expressions; + +namespace YATC.ASTNodes +{ + interface IBreakeableNode + { + LabelTarget BreakTarget { get; set; } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/StatementNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/StatementNode.cs new file mode 100644 index 0000000..80e7749 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/StatementNode.cs @@ -0,0 +1,37 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; + +namespace YATC.ASTNodes +{ + abstract class StatementNode : ExpressionNode + { + protected StatementNode(IToken payload) + : base(payload) + { + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/WhileNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/WhileNode.cs new file mode 100644 index 0000000..fe90c3e --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/StatementNode/WhileNode.cs @@ -0,0 +1,94 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class WhileNode : StatementNode, IBreakeableNode + { + public WhileNode(IToken payload) + : base(payload) + { + } + + public LabelTarget BreakTarget { get; set; } + + public ExpressionNode ConditionExpression { get { return (ExpressionNode)TigerChildren[0]; } } + + public ExpressionNode DoExpression { get { return (ExpressionNode)TigerChildren[1]; } } + + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.ConditionExpression.CheckSemantics(scope, report); + this.DoExpression.CheckSemantics(scope, report); + + if (!this.ConditionExpression.IsOk || !this.DoExpression.IsOk) + { + this.TigerType = TigerType.Error; + return; + } + + if (this.ConditionExpression.TigerType.Basetype != BaseType.Int) + { + report.AddError(Line, Column, + "Type mismatch: Expecting integer (or alias) type on condition expression: '{0}' was found.", + this.ConditionExpression.TigerType.Name); + this.TigerType = TigerType.Error; + return; + } + + if (this.DoExpression.TigerType.Basetype != BaseType.Void) + { + this.TigerType = TigerType.Error; + report.AddError(this.Line, this.Column, + "Type mismatch: Expecting void return type in while expression: '{0}' was found.", + this.DoExpression.TigerType.Name); + return; + } + + this.TigerType = TigerType.Void; + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + BreakTarget = Expression.Label(); + + this.ConditionExpression.GenerateCode(moduleBuilder); + this.DoExpression.GenerateCode(moduleBuilder); + + ConditionalExpression conditionalExpression = Expression.IfThenElse( + Expression.NotEqual(this.ConditionExpression.VmExpression, Expression.Constant(0)), + this.DoExpression.VmExpression, + Expression.Break(this.BreakTarget)); + + this.VmExpression = Expression.Loop(conditionalExpression, this.BreakTarget); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/FillInTypeNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/FillInTypeNode.cs new file mode 100644 index 0000000..75c486c --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/FillInTypeNode.cs @@ -0,0 +1,43 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + internal class FillInTypeNode : TypeNode + { + public FillInTypeNode(IToken payload) + : base(payload) + { + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.TigerType = TigerType.FillIn; + } + } +} \ No newline at end of file diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/IdNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/IdNode.cs new file mode 100644 index 0000000..13f640c --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/IdNode.cs @@ -0,0 +1,44 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class IdNode : TypeNode + { + public IdNode(IToken payload) + : base(payload) + { + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + // vacio exprofeso + this.TigerType = TigerType.Unknown; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/TypeNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/TypeNode.cs new file mode 100644 index 0000000..8bbe3f5 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/TypeNode.cs @@ -0,0 +1,69 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System; +using System.Linq.Expressions; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class TypeNode : ExpressionNode + { + public TypeNode(IToken payload) + : base(payload) + { + } + + public string Name { get { return Text; } } + + public override void CheckSemantics(TigerScope scope, Report report) + { + switch (Text) + { + case "int": + TigerType = TigerType.Int; + break; + case "string": + TigerType = TigerType.String; + break; + case "nil": + TigerType = TigerType.Nil; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + internal override void GenerateCode(ModuleBuilder moduleBuilder) + { + Type retType = this.TigerType.GetCLRType(); + this.VmExpression = retType == null + ? (Expression)Expression.Constant(null) + : Expression.Parameter(retType); + } + } +} diff --git a/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/VoidNode.cs b/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/VoidNode.cs new file mode 100644 index 0000000..9a41fbc --- /dev/null +++ b/YATC/ASTNodes/LocalNode/ExpressionNode/TypeNode/VoidNode.cs @@ -0,0 +1,42 @@ +/* + * 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. + * + */ + +using YATC.Scope; + +namespace YATC.ASTNodes +{ + internal class VoidNode : TypeNode + { + public VoidNode() + : base(null) + { + } + + public override void CheckSemantics(TigerScope scope, Report report) + { + this.TigerType = TigerType.Void; + } + } +} diff --git a/YATC/ASTNodes/LocalNode/LocalNode.cs b/YATC/ASTNodes/LocalNode/LocalNode.cs new file mode 100644 index 0000000..ee4d7e4 --- /dev/null +++ b/YATC/ASTNodes/LocalNode/LocalNode.cs @@ -0,0 +1,46 @@ +/* + * 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. + * + */ + +using System.Reflection.Emit; +using Antlr.Runtime; +using System.Linq.Expressions; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + public abstract class LocalNode : TigerNode + { + protected LocalNode(IToken payload) + : base(payload) + { + } + + public abstract void CheckSemantics(TigerScope scope, Report report); + + internal abstract void GenerateCode(ModuleBuilder moduleBuilder); + + public Expression VmExpression; + } +} diff --git a/YATC/ASTNodes/ProgramNode.cs b/YATC/ASTNodes/ProgramNode.cs new file mode 100644 index 0000000..6ec7c2c --- /dev/null +++ b/YATC/ASTNodes/ProgramNode.cs @@ -0,0 +1,221 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using System; +using System.IO; +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + public class ProgramNode : TigerNode + { + public ProgramNode(IToken payload) + : base(payload) + { + Report = new Report(); + Scope = new TigerScope(); + RecordNumber = 0; + AddStdLib(); + } + + public readonly Report Report; + internal readonly TigerScope Scope; + internal static int RecordNumber; + + private FunctionInfo _print; + private FunctionInfo _printLine; + private FunctionInfo _printi; + private FunctionInfo _printiline; + private FunctionInfo _getline; + private FunctionInfo _ord; + private FunctionInfo _chr; + private FunctionInfo _exit; + private FunctionInfo _not; + private FunctionInfo _concat; + private FunctionInfo _substring; + private FunctionInfo _size; + + internal ExpressionNode ExpressionNode { get { return (ExpressionNode)GetChild(0); } } + + public void CheckSemantics() + { + if (this.ExpressionNode != null) + this.ExpressionNode.CheckSemantics(Scope, Report); + } + + public AssemblyBuilder GenerateCode(string name, string fileName, string outputDir) + { + AssemblyName assemblyName = new AssemblyName(name); + AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, + AssemblyBuilderAccess.RunAndSave, + outputDir); + ModuleBuilder moduleBuilder = assembly.DefineDynamicModule(fileName, fileName); + TypeBuilder typeBuilder = moduleBuilder.DefineType("yatcProgram"); + MethodBuilder mainMethod = typeBuilder.DefineMethod("main", MethodAttributes.Static); + + Expression mainBlock; + if (this.ExpressionNode != null) + { + this.ExpressionNode.GenerateCode(moduleBuilder); + + ParameterExpression outcode = Expression.Parameter(typeof(int)); + ParameterExpression exception = Expression.Parameter(typeof(Exception)); + + MemberInfo excMessageMember = typeof(Exception).GetMember("Message")[0]; + MemberInfo consoleError = typeof(Console).GetMember("Error")[0]; + MethodInfo errorWrite = typeof(TextWriter).GetMethod("WriteLine", new Type[] { typeof(string) }); + + mainBlock = Expression.Block( + new ParameterExpression[] { outcode, exception }, + new Expression[] + { + Expression.Assign(outcode, Expression.Constant(0)), + Expression.TryCatch( + Expression.Block( + this.ExpressionNode.VmExpression, + Expression.Empty() + ), + new CatchBlock[] + { + Expression.MakeCatchBlock( + typeof(Exception), + exception, + Expression.Block( + Expression.Call( + Expression.MakeMemberAccess(null, consoleError), + errorWrite, + Expression.MakeMemberAccess(exception, excMessageMember) + ), + Expression.Assign(outcode, Expression.Constant(1)), + Expression.Empty() + ), + Expression.Constant(true) + ) + } + ), + outcode + }); + } + else + { + mainBlock = Expression.Constant(0); + } + + LambdaExpression lambdaMainBlock = Expression.Lambda>(mainBlock); + lambdaMainBlock.CompileToMethod(mainMethod); + assembly.SetEntryPoint(mainMethod); + + typeBuilder.CreateType(); + moduleBuilder.CreateGlobalFunctions(); + return assembly; + } + + private void AddStdLib() + { + var stringHolder = new TigerTypeHolder(TigerType.String); + var intHolder = new TigerTypeHolder(TigerType.Int); + var voidHolder = new TigerTypeHolder(TigerType.Void); + + _print = new FunctionInfo("print", new[] { new VariableInfo("s", stringHolder, true), }, voidHolder, true); + _printLine = new FunctionInfo("printline", new[] { new VariableInfo("s", stringHolder, true), }, voidHolder, true); + _printi = new FunctionInfo("printi", new[] { new VariableInfo("i", intHolder, true), }, voidHolder, true); + _printiline = new FunctionInfo("printiline", new[] { new VariableInfo("i", intHolder, true), }, voidHolder, true); + _getline = new FunctionInfo("getline", new VariableInfo[0], stringHolder, true); + _ord = new FunctionInfo("ord", new[] { new VariableInfo("s", stringHolder, true), }, intHolder, true); + _chr = new FunctionInfo("chr", new[] { new VariableInfo("i", intHolder, true), }, stringHolder, true); + _size = new FunctionInfo("size", new[] { new VariableInfo("s", stringHolder, true), }, intHolder, true); + _substring = new FunctionInfo("substring", new[] + { + new VariableInfo("s", stringHolder, true), + new VariableInfo("f", intHolder, true), + new VariableInfo("n", intHolder, true), + }, + stringHolder, true); + _concat = new FunctionInfo("concat", + new[] + { + new VariableInfo("s1", stringHolder, true), + new VariableInfo("s2", stringHolder, true), + }, + stringHolder, + true); + _not = new FunctionInfo("not", new[] { new VariableInfo("i", intHolder, true), }, intHolder, true); + _exit = new FunctionInfo("exit", new[] { new VariableInfo("i", intHolder, true), }, voidHolder, true); + + Scope.Add(_print); + Scope.Add(_printLine); + Scope.Add(_printi); + Scope.Add(_printiline); + Scope.Add(_getline); + Scope.Add(_ord); + Scope.Add(_chr); + Scope.Add(_size); + Scope.Add(_substring); + Scope.Add(_concat); + Scope.Add(_not); + Scope.Add(_exit); + + Scope.Add(new TigerTypeInfo("string", new TigerTypeHolder(TigerType.String), true)); + Scope.Add(new TigerTypeInfo("int", new TigerTypeHolder(TigerType.Int), true)); + Scope.Add(new TigerTypeInfo("nil", new TigerTypeHolder(TigerType.Nil), true)); + + // althought it is defined and can be returned as a valid program expression it cannot be called by name + Scope.Add(new TigerTypeInfo("!void", new TigerTypeHolder(TigerType.Void), true)); + + MethodInfo writeString = ((Action)Console.Write).Method; + MethodInfo writeLineString = ((Action)Console.WriteLine).Method; + MethodInfo writeInt = ((Action)Console.Write).Method; + MethodInfo writeLineInt = ((Action)Console.WriteLine).Method; + MethodInfo readLine = ((Func)Console.ReadLine).Method; + MethodInfo chr = ((Func)Convert.ToString).Method; + MethodInfo concat = ((Func)string.Concat).Method; + + _print.MethodInfo = writeString; + _printLine.MethodInfo = writeLineString; + _printi.MethodInfo = writeInt; + _printiline.MethodInfo = writeLineInt; + _getline.MethodInfo = readLine; + //_chr.MethodInfo = chr; + _concat.MethodInfo = concat; + + Expression> lambdaChr = (b) => ( new string(Convert.ToChar(((byte)(b) > 127) ? int.MaxValue : (byte)b), 1)); + Expression> lambdaOrd = (x) => (string.IsNullOrEmpty(x) ? -1 : Convert.ToByte(x[0])); + Expression> lambdaSize = (x) => (x.Length); + Expression> lambdaSubstring = (x, y, z) => (x.Substring(y, z)); + Expression> lambdaNot = (x) => (x == 0 ? 1 : 0); + + _ord.LambdaExpression = lambdaOrd; + _size.LambdaExpression = lambdaSize; + _substring.LambdaExpression = lambdaSubstring; + _not.LambdaExpression = lambdaNot; + _chr.LambdaExpression = lambdaChr; + } + + } +} diff --git a/YATC/ASTNodes/TigerNode.cs b/YATC/ASTNodes/TigerNode.cs new file mode 100644 index 0000000..a3de3aa --- /dev/null +++ b/YATC/ASTNodes/TigerNode.cs @@ -0,0 +1,77 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using Antlr.Runtime.Tree; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace YATC.Scope +{ + public abstract class TigerNode : CommonTree + { + protected TigerNode(IToken payload) + : base(payload) + { + } + + public bool IsRoot + { + get { return Parent == null; } + } + + /// + /// Lists all the nodes from current to root + /// + public IEnumerable GetNodesToRoot() + { + if (this.IsRoot) + yield break; + + Debug.Assert(this.Parent is TigerNode); + + var parent = Parent as TigerNode; + yield return parent; + foreach (var item in parent.GetNodesToRoot()) + yield return item; + } + + public int Column { get { return CharPositionInLine; } } + + //public new TigerNode Parent + //{ + // get { return (TigerNode)base.Parent; } + //} + + public TigerNode[] TigerChildren + { + get + { + return base.Children == null ? new TigerNode[0] : base.Children.Cast().ToArray(); + } + } + } +} diff --git a/YATC/ASTNodes/TigerTreeAdaptor.cs b/YATC/ASTNodes/TigerTreeAdaptor.cs new file mode 100644 index 0000000..1f75180 --- /dev/null +++ b/YATC/ASTNodes/TigerTreeAdaptor.cs @@ -0,0 +1,83 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using Antlr.Runtime.Tree; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using YATC.Grammar; + +namespace YATC.ASTNodes +{ + public class TigerTreeAdaptor : CommonTreeAdaptor + { + private readonly Dictionary _payloadCache; + + public TigerTreeAdaptor() + { + _payloadCache = new Dictionary + { + {tigerParser.INTKEY, typeof (TypeNode)}, + {tigerParser.STRINGKEY, typeof (TypeNode)}, + {tigerParser.NILKEY, typeof (TypeNode)} + }; + + FieldInfo[] _fields = typeof(tigerParser).GetFields(); + Assembly executingAssembly = Assembly.GetExecutingAssembly(); + + foreach (var field in _fields) + { + if (!field.IsStatic) + continue; + + string name = GetName(field.Name); + Type type = executingAssembly.GetType(name); + if (type != null) + _payloadCache[(int)field.GetRawConstantValue()] = type; + } + } + + private string GetName(string name) + { + var sb = new StringBuilder(); + foreach (var x in name.Split('_')) + sb.Append(char.ToUpper(x[0]) + x.Substring(1, x.Length - 1).ToLower()); + return string.Format("YATC.ASTNodes.{0}Node", sb); + } + + public override object Create(IToken payload) + { + if (payload == null) + return new UnknownNode(null); + //return base.Create(null); + + Type type; + bool foundType = _payloadCache.TryGetValue(payload.Type, out type); + return foundType ? Activator.CreateInstance(type, payload) : new UnknownNode(payload); + } + } +} diff --git a/YATC/ASTNodes/UtilNode/FieldInstNode.cs b/YATC/ASTNodes/UtilNode/FieldInstNode.cs new file mode 100644 index 0000000..7e69f91 --- /dev/null +++ b/YATC/ASTNodes/UtilNode/FieldInstNode.cs @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; + +namespace YATC.ASTNodes +{ + class FieldInstNode: UtilNode + { + public FieldInstNode(IToken payload) + : base(payload) + { + } + + public IdNode IdNode { get { return (IdNode) TigerChildren[0]; } } + public ExpressionNode ExpressionNode{ get { return (ExpressionNode) TigerChildren[1]; } } + } +} diff --git a/YATC/ASTNodes/UtilNode/TypeFieldNode.cs b/YATC/ASTNodes/UtilNode/TypeFieldNode.cs new file mode 100644 index 0000000..c5f19fe --- /dev/null +++ b/YATC/ASTNodes/UtilNode/TypeFieldNode.cs @@ -0,0 +1,45 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; + +namespace YATC.ASTNodes +{ + /// + /// Declaracion de parametros de funciones y campos en la declaracion de un record. + /// + class TypeFieldNode : UtilNode + { + public TypeFieldNode(IToken payload) + : base(payload) + { + } + + public TypeNode IdNode { get { return (TypeNode)TigerChildren[0]; } } + public TypeNode TypeNode { get { return (TypeNode)TigerChildren[1]; } } + + public string Name { get { return this.IdNode.Name; } } + } +} diff --git a/YATC/ASTNodes/UtilNode/UnknownNode.cs b/YATC/ASTNodes/UtilNode/UnknownNode.cs new file mode 100644 index 0000000..3df89e2 --- /dev/null +++ b/YATC/ASTNodes/UtilNode/UnknownNode.cs @@ -0,0 +1,38 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + class UnknownNode : TigerNode + { + public UnknownNode(IToken payload) + : base(payload) + { + } + } +} diff --git a/YATC/ASTNodes/UtilNode/UtilNode.cs b/YATC/ASTNodes/UtilNode/UtilNode.cs new file mode 100644 index 0000000..21c6a4d --- /dev/null +++ b/YATC/ASTNodes/UtilNode/UtilNode.cs @@ -0,0 +1,38 @@ +/* + * 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. + * + */ + +using Antlr.Runtime; +using YATC.Scope; + +namespace YATC.ASTNodes +{ + abstract class UtilNode : TigerNode + { + protected UtilNode(IToken payload) + : base(payload) + { + } + } +} diff --git a/YATC/Grammar/ParsingException.cs b/YATC/Grammar/ParsingException.cs new file mode 100644 index 0000000..08b248c --- /dev/null +++ b/YATC/Grammar/ParsingException.cs @@ -0,0 +1,46 @@ +/* + * 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. + * + */ + +using System; +using Antlr.Runtime; + +namespace YATC.Grammar +{ + public class ParsingException : Exception + { + public ParsingException(string message, Exception innerException) + : base(message, innerException) + { + } + + public RecognitionException RecognitionError + { + get + { + return InnerException as RecognitionException; + } + } + } +} diff --git a/YATC/Properties/AssemblyInfo.cs b/YATC/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cffb2c8 --- /dev/null +++ b/YATC/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("YATC")] +[assembly: AssemblyDescription("Yet Another Tiger Compiler code base")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("YATC")] +[assembly: AssemblyCopyright("Copyright Damian Valdes Santiago & Juan Carlos Pujol Mainegra © 2013-2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("791f0f8e-42cf-4906-8b7b-8f7b011f7758")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/YATC/Scope/Report/Item.cs b/YATC/Scope/Report/Item.cs new file mode 100644 index 0000000..25f033a --- /dev/null +++ b/YATC/Scope/Report/Item.cs @@ -0,0 +1,43 @@ +/* + * 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. + * + */ + +namespace YATC.ASTNodes +{ + public class Item + { + public Item(Level level, int line, int column, string text) + { + Level = level; + Line = line; + Column = column; + Text = text; + } + + public readonly Level Level; + public readonly int Line; + public readonly int Column; + public readonly string Text; + } +} diff --git a/YATC/Scope/Report/Report.cs b/YATC/Scope/Report/Report.cs new file mode 100644 index 0000000..369cc1c --- /dev/null +++ b/YATC/Scope/Report/Report.cs @@ -0,0 +1,79 @@ +/* + * 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. + * + */ + +using System.Collections; +using System.Collections.Generic; + +namespace YATC.ASTNodes +{ + /// + /// Indica cuán mal es el error + /// + public enum Level { Info = 0, Warning = 1, Error = 2 } + + public class Report : IEnumerable + { + protected readonly List Items = new List(); + public Level Level { get; private set; } + public bool IsOK { get { return Level != Level.Error; } } + + public void AddError(int line, int column, string text, params object[] modifiers) + { + if (Level < Level.Error) + Level = Level.Error; + Items.Add(new Item(Level.Error, line, column, string.Format(text, modifiers))); + } + + public void AddWarning(int line, int column, string text, params object[] modifiers) + { + if (Level < Level.Warning) + Level = Level.Warning; + Items.Add(new Item(Level.Warning, line, column, string.Format(text, modifiers))); + } + + public void AddInfo(int line, int column, string text, params object[] modifiers) + { + if (Level < Level.Info) + Level = Level.Info; + Items.Add(new Item(Level.Info, line, column, string.Format(text, modifiers))); + } + + public void Reset() + { + Level = Level.Info; + Items.Clear(); + } + + public IEnumerator GetEnumerator() + { + return Items.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/YATC/Scope/TigerInfo/FunVarInfo.cs b/YATC/Scope/TigerInfo/FunVarInfo.cs new file mode 100644 index 0000000..5580262 --- /dev/null +++ b/YATC/Scope/TigerInfo/FunVarInfo.cs @@ -0,0 +1,31 @@ +/* + * 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. + * + */ + +namespace YATC.Scope +{ + public abstract class FunVarInfo : TigerTypeInfo + { + } +} diff --git a/YATC/Scope/TigerInfo/FunctionInfo.cs b/YATC/Scope/TigerInfo/FunctionInfo.cs new file mode 100644 index 0000000..c16bba4 --- /dev/null +++ b/YATC/Scope/TigerInfo/FunctionInfo.cs @@ -0,0 +1,60 @@ +/* + * 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. + * + */ + +using System.Linq.Expressions; +using System.Reflection; + +namespace YATC.Scope +{ + public class FunctionInfo : FunVarInfo + { + public FunctionInfo(string name, VariableInfo[] parameterInfo, TigerTypeHolder returnTypeHolder, bool isStandard) + { + this.Name = name; + this.ParameterInfo = parameterInfo; + this.Holder = returnTypeHolder; + this.IsStandard = isStandard; + } + + public FunctionInfo(string name, VariableInfo[] parameterInfo, TigerTypeHolder returnTypeHolder, + MethodInfo methodInfo) + :this(name, parameterInfo, returnTypeHolder, true) + { + this.MethodInfo = methodInfo; + } + + public MethodInfo MethodInfo; + + /// + /// Listado de parámetros + /// + public readonly VariableInfo[] ParameterInfo; + + /// + /// Función en la máquina virtual correspondiente + /// + public Expression LambdaExpression; + } +} diff --git a/YATC/Scope/TigerInfo/TigerInfo.cs b/YATC/Scope/TigerInfo/TigerInfo.cs new file mode 100644 index 0000000..377f575 --- /dev/null +++ b/YATC/Scope/TigerInfo/TigerInfo.cs @@ -0,0 +1,48 @@ +/* + * 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. + * + */ + +namespace YATC.Scope +{ + /// + /// Describe la existencia de un símbolo en la tabla de símbolos + /// + public abstract class TigerInfo + { + /// + /// Nombre del atributo + /// + public string Name { get; set; } + + /// + /// Tipo del atributo (si es una función indica tipo de retorno) + /// + public TigerTypeHolder Holder { get; set; } + + /// + /// Indica si es del sistema + /// + public bool IsStandard; + } +} diff --git a/YATC/Scope/TigerInfo/TigerTypeInfo.cs b/YATC/Scope/TigerInfo/TigerTypeInfo.cs new file mode 100644 index 0000000..440ce6a --- /dev/null +++ b/YATC/Scope/TigerInfo/TigerTypeInfo.cs @@ -0,0 +1,45 @@ +/* + * 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. + * + */ + +using System; + +namespace YATC.Scope +{ + public class TigerTypeInfo: TigerInfo + { + internal TigerTypeInfo() + { + } + + public TigerTypeInfo(string name, TigerTypeHolder holder, bool isStandard) + { + if (holder == null) + throw new ArgumentNullException("holder"); + this.Name = name; + this.Holder = holder; + this.IsStandard = isStandard; + } + } +} diff --git a/YATC/Scope/TigerInfo/VariableInfo.cs b/YATC/Scope/TigerInfo/VariableInfo.cs new file mode 100644 index 0000000..5c2db74 --- /dev/null +++ b/YATC/Scope/TigerInfo/VariableInfo.cs @@ -0,0 +1,55 @@ +/* + * 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. + * + */ + +using System.Linq.Expressions; + +namespace YATC.Scope +{ + public class VariableInfo : FunVarInfo + { + /// + /// Determina si el atributo es un paramétro o no + /// + public bool IsParameter { get; set; } + + /// + /// Whether the variable cannot be a left value of an assignment + /// + public bool IsReadOnly { get; set; } + + /// + /// Refleja una variable dentro del ejecutable para la generación de código + /// + public ParameterExpression ParameterExpression { get; set; } + + public VariableInfo(string name, TigerTypeHolder holder, bool isParameter) + { + this.Name = name; + this.Holder = holder; + this.IsParameter = isParameter; + } + + } +} diff --git a/YATC/Scope/TigerScope.cs b/YATC/Scope/TigerScope.cs new file mode 100644 index 0000000..de3ea63 --- /dev/null +++ b/YATC/Scope/TigerScope.cs @@ -0,0 +1,169 @@ +/* + * 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. + * + */ + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace YATC.Scope +{ + /// + /// Implementa la tabla de símbolos junto a TigerGlobal + /// + public class TigerScope + { + public TigerScope() + { + } + + private TigerScope(TigerScope parent, int parentIndex) + { + Parent = parent; + ParentIndex = parentIndex; + } + + private int _index; + + /// + /// Ambito padre que contiene a este scope + /// + public readonly TigerScope Parent; + + /// + /// Permite ver variables del padre de 0 a ParentIndex + /// + public readonly int ParentIndex; + + public bool IsRoot { get { return Parent == null; } } + + private readonly List _children = new List(); + private readonly HashSet _typeInfos = new HashSet(); + private readonly HashSet _funVarInfos = new HashSet(); + + public TigerScope[] GetChildren() + { + return _children.ToArray(); + } + + public TigerScope CreateChildScope() + { + return new TigerScope(this, _index); + } + + public bool Add(VariableInfo variableInfo) + { + Debug.WriteLine("Added to variable scope: {0} of type {1}", + variableInfo.Name, + variableInfo.Holder.TigerType != null ? variableInfo.Holder.TigerType.Name : "null"); + return _funVarInfos.Add(variableInfo) && ++_index != 0; + } + + public bool Add(FunctionInfo functionInfo) + { + Debug.WriteLine("Added to function scope: {0} of type {1}", + functionInfo.Name, + functionInfo.Holder.TigerType.Name); + return _funVarInfos.Add(functionInfo) && ++_index != 0; + } + + public bool Add(TigerTypeInfo tigerTypeInfo) + { + Debug.WriteLine("Added to type scope: {0} of type {1}", + tigerTypeInfo.Name, + tigerTypeInfo.Holder.TigerType != null ? tigerTypeInfo.Holder.TigerType.Name: "null"); + return _typeInfos.Add(tigerTypeInfo) && ++_index != 0; + } + + public bool ContainsType(TigerType tigerType, bool localSearchOnly) + { + bool isLocal = _typeInfos.Any(x => x.Holder.TigerType.Equals(tigerType)); + return isLocal || (!localSearchOnly && !IsRoot && Parent.ContainsType(tigerType, false)); + } + + public VariableInfo[] GetLocalVariableInfos() + { + return _funVarInfos.Where(x => x is VariableInfo).Cast().ToArray(); + } + + public VariableInfo FindVariableInfo(string name, bool localSearchOnly) + { + var result = _funVarInfos.FirstOrDefault(x => x.Name == name); + if (result is FunctionInfo) + return null; + return (VariableInfo)result ?? (!localSearchOnly && !IsRoot ? Parent.FindVariableInfo(name, false) : null); + } + + public bool CanFindVariableInfo(string name, bool localSearchOnly) + { + return FindVariableInfo(name, localSearchOnly) != null; + } + + public TigerTypeInfo[] GetLocalTypeInfos() + { + return _typeInfos.ToArray(); + } + + public TigerTypeInfo FindTypeInfo(string name, bool localSearchOnly) + { + var result = _typeInfos.FirstOrDefault(x => x.Name == name); + return result ?? (!localSearchOnly && !IsRoot ? Parent.FindTypeInfo(name, false) : null); + } + + public bool CanFindTypeInfo(string name, bool localSearchOnly) + { + return FindTypeInfo(name, localSearchOnly) != null; + } + + public FunctionInfo[] GetFunctionInfos() + { + return _funVarInfos.Where(x => x is FunctionInfo).Cast().ToArray(); + } + + public FunctionInfo FindFunctionInfo(string name, bool localSearchOnly) + { + FunVarInfo result = _funVarInfos.FirstOrDefault(x => x.Name == name); + if (result is VariableInfo) + return null; + return (FunctionInfo)result ?? (!localSearchOnly && !IsRoot ? Parent.FindFunctionInfo(name, false) : null); + } + + public bool CanFindFunctionInfo(string name, bool localSearchOnly) + { + return FindFunctionInfo(name, localSearchOnly) != null; + } + + public FunVarInfo FindFunVarInfo(string name, bool localSearchOnly) + { + FunVarInfo result = _funVarInfos.FirstOrDefault(x => x.Name == name); + return result ?? (!localSearchOnly && !IsRoot ? Parent.FindFunctionInfo(name, false) : null); + } + + public bool CanFindFunVarInfo(string name, bool localSearchOnly) + { + return FindFunVarInfo(name, localSearchOnly) != null; + } + + } +} diff --git a/YATC/Scope/TigerType/ArrayType.cs b/YATC/Scope/TigerType/ArrayType.cs new file mode 100644 index 0000000..eb8b7c3 --- /dev/null +++ b/YATC/Scope/TigerType/ArrayType.cs @@ -0,0 +1,38 @@ +/* + * 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. + * + */ + +namespace YATC.Scope +{ + public class ArrayType: TigerType + { + public ArrayType(string name, TigerTypeHolder elementTypeHolder) + : base(name, BaseType.Array) + { + this.ElementTypeHolder = elementTypeHolder; + } + + public TigerTypeHolder ElementTypeHolder { get; internal set; } + } +} diff --git a/YATC/Scope/TigerType/RecordType.cs b/YATC/Scope/TigerType/RecordType.cs new file mode 100644 index 0000000..b87c193 --- /dev/null +++ b/YATC/Scope/TigerType/RecordType.cs @@ -0,0 +1,38 @@ +/* + * 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. + * + */ + +namespace YATC.Scope +{ + public class RecordType: TigerType + { + public RecordType(string name, VariableInfo[] fieldInfos) + : base(name, BaseType.Record) + { + this.FieldInfos = fieldInfos; + } + + public VariableInfo[] FieldInfos { get; internal set; } + } +} diff --git a/YATC/Scope/TigerType/TigerType.cs b/YATC/Scope/TigerType/TigerType.cs new file mode 100644 index 0000000..0e0e019 --- /dev/null +++ b/YATC/Scope/TigerType/TigerType.cs @@ -0,0 +1,105 @@ +/* + * 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. + * + */ + +using System; +using System.Diagnostics; + +namespace YATC.Scope +{ + public enum BaseType + { + Error = -1, + Int = 0, + String = 1, + Nil = 2, + Record = 3, + Array = 4, + Void = 5, + FillIn = 6, + Unknown = 7 + } + + public class TigerType + { + public string Name { get; protected set; } + public BaseType Basetype { get; private set; } + + public Type CLRType { get; set; } + + protected TigerType(string name, BaseType basetype) + { + this.Name = name; + this.Basetype = basetype; + } + + protected TigerType(BaseType baseType) + : this(baseType.ToString().ToLowerInvariant(), baseType) + { + } + + public virtual Type GetCLRType() + { + if (CLRType != null) + return CLRType; + + switch (Basetype) + { + case BaseType.Int: + return typeof(int); + case BaseType.String: + return typeof(string); + case BaseType.Void: + return typeof(void); + case BaseType.Nil: + return null; + case BaseType.Array: + return (this as ArrayType).ElementTypeHolder.TigerType.GetCLRType().MakeArrayType(); + default: + throw new IndexOutOfRangeException(); + } + } + + public static readonly TigerType Error = new TigerType(BaseType.Error); + public static readonly TigerType Int = new TigerType(BaseType.Int); + public static readonly TigerType String = new TigerType(BaseType.String); + public static readonly TigerType Nil = new TigerType(BaseType.Nil); + public static readonly TigerType Void = new TigerType(BaseType.Void); + public static readonly TigerType FillIn = new TigerType(BaseType.FillIn); + public static readonly TigerType Unknown = new TigerType(BaseType.Unknown); + + public virtual bool IsAssignableTo(TigerType other) + { + bool result = this.Equals(other) || + (this.Basetype != BaseType.Record && + this.Basetype != BaseType.Array && this.Basetype == other.Basetype) || + (this.Basetype == BaseType.Nil && other.Basetype == BaseType.Array) || + (this.Basetype == BaseType.Nil && other.Basetype == BaseType.Record) || + (this.Basetype == BaseType.Nil && other.Basetype == BaseType.String); + Debug.WriteLine("Typesystem ruled that '{0}' {2} assignable to '{1}'.", + this.Name, other.Name, result ? "is" : "is NOT"); + return result; + } + } +} diff --git a/YATC/Scope/TigerType/TigerTypeHolder.cs b/YATC/Scope/TigerType/TigerTypeHolder.cs new file mode 100644 index 0000000..c5df682 --- /dev/null +++ b/YATC/Scope/TigerType/TigerTypeHolder.cs @@ -0,0 +1,41 @@ +/* + * 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. + * + */ + +namespace YATC.Scope +{ + public class TigerTypeHolder + { + public TigerTypeHolder() + { + } + + public TigerTypeHolder(TigerType tigerType) + { + this.TigerType = tigerType; + } + + public TigerType TigerType; + } +} diff --git a/YATC/YATC.csproj b/YATC/YATC.csproj new file mode 100644 index 0000000..9a13653 --- /dev/null +++ b/YATC/YATC.csproj @@ -0,0 +1,145 @@ + + + + + Debug + AnyCPU + {D62DA087-4724-49A3-91B5-83689F442747} + Library + Properties + YATC + YATC.Base + v4.0 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\Antlr3.Runtime.dll + + + + + + + + + + + + Grammar\tigerLexer.cs + + + Grammar\tigerParser.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Grammar\tiger.g + MSBuild:Compile + YATC.Grammar + + + + + \ No newline at end of file