From 8f93fea9100be0f23b30ed0e0b51723276277291 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 4 Mar 2022 17:54:25 +0300 Subject: [PATCH 1/4] Parser and Lexer are changed --- lexer.l | 133 +--- parser.y | 264 +------ src/Parser/LexerAnaltsis.java | 1066 ++++++++++++++++++++++++++ src/Parser/Parser.java | 1336 +++++++++++++++++++++++++++++++++ 4 files changed, 2404 insertions(+), 395 deletions(-) create mode 100644 src/Parser/LexerAnaltsis.java create mode 100644 src/Parser/Parser.java diff --git a/lexer.l b/lexer.l index b69f4c2..9c54124 100644 --- a/lexer.l +++ b/lexer.l @@ -1,132 +1 @@ -import java.util.*; - -%% -%class lexer -%standalone -%unicode -%type JavaType -%line -%column -%byaccj - - -/* main character classes */ -LineTerminator = \r|\n|;|\r\n -InputCharacter = [^\r\n] - -WhiteSpace = {LineTerminator} | [ \t\f] - -/* comments */ -Comment = {TraditionalComment} | {EndOfLineComment} - -TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" -EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? - -/* identifiers -Identifier = [:jletter:][:jletterdigit:]* */ - -/* integer literals */ -IntegerLiteral = 0 | [1-9][0-9]* - -/* Real number literals */ -RealLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] - -FLit1 = [0-9]+ \. [0-9]* -FLit2 = \. [0-9]+ -FLit3 = [0-9]+ -Exponent = [eE] [+-]? [0-9]+ - - -/* string literals */ -StringCharacter = [^\r\n\"\\] -SingleCharacter = [^\r\n\'\\] - -UNKNOWN_TOKEN = . - -%state STRING, CHARLITERAL - -%% - { - - /* keywords */ - "is" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "var" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "if" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "then" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "then" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "else" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "end" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "while" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "for" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "loop" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "return" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "print" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - "funct" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.KEYWORD; } - - - /* boolean literals */ - "true" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.BOOLEAN_LITERAL; } - "false" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.BOOLEAN_LITERAL; } - - - /* separators */ - "(" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.LPAREN; } - ")" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.RPAREN; } - "{" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.LBRACE; } - "}" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.RBRACE; } - "[" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.LBRACK; } - "]" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.RBRACK; } - ";" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.SEMICOLON; } - "," { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.COMMA; } - "." { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.DOT; } - - /* operators */ - "=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.EQ; } - ":=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.ASSIGN; } - ">" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.GT; } - "<" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.LT; } - "<=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.LTEQ; } - ">=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.GTEQ; } - "+" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.PLUS; } - "-" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.MINUS; } - "*" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.MULT; } - "/" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.DIV; } - "=>" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.EXPR; } - "or" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.TOKEN_OR; } - "and" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.TOKEN_AND; } - "xor" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.TOKEN_XOR; } - - /* numeric literals */ - - {IntegerLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.INTEGER_LITERAL; } - {RealLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.REAL_LITERAL; } - - /* comments */ - {Comment} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.COMMENT; } - - /* whitespace */ - {WhiteSpace} { return ParserLexer.WHITESPACE; } - - { - \" { yybegin(YYINITIAL); return ParserLexer.STRING } - - {StringCharacter}+ { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return ParserLexer.STRING; } - - /* escape sequences */ - "\\n" { return ParserLexer.STRING; } - "\\\"" { return ParserLexer.STRING; } - "\\'" { return ParserLexer.STRING; } - "\\\\" { return ParserLexer.STRING; } - - /* error cases */ - \\. { throw new RuntimeException("Illegal escape sequence \""+yytext()+"\""); } - {LineTerminator} { throw new RuntimeException("Unterminated string at end of line"); } -} - -/* UNKNOWN TOKENS */ -{UNKNOWN_TOKEN} {return ParserLexer.UNKNOWN_TOKEN;} - -/* error fallback */ -[^] { throw new RuntimeException("Illegal character \""+yytext()+"\" at line "+yyline+", column "+yycolumn); } -<> { return ParserLexer.EOF; } - +import java.util.*; %% %class Parser.Lexer %standalone %unicode %type JavaType %line %column %byaccj /* main character classes */ LineTerminator = \r|\n|\r\n Semicolon = ; Digit = [0-9] Letter = [a-zA-Z] LetterOrDigit = [a-zA-Z0-9] WhiteSpace = {LineTerminator} | [ \t\f] /* comments */ Comment = {TraditionalComment}|{EndOfLineComment} TraditionalComment = "/\**\*/" EndOfLineComment = "//*{LineTerminator}?" /* identifiers */ Identifier = {Letter}{LetterOrDigit}* /* integer literals */ IntegerLiteral = 0 | [1-9][0-9]* /* Real number literals */ RealLiteral = ({FLit1}|{FLit2}|{FLit3}){Exponent}?[fF] FLit1 = [0-9]+\.[0-9]* FLit2 = \.[0-9]+ FLit3 = [0-9]+ Exponent = [eE][+-]?[0-9]+ UNKNOWN_TOKEN = . %state STRING %% { /* keywords */ "is" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_IS; } "var" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_VAR; } "if" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_IF; } "then" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_THEN; } "else" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_ELSE; } "end" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_END; } "while" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_WHILE; } "for" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FOR; } "loop" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_LOOP; } "return" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_RETURN; } "print" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_PRINT; } "func" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FUNC; } /* boolean literals */ "true" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_TRUE; } "false" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FALSE; } /* separators */ "(" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LPAREN; } ")" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RPAREN; } "{" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LBRACE; } "}" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RBRACE; } "[" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LBRACK; } "]" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RBRACK; } ";" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.SEMICOLON; } "," { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.COMMA; } "." { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.DOT; } /* operators */ "=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.EQ; } ":=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.ASSIGN; } ">" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.GT; } "<" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LT; } "<=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LTEQ; } ">=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.GTEQ; } "+" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.PLUS; } "-" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.MINUS; } "*" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.MULT; } "/" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.DIV; } "=>" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LAMBDA; } "or" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.OR; } "and" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.AND; } "xor" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.XOR; } /* numeric literals */ {IntegerLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.INTEGER_LITERAL; } {RealLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.REAL_LITERAL; } {Identifier} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.IDENTIFIER; } /* comments */ {Comment} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.COMMENT; } /* whitespace */ {WhiteSpace} { return Lexeme.WHITESPACE; } "\"([^\\\"\n\r]*\\[^\n\r])*\"" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.STRING; } } /* UNKNOWN TOKENS */ {UNKNOWN_TOKEN} {return Lexeme.UNKNOWN_TOKEN;} /* error fallback */ [^] { throw new RuntimeException("Illegal character \""+yytext()+"\" at line "+yyline+", column "+yycolumn); } <> { return Lexeme.EOF; } \ No newline at end of file diff --git a/parser.y b/parser.y index a250a4d..178fcb9 100644 --- a/parser.y +++ b/parser.y @@ -1,263 +1 @@ -%define api.prefix {Parser} -%define api.parser.class {Parser} -%define api.parser.public -%define parse.error verbose - -%code imports{ - import java.io.InputStream; - import java.io.InputStreamReader; - import java.io.Reader; - import java.io.IOException; -} - - -%code { - public static void main(String args[]) throws IOException { - ParserLexer lexer = new ParserLexer(System.in); - Parser p = new Parser(lexer); - if(parser.parse()) - System.out.println("---------------------\n Parser Completed Successfully!"); - return; - } -} - -//All keywords -%token KEYWORD - -//Boolean -%token BOOLEAN_LITERAL - -// Separators -%token LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK SEMICOLON COMMA DOT - -// Operators -%token EQ ASSIGN GT LT LTEQ GTEQ PLUS MINUS MULT DIV EXPR TOKEN_OR TOKEN_AND TOKEN_XOR - -// Numeric -%token INTEGER_LITERAL REAL_LITERAL - -//Other tokens -%token COMMENT WHITESPACE STRING UNKNOWN_TOKEN EOF - -// TYpe declaration -%union { - //Node *node; - NProgram *program; - NInstruction *instruction; - NBlock *block; - NDeclaration *declaration; - NArray *array; - NTuple *tuple; - NStatement *statement; - NAssignment *assignment; - NPrint *print; - NFunctionDefinition *funcdef; - NParameters *param; - NIf *ifstmt; - NIfElse *ifelse; - NLoop *loop; - NReturn *returnstmt; - - NExpression *expression; - NIdentifier *identifier; - NIntegerLiteral *integer_lit; - NReal *real; - NBool *boolstmt; - NStringLiteral *string_lit; - NBinaryOperator *binaryop; - NTypeCheck *typecheck; - NUnary *unary; - NReadInput *readinput; - std::vector *variableVector; - std::vector *statementVector; - std::vector *expressionVector; - std::vector *paramVector; - - std::string *string; - int token; -} - -%type Body LoopBody Prog -%type Declaration -%type Statement -%type Expression Relation Factor Term Unary Primary Literal -%type FunctionLiteral -%type ArrayLiteral TupleLiteral -%type Assignment Return If Loop -%type Print Expressions -%type Identifiers Parameters -%type TypeIndicator - -%% -Prog : Body -; - -Body : /* empty */ //{$$ = NULL; } - | Declaration Body - | Statement Body - | Expression Body -; - -Declaration : KEYWORD STRING SEMICOLON - | KEYWORD STRING ASSIGN Expression SEMICOLON -; - -Expression : Relation - | Relation TOKEN_AND Relation {$$ = $1 && $3; } - | Relation TOKEN_OR Relation {$$ = $1 || $3; } - | Relation TOKEN_XOR Relation {$$ = ($1 || $3)&&(!$1 || !$3); } -; - -Relation : Factor - | Factor LT Factor {$$ = $1 < $3; } - | Factor LTEQ Factor {$$ = $1 <= $3; } - | Factor GT Factor {$$ = $1 > $3; } - | Factor GTEQ Factor {$$ = $1 >= $3; } - | Factor EQ Factor {$$ = $1 == $3; } -; - -Factor : Term - | Term PLUS Factor {$$ = $1 + $3; } - | Term MINUS Factor {$$ = $1 - $3; } -; - -Term : Unary - | Unary MULT Term {$$ = $1 * $3; } - | Unary DIV Term {$$ = $1 / $3; } -; - -Unary : Primary - | PLUS Primary - | MINUS Primary - | Literal - | LPAREN Expression RPAREN - | PLUS Primary KEYWORD TypeIndicator - | MINUS Primary KEYWORD TypeIndicator - | Primary KEYWORD TypeIndicator -; - -Primary : TOKEN_IDENTIFIER Tails - | TOKEN_READINT {scanf("%d", &$1); $$ = $1; } - | TOKEN_READREAL //{scanf("%f", &$1); $$ = $1; } - | TOKEN_READSTRING //{scanf("%s", $1); $$ = $1; } -; - -Tails : /* empty */ //{$$ = NULL; } - | Tail Tails -; - -Tail : TOKEN_DOT TOKEN_INT_LITERAL - | TOKEN_DOT TOKEN_IDENTIFIER - | TOKEN_LSQUARE Expression TOKEN_RSQUARE - | TOKEN_LPAREN Expressions TOKEN_RPAREN -; - -Statement : Assignment - | Print - | Return - | If - | Loop -; - -Assignment : Primary TOKEN_ASSIGNMENT Expression TOKEN_SEMI //{$$ = $1 = $3; } -; - -Print : TOKEN_PRINT Expressions TOKEN_SEMI -; - -Expressions : Expression - | Expression TOKEN_COMMA Expressions -; - -Return : TOKEN_RETURN Expression TOKEN_SEMI //{$$ = return $2; } - | TOKEN_RETURN TOKEN_SEMI //{$$ = NULL; } -; - -If : TOKEN_IF Expression TOKEN_THEN Body TOKEN_END //{$$ = if_statement($2, $4, NULL); } - | TOKEN_IF Expression TOKEN_THEN Body TOKEN_ELSE Body TOKEN_END //{$$ = if_statement($2, $4, $6); } -; - -Loop : TOKEN_WHILE Expression LoopBody - | TOKEN_FOR TOKEN_IDENTIFIER TOKEN_IN TypeIndicator LoopBody -; - -LoopBody : TOKEN_LOOP Body TOKEN_END -; - -TypeIndicator : TOKEN_INT //{$$ = "int";} - | TOKEN_REAL //{$$ = "float";} - | TOKEN_BOOL //{$$ = "bool";} - | TOKEN_STRING //{$$ = "string";} - | TOKEN_EMPTY //{$$ = "empty";} - | ArrayLiteral - | TupleLiteral - | TOKEN_FUNC -; - -Literal : TOKEN_INT_LITERAL - | TOKEN_REAL_LITERAL - | TOKEN_TRUE - | TOKEN_FALSE - | TOKEN_STRING_LITERAL - | ArrayLiteral - | TupleLiteral - | FunctionLiteral -; - -ArrayLiteral : TOKEN_LSQUARE TOKEN_RSQUARE - | TOKEN_LSQUARE Expressions TOKEN_RSQUARE -; - -TupleLiteral : TOKEN_LCURLY TOKEN_RCURLY - | TOKEN_LCURLY TOKEN_IDENTIFIER TupleTail - | TOKEN_LCURLY TOKEN_IDENTIFIER TOKEN_ASSIGNMENT Expression TupleTail -; - -TupleTail : TOKEN_RCURLY - | TOKEN_COMMA TOKEN_IDENTIFIER TupleTail - | TOKEN_COMMA TOKEN_IDENTIFIER TOKEN_ASSIGNMENT Expression TupleTail -; - -FunctionLiteral : TOKEN_FUNC FunBody - | TOKEN_FUNC Parameters FunBody -; - -Parameters : TOKEN_LPAREN Identifiers TOKEN_RPAREN -; - -Identifiers : TOKEN_IDENTIFIER - | TOKEN_IDENTIFIER TOKEN_COMMA Identifiers -FunBody : TOKEN_IS Body TOKEN_END - | TOKEN_FUNCTOR Expression - ; - - -%% - - -class ParserLexer implements Parser.Lexer { - InputStreamReader it; - Yylex yylex; - - public ParserLexer(InputStream is){ - it = new InputStreamReader(is); - yylex = new Yylex(it); - } - - @Override - public void yyerror (String s){ - System.out.println("---------------------\nParser Completed with some errors"); - System.err.println("\t-> Error: " + s); - } - - @Override - public Object getLVal() { - return null; - } - - @Override - public int yylex () throws IOException{ - int token = yylex.yylex(); - return token; - } -} +%define api.prefix {Parser} %define api.parser.class {Parser} %define api.parser.public %define parse.error verbose %code imports{ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.IOException; } %code { public static void main(String args[]) throws IOException { ParserLexer lexer = new ParserLexer(System.in); Parser p = new Parser(lexer); if(parser.parse()) System.out.println("---------------------\n Parser Completed Successfully!"); return; } } %left PLUS MINUS %left MULT DIV //All keywords %token KW_IF KW_IS KW_VAR KW_END //Boolean %token BOOLEAN_LITERAL // Separators %token LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK SEMICOLON COMMA DOT // Operators %token EQ ASSIGN GT LT LTEQ GTEQ PLUS MINUS MULT DIV OR AND XOR NOT // Numeric %token INTEGER_LITERAL REAL_LITERAL //Other tokens %token COMMENT WHITESPACE STRING UNKNOWN_TOKEN EOF IDENTIFIER %% Prog : Body ; Body : /* empty */ | Declaration Body | Statement Body | Expression Body ; Declaration : KW_VAR IDENTIFIER SEMICOLON | KW_VAR IDENTIFIER ASSIGN Expression SEMICOLON | KW_VAR IDENTIFIER ASSIGN FunctionDef SEMICOLON ; Expression : | FunctionCall | Calc | Relation | IDENTIFIER | Value ; Relation : Expression LT Expression | Expression LTEQ Expression | Expression GT Expression | Expression GTEQ Expression | Expression EQ Expression | Expression AND Expression | Expression OR Expression | Expression XOR Expression | NOT Expression ; Calc : Expression PLUS Expression | Expression MINUS Expression | Expression MULT Expression | Expression DIV Expression ; Value : STRING | INTEGER_LITERAL | REAL_LITERAL ; FunctionDef : LPAREN Params RPAREN KW_IS Body KW_END ; FunctionCall : IDENTIFIER LPAREN Args RPAREN ; Params: //empty | IDENTIFIER COMMA Params ; Args: //empty | Expression COMMA Args ; %% class ParserLexer implements Parser.Lexer { InputStreamReader it; Yylex yylex; public ParserLexer(InputStream is){ it = new InputStreamReader(is); yylex = new Yylex(it); } @Override public void yyerror (String s){ System.out.println("---------------------\nParser Completed with some errors"); System.err.println("\t-> Error: " + s); } @Override public Object getLVal() { return null; } @Override public int yylex () throws IOException{ int token = yylex.yylex(); return token; } } \ No newline at end of file diff --git a/src/Parser/LexerAnaltsis.java b/src/Parser/LexerAnaltsis.java new file mode 100644 index 0000000..065d054 --- /dev/null +++ b/src/Parser/LexerAnaltsis.java @@ -0,0 +1,1066 @@ +package Parser;// DO NOT EDIT +// Generated by JFlex 1.8.2 http://jflex.de/ +// source: lexer.l + +import Parser.Parser; + +import java.util.*; + +// See https://github.com/jflex-de/jflex/issues/222 +@SuppressWarnings("FallThrough") +class LexerAnalysis { + + /** This character denotes the end of file. */ + public static final int YYEOF = -1; + + /** Initial size of the lookahead buffer. */ + private static final int ZZ_BUFFERSIZE = 16384; + + // Lexical states. + public static final int YYINITIAL = 0; + public static final int STRING = 2; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int[] ZZ_LEXSTATE = { + 0, 1, 2, 3 + }; + + /** + * Top-level table for translating characters to character classes + */ + private static final int [] ZZ_CMAP_TOP = zzUnpackcmap_top(); + + private static final String ZZ_CMAP_TOP_PACKED_0 = + "\1\0\37\u0100\1\u0200\267\u0100\10\u0300\u1020\u0100"; + + private static int [] zzUnpackcmap_top() { + int [] result = new int[4352]; + int offset = 0; + offset = zzUnpackcmap_top(ZZ_CMAP_TOP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackcmap_top(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Second-level tables for translating characters to character classes + */ + private static final int [] ZZ_CMAP_BLOCKS = zzUnpackcmap_blocks(); + + private static final String ZZ_CMAP_BLOCKS_PACKED_0 = + "\11\0\1\1\1\2\1\3\1\4\1\5\22\0\1\1"+ + "\1\0\1\6\5\0\1\7\1\10\1\11\1\12\1\13"+ + "\1\14\1\15\1\16\1\17\11\20\1\21\1\22\1\23"+ + "\1\24\1\25\1\26\1\0\4\27\1\30\1\31\5\27"+ + "\1\32\7\27\1\33\6\27\1\34\1\35\1\36\1\37"+ + "\2\0\1\40\1\27\1\41\1\42\1\43\1\44\1\27"+ + "\1\45\1\46\2\27\1\47\1\50\1\51\1\52\1\53"+ + "\1\27\1\54\1\55\1\56\1\57\1\60\1\61\1\62"+ + "\2\27\1\63\1\0\1\64\7\0\1\3\u01a2\0\2\3"+ + "\326\0\u0100\3"; + + private static int [] zzUnpackcmap_blocks() { + int [] result = new int[1024]; + int offset = 0; + offset = zzUnpackcmap_blocks(ZZ_CMAP_BLOCKS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackcmap_blocks(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\4\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7"+ + "\1\10\1\11\1\12\2\13\1\1\1\14\1\15\1\16"+ + "\1\17\1\20\1\21\1\22\15\20\1\23\1\24\6\0"+ + "\1\25\1\13\1\26\1\27\1\30\7\20\1\31\1\32"+ + "\1\33\2\20\1\34\7\20\5\0\1\35\1\20\1\36"+ + "\1\20\1\37\2\20\1\40\4\20\1\41\1\20\1\42"+ + "\2\0\1\43\1\20\1\44\1\45\2\20\1\46\1\47"+ + "\1\20\2\0\1\50\1\51\1\20\1\52\2\0\1\53"+ + "\45\0\1\54"; + + private static int [] zzUnpackAction() { + int [] result = new int[148]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\0\0\65\0\65\0\152\0\152\0\152\0\152"+ + "\0\152\0\152\0\152\0\152\0\237\0\324\0\u0109\0\u013e"+ + "\0\u0173\0\152\0\u01a8\0\152\0\u01dd\0\u0212\0\152\0\152"+ + "\0\u0247\0\u027c\0\u02b1\0\u02e6\0\u031b\0\u0350\0\u0385\0\u03ba"+ + "\0\u03ef\0\u0424\0\u0459\0\u048e\0\u04c3\0\152\0\152\0\u04f8"+ + "\0\u052d\0\u0562\0\u0597\0\u0109\0\u05cc\0\152\0\u013e\0\152"+ + "\0\152\0\152\0\u0212\0\u0601\0\u0636\0\u066b\0\u06a0\0\u06d5"+ + "\0\u070a\0\u0212\0\u0212\0\u0212\0\u073f\0\u0774\0\u0212\0\u07a9"+ + "\0\u07de\0\u0813\0\u0848\0\u087d\0\u08b2\0\u08e7\0\u091c\0\u0951"+ + "\0\u0597\0\u0986\0\u09bb\0\u0212\0\u09f0\0\u0212\0\u0a25\0\u0212"+ + "\0\u0a5a\0\u0a8f\0\u0212\0\u0ac4\0\u0af9\0\u0b2e\0\u0b63\0\u0212"+ + "\0\u0b98\0\u0212\0\u0bcd\0\u0c02\0\u0212\0\u0c37\0\u0212\0\u0212"+ + "\0\u0c6c\0\u0ca1\0\u0212\0\u0212\0\u0cd6\0\u0d0b\0\u0d40\0\u0212"+ + "\0\u0212\0\u0d75\0\u0212\0\u0daa\0\u0ddf\0\u0212\0\u0e14\0\u0e14"+ + "\0\u0e49\0\u0e7e\0\u0eb3\0\u0e14\0\u0ee8\0\u0f1d\0\u0f52\0\u0f87"+ + "\0\u0fbc\0\u0ff1\0\u1026\0\u105b\0\u1090\0\u10c5\0\u10fa\0\u112f"+ + "\0\u1164\0\u1199\0\u11ce\0\u1203\0\u1238\0\u126d\0\u12a2\0\u12d7"+ + "\0\u130c\0\u1341\0\u1376\0\u13ab\0\u0d0b\0\u13e0\0\u1415\0\u144a"+ + "\0\u147f\0\u14b4\0\u14e9\0\152"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[148]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\2\5\4\6\1\5\1\7\1\10\1\11\1\12\1\13"+ + "\1\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23"+ + "\1\24\1\25\1\5\5\26\1\27\1\5\1\30\1\5"+ + "\1\31\2\26\1\32\1\33\1\26\1\34\1\35\1\26"+ + "\1\36\1\37\1\40\1\41\1\26\1\42\1\26\1\43"+ + "\1\44\1\45\1\46\1\47\2\5\4\6\57\5\104\0"+ + "\2\50\55\0\1\51\4\0\1\52\63\0\1\53\1\0"+ + "\2\54\7\0\1\55\1\56\11\0\1\55\1\56\35\0"+ + "\1\53\1\0\2\57\7\0\1\55\1\56\11\0\1\55"+ + "\1\56\44\0\1\60\64\0\1\61\64\0\1\62\57\0"+ + "\2\63\6\0\5\63\4\0\23\63\21\0\2\63\6\0"+ + "\5\63\4\0\11\63\1\64\11\63\21\0\2\63\6\0"+ + "\5\63\4\0\7\63\1\65\1\63\1\66\11\63\21\0"+ + "\2\63\6\0\5\63\4\0\1\67\11\63\1\70\4\63"+ + "\1\71\3\63\21\0\2\63\6\0\5\63\4\0\4\63"+ + "\1\72\4\63\1\73\3\63\1\74\5\63\21\0\2\63"+ + "\6\0\5\63\4\0\12\63\1\75\10\63\21\0\2\63"+ + "\6\0\5\63\4\0\12\63\1\76\10\63\21\0\2\63"+ + "\6\0\5\63\4\0\14\63\1\77\6\63\21\0\2\63"+ + "\6\0\5\63\4\0\14\63\1\100\6\63\21\0\2\63"+ + "\6\0\5\63\4\0\3\63\1\101\17\63\21\0\2\63"+ + "\6\0\5\63\4\0\5\63\1\102\6\63\1\103\6\63"+ + "\21\0\2\63\6\0\5\63\4\0\1\104\22\63\21\0"+ + "\2\63\6\0\5\63\4\0\5\63\1\105\15\63\21\0"+ + "\2\63\6\0\5\63\4\0\12\63\1\106\10\63\21\0"+ + "\2\50\7\0\1\55\1\56\11\0\1\55\1\56\31\0"+ + "\1\107\64\0\1\110\72\0\2\111\7\0\1\55\1\56"+ + "\11\0\1\55\1\56\32\0\1\112\1\0\1\112\2\0"+ + "\2\113\63\0\2\63\6\0\5\63\4\0\2\63\1\114"+ + "\20\63\21\0\2\63\6\0\5\63\4\0\15\63\1\115"+ + "\5\63\21\0\2\63\6\0\5\63\4\0\2\63\1\116"+ + "\20\63\21\0\2\63\6\0\5\63\4\0\7\63\1\117"+ + "\13\63\21\0\2\63\6\0\5\63\4\0\14\63\1\120"+ + "\6\63\21\0\2\63\6\0\5\63\4\0\11\63\1\121"+ + "\11\63\21\0\2\63\6\0\5\63\4\0\12\63\1\122"+ + "\10\63\21\0\2\63\6\0\5\63\4\0\16\63\1\123"+ + "\4\63\21\0\2\63\6\0\5\63\4\0\6\63\1\124"+ + "\14\63\21\0\2\63\6\0\5\63\4\0\16\63\1\125"+ + "\4\63\21\0\2\63\6\0\5\63\4\0\3\63\1\126"+ + "\17\63\21\0\2\63\6\0\5\63\4\0\17\63\1\127"+ + "\3\63\21\0\2\63\6\0\5\63\4\0\14\63\1\130"+ + "\6\63\21\0\2\63\6\0\5\63\4\0\6\63\1\131"+ + "\14\63\21\0\2\63\6\0\5\63\4\0\14\63\1\132"+ + "\6\63\13\0\1\133\136\0\1\134\20\0\2\113\63\0"+ + "\2\113\10\0\1\56\12\0\1\56\37\0\2\63\6\0"+ + "\5\63\4\0\3\63\1\135\17\63\21\0\2\63\6\0"+ + "\5\63\4\0\15\63\1\136\5\63\21\0\2\63\6\0"+ + "\5\63\4\0\1\63\1\137\21\63\21\0\2\63\6\0"+ + "\5\63\4\0\13\63\1\140\7\63\21\0\2\63\6\0"+ + "\5\63\4\0\11\63\1\141\11\63\21\0\2\63\6\0"+ + "\5\63\4\0\17\63\1\142\3\63\21\0\2\63\6\0"+ + "\5\63\4\0\11\63\1\143\11\63\21\0\2\63\6\0"+ + "\5\63\4\0\3\63\1\144\17\63\21\0\2\63\6\0"+ + "\5\63\4\0\7\63\1\145\13\63\20\0\1\146\100\0"+ + "\1\147\51\0\2\63\6\0\5\63\4\0\3\63\1\150"+ + "\17\63\21\0\2\63\6\0\5\63\4\0\16\63\1\151"+ + "\4\63\21\0\2\63\6\0\5\63\4\0\14\63\1\152"+ + "\6\63\21\0\2\63\6\0\5\63\4\0\3\63\1\153"+ + "\17\63\24\0\1\154\110\0\1\155\35\0\2\63\6\0"+ + "\5\63\4\0\11\63\1\156\11\63\3\0\1\157\1\160"+ + "\1\0\1\157\1\161\130\0\1\162\35\0\1\163\44\0"+ + "\1\164\17\0\1\163\105\0\1\165\27\0\1\166\111\0"+ + "\1\167\40\0\1\170\120\0\1\171\55\0\1\172\104\0"+ + "\1\173\47\0\1\174\75\0\1\175\51\0\1\176\75\0"+ + "\1\177\24\0\1\200\127\0\1\201\15\0\1\202\122\0"+ + "\1\203\31\0\1\204\135\0\1\205\44\0\1\206\100\0"+ + "\1\207\23\0\1\210\127\0\1\211\45\0\1\212\113\0"+ + "\1\213\34\0\1\214\56\0\1\215\75\0\1\216\27\0"+ + "\1\217\67\0\1\220\115\0\1\221\36\0\1\222\65\0"+ + "\1\223\61\0\1\224\56\0"; + + private static int [] zzUnpackTrans() { + int [] result = new int[5406]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** Error code for "Unknown internal scanner error". */ + private static final int ZZ_UNKNOWN_ERROR = 0; + /** Error code for "could not match input". */ + private static final int ZZ_NO_MATCH = 1; + /** Error code for "pushback value was too large". */ + private static final int ZZ_PUSHBACK_2BIG = 2; + + /** + * Error messages for {@link #ZZ_UNKNOWN_ERROR}, {@link #ZZ_NO_MATCH}, and + * {@link #ZZ_PUSHBACK_2BIG} respectively. + */ + private static final String[] ZZ_ERROR_MSG = { + "Unknown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state {@code aState} + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\4\0\10\11\5\1\1\11\1\1\1\11\2\1\2\11"+ + "\15\1\2\11\6\0\1\11\1\1\3\11\24\1\5\0"+ + "\17\1\2\0\11\1\2\0\4\1\2\0\1\1\45\0"+ + "\1\11"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[148]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** Input device. */ + private java.io.Reader zzReader; + + /** Current state of the DFA. */ + private int zzState; + + /** Current lexical state. */ + private int zzLexicalState = YYINITIAL; + + /** + * This buffer contains the current text to be matched and is the source of the {@link #yytext()} + * string. + */ + private char[] zzBuffer = new char[ZZ_BUFFERSIZE]; + + /** Text position at the last accepting state. */ + private int zzMarkedPos; + + /** Current text position in the buffer. */ + private int zzCurrentPos; + + /** Marks the beginning of the {@link #yytext()} string in the buffer. */ + private int zzStartRead; + + /** Marks the last character in the buffer, that has been read from input. */ + private int zzEndRead; + + /** + * Whether the scanner is at the end of file. + * @see #yyatEOF + */ + private boolean zzAtEOF; + + /** + * The number of occupied positions in {@link #zzBuffer} beyond {@link #zzEndRead}. + * + *

When a lead/high surrogate has been read from the input stream into the final + * {@link #zzBuffer} position, this will have a value of 1; otherwise, it will have a value of 0. + */ + private int zzFinalHighSurrogate = 0; + + /** Number of newlines encountered up to the start of the matched text. */ + private int yyline; + + /** Number of characters from the last newline up to the start of the matched text. */ + private int yycolumn; + + /** Number of characters up to the start of the matched text. */ + @SuppressWarnings("unused") + private long yychar; + + /** Whether the scanner is currently at the beginning of a line. */ + @SuppressWarnings("unused") + private boolean zzAtBOL = true; + + /** Whether the user-EOF-code has already been executed. */ + private boolean zzEOFDone; + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + LexerAnalysis(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Translates raw input code points to DFA table row + */ + private static int zzCMap(int input) { + int offset = input & 255; + return offset == input ? ZZ_CMAP_BLOCKS[offset] : ZZ_CMAP_BLOCKS[ZZ_CMAP_TOP[input >> 8] | offset]; + } + + /** + * Refills the input buffer. + * + * @return {@code false} iff there was new input. + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead - zzStartRead); + + /* translate stored positions */ + zzEndRead -= zzStartRead; + zzCurrentPos -= zzStartRead; + zzMarkedPos -= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { + /* if not: blow it up */ + char[] newBuffer = new char[zzBuffer.length * 2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + } + + /* fill the buffer with new input */ + int requested = zzBuffer.length - zzEndRead; + int numRead = zzReader.read(zzBuffer, zzEndRead, requested); + + /* not supposed to occur according to specification of java.io.Reader */ + if (numRead == 0) { + throw new java.io.IOException( + "Reader returned 0 characters. See JFlex examples/zero-reader for a workaround."); + } + if (numRead > 0) { + zzEndRead += numRead; + if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { + if (numRead == requested) { // We requested too few chars to encode a full Unicode character + --zzEndRead; + zzFinalHighSurrogate = 1; + } else { // There is room in the buffer for at least one more char + int c = zzReader.read(); // Expecting to read a paired low surrogate char + if (c == -1) { + return true; + } else { + zzBuffer[zzEndRead++] = (char)c; + } + } + } + /* potentially more input available */ + return false; + } + + /* numRead < 0 ==> end of stream */ + return true; + } + + + /** + * Closes the input reader. + * + * @throws java.io.IOException if the reader could not be closed. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; // indicate end of file + zzEndRead = zzStartRead; // invalidate buffer + + if (zzReader != null) { + zzReader.close(); + } + } + + + /** + * Resets the scanner to read from a new input stream. + * + *

Does not close the old reader. + * + *

All internal variables are reset, the old input stream cannot be reused (internal + * buffer is discarded and lost). Lexical state is set to {@code ZZ_INITIAL}. + * + *

Internal scan buffer is resized down to its initial length, if it has grown. + * + * @param reader The new input stream. + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzEOFDone = false; + yyResetPosition(); + zzLexicalState = YYINITIAL; + if (zzBuffer.length > ZZ_BUFFERSIZE) { + zzBuffer = new char[ZZ_BUFFERSIZE]; + } + } + + /** + * Resets the input position. + */ + private final void yyResetPosition() { + zzAtBOL = true; + zzAtEOF = false; + zzCurrentPos = 0; + zzMarkedPos = 0; + zzStartRead = 0; + zzEndRead = 0; + zzFinalHighSurrogate = 0; + yyline = 0; + yycolumn = 0; + yychar = 0L; + } + + + /** + * Returns whether the scanner has reached the end of the reader it reads from. + * + * @return whether the scanner has reached EOF. + */ + public final boolean yyatEOF() { + return zzAtEOF; + } + + + /** + * Returns the current lexical state. + * + * @return the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state. + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + * + * @return the matched text. + */ + public final String yytext() { + return new String(zzBuffer, zzStartRead, zzMarkedPos-zzStartRead); + } + + + /** + * Returns the character at the given position from the matched text. + * + *

It is equivalent to {@code yytext().charAt(pos)}, but faster. + * + * @param position the position of the character to fetch. A value from 0 to {@code yylength()-1}. + * + * @return the character at {@code position}. + */ + public final char yycharat(int position) { + return zzBuffer[zzStartRead + position]; + } + + + /** + * How many characters were matched. + * + * @return the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occurred while scanning. + * + *

In a well-formed scanner (no or only correct usage of {@code yypushback(int)} and a + * match-all fallback rule) this method will only be called with things that + * "Can't Possibly Happen". + * + *

If this method is called, something is seriously wrong (e.g. a JFlex bug producing a faulty + * scanner etc.). + * + *

Usual syntax/scanner level error handling should be done in error fallback rules. + * + * @param errorCode the code of the error message to display. + */ + private static void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + *

They will be read again by then next call of the scanning method. + * + * @param number the number of characters to be read again. This number must not be greater than + * {@link #yylength()}. + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Contains user EOF-code, which will be executed exactly once, + * when the end of file is reached + */ + private void zzDoEOF() throws java.io.IOException { + if (!zzEOFDone) { + zzEOFDone = true; + + yyclose(); } + } + + + + + /** + * Resumes scanning until the next regular expression is matched, the end of input is encountered + * or an I/O-Error occurs. + * + * @return the next token. + * @exception java.io.IOException if any I/O-Error occurs. + */ + public int yylex() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char[] zzBufferL = zzBuffer; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + boolean zzR = false; + int zzCh; + int zzCharCount; + for (zzCurrentPosL = zzStartRead ; + zzCurrentPosL < zzMarkedPosL ; + zzCurrentPosL += zzCharCount ) { + zzCh = Character.codePointAt(zzBufferL, zzCurrentPosL, zzMarkedPosL); + zzCharCount = Character.charCount(zzCh); + switch (zzCh) { + case '\u000B': // fall through + case '\u000C': // fall through + case '\u0085': // fall through + case '\u2028': // fall through + case '\u2029': + yyline++; + yycolumn = 0; + zzR = false; + break; + case '\r': + yyline++; + yycolumn = 0; + zzR = true; + break; + case '\n': + if (zzR) + zzR = false; + else { + yyline++; + yycolumn = 0; + } + break; + default: + zzR = false; + yycolumn += zzCharCount; + } + } + + if (zzR) { + // peek one character ahead if it is + // (if we have counted one line too much) + boolean zzPeek; + if (zzMarkedPosL < zzEndReadL) + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + else if (zzAtEOF) + zzPeek = false; + else { + boolean eof = zzRefill(); + zzEndReadL = zzEndRead; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + if (eof) + zzPeek = false; + else + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + } + if (zzPeek) yyline--; + } + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + // set up zzAction for empty match case: + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + } + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMap(zzInput) ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + zzDoEOF(); + { + return Parser.Lexer.EOF; + } + } + else { + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: + { return 3000; + } + // fall through + case 45: break; + case 2: + { throw new RuntimeException("Illegal character \""+yytext()+"\" at line "+yyline+", column "+yycolumn); + } + // fall through + case 46: break; + case 3: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.LPAREN; + } + // fall through + case 47: break; + case 4: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.RPAREN; + } + // fall through + case 48: break; + case 5: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.MULT; + } + // fall through + case 49: break; + case 6: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.PLUS; + } + // fall through + case 50: break; + case 7: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.COMMA; + } + // fall through + case 51: break; + case 8: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.MINUS; + } + // fall through + case 52: break; + case 9: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.DOT; + } + // fall through + case 53: break; + case 10: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.DIV; + } + // fall through + case 54: break; + case 11: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.INTEGER_LITERAL; + } + // fall through + case 55: break; + case 12: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.SEMICOLON; + } + // fall through + case 56: break; + case 13: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.LT; + } + // fall through + case 57: break; + case 14: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.EQ; + } + // fall through + case 58: break; + case 15: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.GT; + } + // fall through + case 59: break; + case 16: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.IDENTIFIER; + } + // fall through + case 60: break; + case 17: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.LBRACK; + } + // fall through + case 61: break; + case 18: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.RBRACK; + } + // fall through + case 62: break; + case 19: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.LBRACE; + } + // fall through + case 63: break; + case 20: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.RBRACE; + } + // fall through + case 64: break; + case 21: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.REAL_LITERAL; + } + // fall through + case 65: break; + case 22: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.ASSIGN; + } + // fall through + case 66: break; + case 23: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.LTEQ; + } + // fall through + case 67: break; + case 24: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.GTEQ; + } + // fall through + case 68: break; + case 25: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_IF; + } + // fall through + case 69: break; + case 26: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_IN; + } + // fall through + case 70: break; + case 27: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_IS; + } + // fall through + case 71: break; + case 28: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.OR; + } + // fall through + case 72: break; + case 29: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.AND; + } + // fall through + case 73: break; + case 30: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_END; + } + // fall through + case 74: break; + case 31: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_FOR; + } + // fall through + case 75: break; + case 32: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.NOT; + } + // fall through + case 76: break; + case 33: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_VAR; + } + // fall through + case 77: break; + case 34: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.XOR; + } + // fall through + case 78: break; + case 35: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_ELSE; + } + // fall through + case 79: break; + case 36: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_FUNC; + } + // fall through + case 80: break; + case 37: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_LOOP; + } + // fall through + case 81: break; + case 38: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_THEN; + } + // fall through + case 82: break; + case 39: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_TRUE; + } + // fall through + case 83: break; + case 40: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_FALSE; + } + // fall through + case 84: break; + case 41: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_PRINT; + } + // fall through + case 85: break; + case 42: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_WHILE; + } + // fall through + case 86: break; + case 43: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.KW_RETURN; + } + // fall through + case 87: break; + case 44: + { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Parser.Lexer.STRING; + } + // fall through + case 88: break; + default: + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + /** + * Runs the scanner on input files. + * + * This is a standalone scanner, it will print any unmatched + * text to System.out unchanged. + * + * @param argv the command line, contains the filenames to run + * the scanner on. + */ + public static void main(String[] argv) { + if (argv.length == 0) { + System.out.println("Usage : java LexerAnalysis [ --encoding ] "); + } + else { + int firstFilePos = 0; + String encodingName = "UTF-8"; + if (argv[0].equals("--encoding")) { + firstFilePos = 2; + encodingName = argv[1]; + try { + // Side-effect: is encodingName valid? + java.nio.charset.Charset.forName(encodingName); + } catch (Exception e) { + System.out.println("Invalid encoding '" + encodingName + "'"); + return; + } + } + for (int i = firstFilePos; i < argv.length; i++) { + LexerAnalysis scanner = null; + try { + java.io.FileInputStream stream = new java.io.FileInputStream(argv[i]); + java.io.Reader reader = new java.io.InputStreamReader(stream, encodingName); + scanner = new LexerAnalysis(reader); + while ( !scanner.zzAtEOF ) scanner.yylex(); + } + catch (java.io.FileNotFoundException e) { + System.out.println("File not found : \""+argv[i]+"\""); + } + catch (java.io.IOException e) { + System.out.println("IO error scanning file \""+argv[i]+"\""); + System.out.println(e); + } + catch (Exception e) { + System.out.println("Unexpected exception:"); + e.printStackTrace(); + } + } + } + } + + +} diff --git a/src/Parser/Parser.java b/src/Parser/Parser.java new file mode 100644 index 0000000..c24f0b0 --- /dev/null +++ b/src/Parser/Parser.java @@ -0,0 +1,1336 @@ +/* A Bison parser, made by GNU Bison 3.7.4. */ + +/* Skeleton implementation for Bison LALR(1) parsers in Java + + Copyright (C) 2007-2015, 2018-2020 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +package Parser; + + + +import java.text.MessageFormat; +/* "%code imports" blocks. */ +/* "parser.y":7 */ + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.IOException; + +/* "parser.java":51 */ + +/** + * A Bison parser, automatically generated from parser.y. + * + * @author LALR (1) parser skeleton written by Paolo Bonzini. + */ +public class Parser +{ + /** Version number for the Bison executable that generated this parser. */ + public static final String bisonVersion = "3.7.4"; + + /** Name of the skeleton that generated this parser. */ + public static final String bisonSkeleton = "lalr1.java"; + + + + /** + * True if verbose error messages are enabled. + */ + private boolean yyErrorVerbose = true; + + /** + * Whether verbose error messages are enabled. + */ + public final boolean getErrorVerbose() { return yyErrorVerbose; } + + /** + * Set the verbosity of error messages. + * @param verbose True to request verbose error messages. + */ + public final void setErrorVerbose(boolean verbose) + { yyErrorVerbose = verbose; } + + + + + public enum SymbolKind + { + S_YYEOF(0), /* "end of file" */ + S_YYerror(1), /* error */ + S_YYUNDEF(2), /* "invalid token" */ + S_KW_IF(3), /* KW_IF */ + S_KW_IS(4), /* KW_IS */ + S_KW_VAR(5), /* KW_VAR */ + S_KW_END(6), /* KW_END */ + S_KW_TRUE(7), /* KW_TRUE */ + S_KW_FALSE(8), /* KW_FALSE */ + S_KW_THEN(9), /* KW_THEN */ + S_KW_ELSE(10), /* KW_ELSE */ + S_KW_FOR(11), /* KW_FOR */ + S_KW_LOOP(12), /* KW_LOOP */ + S_KW_IN(13), /* KW_IN */ + S_KW_WHILE(14), /* KW_WHILE */ + S_KW_FUNC(15), /* KW_FUNC */ + S_KW_RETURN(16), /* KW_RETURN */ + S_KW_PRINT(17), /* KW_PRINT */ + S_LPAREN(18), /* LPAREN */ + S_RPAREN(19), /* RPAREN */ + S_LBRACE(20), /* LBRACE */ + S_RBRACE(21), /* RBRACE */ + S_LBRACK(22), /* LBRACK */ + S_RBRACK(23), /* RBRACK */ + S_SEMICOLON(24), /* SEMICOLON */ + S_COMMA(25), /* COMMA */ + S_DOT(26), /* DOT */ + S_EQ(27), /* EQ */ + S_ASSIGN(28), /* ASSIGN */ + S_GT(29), /* GT */ + S_LT(30), /* LT */ + S_LTEQ(31), /* LTEQ */ + S_GTEQ(32), /* GTEQ */ + S_PLUS(33), /* PLUS */ + S_MINUS(34), /* MINUS */ + S_MULT(35), /* MULT */ + S_DIV(36), /* DIV */ + S_OR(37), /* OR */ + S_AND(38), /* AND */ + S_XOR(39), /* XOR */ + S_NOT(40), /* NOT */ + S_INTEGER_LITERAL(41), /* INTEGER_LITERAL */ + S_REAL_LITERAL(42), /* REAL_LITERAL */ + S_STRING(43), /* STRING */ + S_IDENTIFIER(44), /* IDENTIFIER */ + S_YYACCEPT(45), /* $accept */ + S_Prog(46), /* Prog */ + S_Body(47), /* Body */ + S_Declaration(48), /* Declaration */ + S_ReturnStatement(49), /* ReturnStatement */ + S_PrintStatement(50), /* PrintStatement */ + S_Assignment(51), /* Assignment */ + S_Expression(52), /* Expression */ + S_ArrayAccess(53), /* ArrayAccess */ + S_Relation(54), /* Relation */ + S_Calc(55), /* Calc */ + S_Value(56), /* Value */ + S_ArrayValue(57), /* ArrayValue */ + S_DictValue(58), /* DictValue */ + S_DictValues(59), /* DictValues */ + S_ArrayValues(60), /* ArrayValues */ + S_FunctionDef(61), /* FunctionDef */ + S_FunctionCall(62), /* FunctionCall */ + S_Params(63), /* Params */ + S_Args(64), /* Args */ + S_Statement(65), /* Statement */ + S_IfStatement(66), /* IfStatement */ + S_ForStatement(67), /* ForStatement */ + S_WhileStatement(68); /* WhileStatement */ + + + private final int yycode_; + + SymbolKind (int n) { + this.yycode_ = n; + } + + private static final SymbolKind[] values_ = { + SymbolKind.S_YYEOF, + SymbolKind.S_YYerror, + SymbolKind.S_YYUNDEF, + SymbolKind.S_KW_IF, + SymbolKind.S_KW_IS, + SymbolKind.S_KW_VAR, + SymbolKind.S_KW_END, + SymbolKind.S_KW_TRUE, + SymbolKind.S_KW_FALSE, + SymbolKind.S_KW_THEN, + SymbolKind.S_KW_ELSE, + SymbolKind.S_KW_FOR, + SymbolKind.S_KW_LOOP, + SymbolKind.S_KW_IN, + SymbolKind.S_KW_WHILE, + SymbolKind.S_KW_FUNC, + SymbolKind.S_KW_RETURN, + SymbolKind.S_KW_PRINT, + SymbolKind.S_LPAREN, + SymbolKind.S_RPAREN, + SymbolKind.S_LBRACE, + SymbolKind.S_RBRACE, + SymbolKind.S_LBRACK, + SymbolKind.S_RBRACK, + SymbolKind.S_SEMICOLON, + SymbolKind.S_COMMA, + SymbolKind.S_DOT, + SymbolKind.S_EQ, + SymbolKind.S_ASSIGN, + SymbolKind.S_GT, + SymbolKind.S_LT, + SymbolKind.S_LTEQ, + SymbolKind.S_GTEQ, + SymbolKind.S_PLUS, + SymbolKind.S_MINUS, + SymbolKind.S_MULT, + SymbolKind.S_DIV, + SymbolKind.S_OR, + SymbolKind.S_AND, + SymbolKind.S_XOR, + SymbolKind.S_NOT, + SymbolKind.S_INTEGER_LITERAL, + SymbolKind.S_REAL_LITERAL, + SymbolKind.S_STRING, + SymbolKind.S_IDENTIFIER, + SymbolKind.S_YYACCEPT, + SymbolKind.S_Prog, + SymbolKind.S_Body, + SymbolKind.S_Declaration, + SymbolKind.S_ReturnStatement, + SymbolKind.S_PrintStatement, + SymbolKind.S_Assignment, + SymbolKind.S_Expression, + SymbolKind.S_ArrayAccess, + SymbolKind.S_Relation, + SymbolKind.S_Calc, + SymbolKind.S_Value, + SymbolKind.S_ArrayValue, + SymbolKind.S_DictValue, + SymbolKind.S_DictValues, + SymbolKind.S_ArrayValues, + SymbolKind.S_FunctionDef, + SymbolKind.S_FunctionCall, + SymbolKind.S_Params, + SymbolKind.S_Args, + SymbolKind.S_Statement, + SymbolKind.S_IfStatement, + SymbolKind.S_ForStatement, + SymbolKind.S_WhileStatement + }; + + static final SymbolKind get(int code) { + return values_[code]; + } + + public final int getCode() { + return this.yycode_; + } + + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ + private static String yytnamerr_(String yystr) + { + if (yystr.charAt (0) == '"') + { + StringBuffer yyr = new StringBuffer(); + strip_quotes: for (int i = 1; i < yystr.length(); i++) + switch (yystr.charAt(i)) + { + case '\'': + case ',': + break strip_quotes; + + case '\\': + if (yystr.charAt(++i) != '\\') + break strip_quotes; + /* Fall through. */ + default: + yyr.append(yystr.charAt(i)); + break; + + case '"': + return yyr.toString(); + } + } + return yystr; + } + + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at \a YYNTOKENS_, nonterminals. */ + private static final String[] yytname_ = yytname_init(); + private static final String[] yytname_init() + { + return new String[] + { + "\"end of file\"", "error", "\"invalid token\"", "KW_IF", "KW_IS", + "KW_VAR", "KW_END", "KW_TRUE", "KW_FALSE", "KW_THEN", "KW_ELSE", + "KW_FOR", "KW_LOOP", "KW_IN", "KW_WHILE", "KW_FUNC", "KW_RETURN", + "KW_PRINT", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK", + "SEMICOLON", "COMMA", "DOT", "EQ", "ASSIGN", "GT", "LT", "LTEQ", "GTEQ", + "PLUS", "MINUS", "MULT", "DIV", "OR", "AND", "XOR", "NOT", + "INTEGER_LITERAL", "REAL_LITERAL", "STRING", "IDENTIFIER", "$accept", + "Prog", "Body", "Declaration", "ReturnStatement", "PrintStatement", + "Assignment", "Expression", "ArrayAccess", "Relation", "Calc", "Value", + "ArrayValue", "DictValue", "DictValues", "ArrayValues", "FunctionDef", + "FunctionCall", "Params", "Args", "Statement", "IfStatement", + "ForStatement", "WhileStatement", null + }; + } + + /* The user-facing name of this symbol. */ + public final String getName() { + return yytnamerr_(yytname_[yycode_]); + } + + }; + + + /** + * Communication interface between the scanner and the Bison-generated + * parser Parser. + */ + public interface Lexer { + /* Token kinds. */ + /** Token "end of file", to be returned by the scanner. */ + static final int YYEOF = 0; + /** Token error, to be returned by the scanner. */ + static final int YYerror = 256; + /** Token "invalid token", to be returned by the scanner. */ + static final int YYUNDEF = 257; + /** Token KW_IF, to be returned by the scanner. */ + static final int KW_IF = 258; + /** Token KW_IS, to be returned by the scanner. */ + static final int KW_IS = 259; + /** Token KW_VAR, to be returned by the scanner. */ + static final int KW_VAR = 260; + /** Token KW_END, to be returned by the scanner. */ + static final int KW_END = 261; + /** Token KW_TRUE, to be returned by the scanner. */ + static final int KW_TRUE = 262; + /** Token KW_FALSE, to be returned by the scanner. */ + static final int KW_FALSE = 263; + /** Token KW_THEN, to be returned by the scanner. */ + static final int KW_THEN = 264; + /** Token KW_ELSE, to be returned by the scanner. */ + static final int KW_ELSE = 265; + /** Token KW_FOR, to be returned by the scanner. */ + static final int KW_FOR = 266; + /** Token KW_LOOP, to be returned by the scanner. */ + static final int KW_LOOP = 267; + /** Token KW_IN, to be returned by the scanner. */ + static final int KW_IN = 268; + /** Token KW_WHILE, to be returned by the scanner. */ + static final int KW_WHILE = 269; + /** Token KW_FUNC, to be returned by the scanner. */ + static final int KW_FUNC = 270; + /** Token KW_RETURN, to be returned by the scanner. */ + static final int KW_RETURN = 271; + /** Token KW_PRINT, to be returned by the scanner. */ + static final int KW_PRINT = 272; + /** Token LPAREN, to be returned by the scanner. */ + static final int LPAREN = 273; + /** Token RPAREN, to be returned by the scanner. */ + static final int RPAREN = 274; + /** Token LBRACE, to be returned by the scanner. */ + static final int LBRACE = 275; + /** Token RBRACE, to be returned by the scanner. */ + static final int RBRACE = 276; + /** Token LBRACK, to be returned by the scanner. */ + static final int LBRACK = 277; + /** Token RBRACK, to be returned by the scanner. */ + static final int RBRACK = 278; + /** Token SEMICOLON, to be returned by the scanner. */ + static final int SEMICOLON = 279; + /** Token COMMA, to be returned by the scanner. */ + static final int COMMA = 280; + /** Token DOT, to be returned by the scanner. */ + static final int DOT = 281; + /** Token EQ, to be returned by the scanner. */ + static final int EQ = 282; + /** Token ASSIGN, to be returned by the scanner. */ + static final int ASSIGN = 283; + /** Token GT, to be returned by the scanner. */ + static final int GT = 284; + /** Token LT, to be returned by the scanner. */ + static final int LT = 285; + /** Token LTEQ, to be returned by the scanner. */ + static final int LTEQ = 286; + /** Token GTEQ, to be returned by the scanner. */ + static final int GTEQ = 287; + /** Token PLUS, to be returned by the scanner. */ + static final int PLUS = 288; + /** Token MINUS, to be returned by the scanner. */ + static final int MINUS = 289; + /** Token MULT, to be returned by the scanner. */ + static final int MULT = 290; + /** Token DIV, to be returned by the scanner. */ + static final int DIV = 291; + /** Token OR, to be returned by the scanner. */ + static final int OR = 292; + /** Token AND, to be returned by the scanner. */ + static final int AND = 293; + /** Token XOR, to be returned by the scanner. */ + static final int XOR = 294; + /** Token NOT, to be returned by the scanner. */ + static final int NOT = 295; + /** Token INTEGER_LITERAL, to be returned by the scanner. */ + static final int INTEGER_LITERAL = 296; + /** Token REAL_LITERAL, to be returned by the scanner. */ + static final int REAL_LITERAL = 297; + /** Token STRING, to be returned by the scanner. */ + static final int STRING = 298; + /** Token IDENTIFIER, to be returned by the scanner. */ + static final int IDENTIFIER = 299; + + /** Deprecated, use YYEOF instead. */ + public static final int EOF = YYEOF; + + + /** + * Method to retrieve the semantic value of the last scanned token. + * @return the semantic value of the last scanned token. + */ + Object getLVal(); + + /** + * Entry point for the scanner. Returns the token identifier corresponding + * to the next token and prepares to return the semantic value + * of the token. + * @return the token identifier corresponding to the next token. + */ + int yylex() throws java.io.IOException; + + /** + * Emit an errorin a user-defined way. + * + * + * @param msg The string for the error message. + */ + void yyerror(String msg); + + + } + + + /** + * The object doing lexical analysis for us. + */ + private Lexer yylexer; + + + + + + /** + * Instantiates the Bison-generated parser. + * @param yylexer The scanner that will supply tokens to the parser. + */ + public Parser (Lexer yylexer) + { + + this.yylexer = yylexer; + + } + + + + private int yynerrs = 0; + + /** + * The number of syntax errors so far. + */ + public final int getNumberOfErrors () { return yynerrs; } + + /** + * Print an error message via the lexer. + * + * @param msg The error message. + */ + public final void yyerror(String msg) { + yylexer.yyerror(msg); + } + + + + private final class YYStack { + private int[] stateStack = new int[16]; + private Object[] valueStack = new Object[16]; + + public int size = 16; + public int height = -1; + + public final void push (int state, Object value) { + height++; + if (size == height) + { + int[] newStateStack = new int[size * 2]; + System.arraycopy (stateStack, 0, newStateStack, 0, height); + stateStack = newStateStack; + + Object[] newValueStack = new Object[size * 2]; + System.arraycopy (valueStack, 0, newValueStack, 0, height); + valueStack = newValueStack; + + size *= 2; + } + + stateStack[height] = state; + valueStack[height] = value; + } + + public final void pop () { + pop (1); + } + + public final void pop (int num) { + // Avoid memory leaks... garbage collection is a white lie! + if (0 < num) { + java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null); + } + height -= num; + } + + public final int stateAt (int i) { + return stateStack[height - i]; + } + + public final Object valueAt (int i) { + return valueStack[height - i]; + } + + // Print the state stack on the debug stream. + public void print (java.io.PrintStream out) { + out.print ("Stack now"); + + for (int i = 0; i <= height; i++) + { + out.print (' '); + out.print (stateStack[i]); + } + out.println (); + } + } + + /** + * Returned by a Bison action in order to stop the parsing process and + * return success (true). + */ + public static final int YYACCEPT = 0; + + /** + * Returned by a Bison action in order to stop the parsing process and + * return failure (false). + */ + public static final int YYABORT = 1; + + + + /** + * Returned by a Bison action in order to start error recovery without + * printing an error message. + */ + public static final int YYERROR = 2; + + /** + * Internal return codes that are not supported for user semantic + * actions. + */ + private static final int YYERRLAB = 3; + private static final int YYNEWSTATE = 4; + private static final int YYDEFAULT = 5; + private static final int YYREDUCE = 6; + private static final int YYERRLAB1 = 7; + private static final int YYRETURN = 8; + + + private int yyerrstatus_ = 0; + + + /** + * Whether error recovery is being done. In this state, the parser + * reads token until it reaches a known state, and then restarts normal + * operation. + */ + public final boolean recovering () + { + return yyerrstatus_ == 0; + } + + /** Compute post-reduction state. + * @param yystate the current state + * @param yysym the nonterminal to push on the stack + */ + private int yyLRGotoState (int yystate, int yysym) + { + int yyr = yypgoto_[yysym - YYNTOKENS_] + yystate; + if (0 <= yyr && yyr <= YYLAST_ && yycheck_[yyr] == yystate) + return yytable_[yyr]; + else + return yydefgoto_[yysym - YYNTOKENS_]; + } + + private int yyaction(int yyn, YYStack yystack, int yylen) + { + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. Otherwise, use the top of the stack. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. */ + Object yyval = (0 < yylen) ? yystack.valueAt(yylen - 1) : yystack.valueAt(0); + + switch (yyn) + { + + /* "parser.java":606 */ + + default: break; + } + + yystack.pop(yylen); + yylen = 0; + /* Shift the result of the reduction. */ + int yystate = yyLRGotoState(yystack.stateAt(0), yyr1_[yyn]); + yystack.push(yystate, yyval); + return YYNEWSTATE; + } + + + + + /** + * Parse input from the scanner that was specified at object construction + * time. Return whether the end of the input was reached successfully. + * + * @return true if the parsing succeeds. Note that this does not + * imply that there were no syntax errors. + */ + public boolean parse() throws java.io.IOException + + { + + + /* Lookahead token kind. */ + int yychar = YYEMPTY_; + /* Lookahead symbol kind. */ + SymbolKind yytoken = null; + + /* State. */ + int yyn = 0; + int yylen = 0; + int yystate = 0; + YYStack yystack = new YYStack (); + int label = YYNEWSTATE; + + + + /* Semantic value of the lookahead. */ + Object yylval = null; + + yyerrstatus_ = 0; + yynerrs = 0; + + /* Initialize the stack. */ + yystack.push (yystate, yylval); + + + + for (;;) + switch (label) + { + /* New state. Unlike in the C/C++ skeletons, the state is already + pushed when we come here. */ + case YYNEWSTATE: + + /* Accept? */ + if (yystate == YYFINAL_) + return true; + + /* Take a decision. First try without lookahead. */ + yyn = yypact_[yystate]; + if (yyPactValueIsDefault (yyn)) + { + label = YYDEFAULT; + break; + } + + /* Read a lookahead token. */ + if (yychar == YYEMPTY_) + { + + yychar = yylexer.yylex (); + yylval = yylexer.getLVal(); + + } + + /* Convert token to internal form. */ + yytoken = yytranslate_ (yychar); + + if (yytoken == SymbolKind.S_YYerror) + { + // The scanner already issued an error message, process directly + // to error recovery. But do not keep the error token as + // lookahead, it is too special and may lead us to an endless + // loop in error recovery. */ + yychar = Lexer.YYUNDEF; + yytoken = SymbolKind.S_YYUNDEF; + label = YYERRLAB1; + } + else + { + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken.getCode(); + if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode()) + label = YYDEFAULT; + + /* <= 0 means reduce or error. */ + else if ((yyn = yytable_[yyn]) <= 0) + { + if (yyTableValueIsError (yyn)) + label = YYERRLAB; + else + { + yyn = -yyn; + label = YYREDUCE; + } + } + + else + { + /* Shift the lookahead token. */ + /* Discard the token being shifted. */ + yychar = YYEMPTY_; + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus_ > 0) + --yyerrstatus_; + + yystate = yyn; + yystack.push (yystate, yylval); + label = YYNEWSTATE; + } + } + break; + + /*-----------------------------------------------------------. + | yydefault -- do the default action for the current state. | + `-----------------------------------------------------------*/ + case YYDEFAULT: + yyn = yydefact_[yystate]; + if (yyn == 0) + label = YYERRLAB; + else + label = YYREDUCE; + break; + + /*-----------------------------. + | yyreduce -- Do a reduction. | + `-----------------------------*/ + case YYREDUCE: + yylen = yyr2_[yyn]; + label = yyaction(yyn, yystack, yylen); + yystate = yystack.stateAt (0); + break; + + /*------------------------------------. + | yyerrlab -- here on detecting error | + `------------------------------------*/ + case YYERRLAB: + /* If not already recovering from an error, report this error. */ + if (yyerrstatus_ == 0) + { + ++yynerrs; + if (yychar == YYEMPTY_) + yytoken = null; + yyreportSyntaxError (new Context (yystack, yytoken)); + } + + if (yyerrstatus_ == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= Lexer.YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == Lexer.YYEOF) + return false; + } + else + yychar = YYEMPTY_; + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + label = YYERRLAB1; + break; + + /*-------------------------------------------------. + | errorlab -- error raised explicitly by YYERROR. | + `-------------------------------------------------*/ + case YYERROR: + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + yystack.pop (yylen); + yylen = 0; + yystate = yystack.stateAt (0); + label = YYERRLAB1; + break; + + /*-------------------------------------------------------------. + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + case YYERRLAB1: + yyerrstatus_ = 3; /* Each real token shifted decrements this. */ + + // Pop stack until we find a state that shifts the error token. + for (;;) + { + yyn = yypact_[yystate]; + if (!yyPactValueIsDefault (yyn)) + { + yyn += SymbolKind.S_YYerror.getCode(); + if (0 <= yyn && yyn <= YYLAST_ + && yycheck_[yyn] == SymbolKind.S_YYerror.getCode()) + { + yyn = yytable_[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the + * error token. */ + if (yystack.height == 0) + return false; + + + yystack.pop (); + yystate = yystack.stateAt (0); + } + + if (label == YYABORT) + /* Leave the switch. */ + break; + + + + /* Shift the error token. */ + + yystate = yyn; + yystack.push (yyn, yylval); + label = YYNEWSTATE; + break; + + /* Accept. */ + case YYACCEPT: + return true; + + /* Abort. */ + case YYABORT: + return false; + } + } + + + + + /** + * Information needed to get the list of expected tokens and to forge + * a syntax error diagnostic. + */ + public static final class Context + { + Context (YYStack stack, SymbolKind token) + { + yystack = stack; + yytoken = token; + } + + private YYStack yystack; + + + /** + * The symbol kind of the lookahead token. + */ + public final SymbolKind getToken () + { + return yytoken; + } + + private SymbolKind yytoken; + static final int NTOKENS = Parser.YYNTOKENS_; + + /** + * Put in YYARG at most YYARGN of the expected tokens given the + * current YYCTX, and return the number of tokens stored in YYARG. If + * YYARG is null, return the number of expected tokens (guaranteed to + * be less than YYNTOKENS). + */ + int getExpectedTokens (SymbolKind yyarg[], int yyargn) + { + return getExpectedTokens (yyarg, 0, yyargn); + } + + int getExpectedTokens (SymbolKind yyarg[], int yyoffset, int yyargn) + { + int yycount = yyoffset; + int yyn = yypact_[this.yystack.stateAt (0)]; + if (!yyPactValueIsDefault (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative + indexes in YYCHECK. In other words, skip the first + -YYN actions for this state because they are default + actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST_ - yyn + 1; + int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS; + for (int yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck_[yyx + yyn] == yyx && yyx != SymbolKind.S_YYerror.getCode() + && !yyTableValueIsError(yytable_[yyx + yyn])) + { + if (yyarg == null) + yycount += 1; + else if (yycount == yyargn) + return 0; // FIXME: this is incorrect. + else + yyarg[yycount++] = SymbolKind.get(yyx); + } + } + if (yyarg != null && yycount == yyoffset && yyoffset < yyargn) + yyarg[yycount] = null; + return yycount - yyoffset; + } + } + + + private int yysyntaxErrorArguments (Context yyctx, SymbolKind[] yyarg, int yyargn) + { + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, + then the only way this function was invoked is if the + default action is an error action. In that case, don't + check for expected tokens because there are none. + - The only way there can be no lookahead present (in tok) is + if this state is a consistent state with a default action. + Thus, detecting the absence of a lookahead is sufficient to + determine that there is no unexpected or expected token to + report. In that case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this + state is a consistent state with a default action. There + might have been a previous inconsistent state, consistent + state with a non-default action, or user semantic action + that manipulated yychar. (However, yychar is currently out + of scope during semantic actions.) + - Of course, the expected token list depends on states to + have correct lookahead information, and it depends on the + parser not to perform extra reductions after fetching a + lookahead from the scanner and before detecting a syntax + error. Thus, state merging (from LALR or IELR) and default + reductions corrupt the expected token list. However, the + list is correct for canonical LR with one exception: it + will still contain any token that will not be accepted due + to an error action in a later state. + */ + int yycount = 0; + if (yyctx.getToken() != null) + { + if (yyarg != null) + yyarg[yycount] = yyctx.getToken(); + yycount += 1; + yycount += yyctx.getExpectedTokens(yyarg, 1, yyargn); + } + return yycount; + } + + + private void yyreportSyntaxError(Context yyctx) { + if (yyErrorVerbose) { + final int argmax = 5; + SymbolKind[] yyarg = new SymbolKind[argmax]; + int yycount = yysyntaxErrorArguments(yyctx, yyarg, argmax); + String[] yystr = new String[yycount]; + for (int yyi = 0; yyi < yycount; ++yyi) { + yystr[yyi] = yyarg[yyi].getName(); + } + String yyformat; + switch (yycount) { + default: + case 0: yyformat = "syntax error"; break; + case 1: yyformat = "syntax error, unexpected {0}"; break; + case 2: yyformat = "syntax error, unexpected {0}, expecting {1}"; break; + case 3: yyformat = "syntax error, unexpected {0}, expecting {1} or {2}"; break; + case 4: yyformat = "syntax error, unexpected {0}, expecting {1} or {2} or {3}"; break; + case 5: yyformat = "syntax error, unexpected {0}, expecting {1} or {2} or {3} or {4}"; break; + } + yyerror(new MessageFormat(yyformat).format(yystr)); + } else { + yyerror("syntax error"); + } + } + + /** + * Whether the given yypact_ value indicates a defaulted state. + * @param yyvalue the value to check + */ + private static boolean yyPactValueIsDefault (int yyvalue) + { + return yyvalue == yypact_ninf_; + } + + /** + * Whether the given yytable_ + * value indicates a syntax error. + * @param yyvalue the value to check + */ + private static boolean yyTableValueIsError (int yyvalue) + { + return yyvalue == yytable_ninf_; + } + + private static final short yypact_ninf_ = -44; + private static final short yytable_ninf_ = -1; + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ + private static final short[] yypact_ = yypact_init(); + private static final short[] yypact_init() + { + return new short[] + { + 87, -6, -33, -44, -44, -3, -2, 130, 130, 130, + -31, 130, 130, -44, -44, -44, -9, 18, -44, 10, + -44, 12, 17, 127, -44, -44, -44, -44, -44, -44, + -44, 87, -44, -44, -44, 130, -8, -23, 130, 24, + 291, 237, -44, 156, 20, 25, 1, 255, 40, 77, + 130, 130, -44, 87, 87, 87, 130, 87, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + -44, 177, 103, 53, 198, 130, -44, -31, -44, 130, + -44, 48, 291, -44, -44, -44, 273, -44, 77, 42, + 42, 42, 42, 309, 309, 8, 8, -5, 49, -14, + 61, 56, 291, -44, 130, 63, -44, -44, -44, -44, + -44, 87, 32, 219, 87, 4, 52, 59, 70, 78, + -44, 87, 32, 81, 87, -44, 82, -44, 87, 83, + -44, 85, -44, -44 + }; + } + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ + private static final byte[] yydefact_ = yydefact_init(); + private static final byte[] yydefact_init() + { + return new byte[] + { + 3, 0, 0, 40, 41, 0, 0, 0, 54, 0, + 46, 48, 0, 38, 39, 37, 16, 0, 2, 0, + 9, 0, 0, 0, 22, 18, 21, 19, 42, 43, + 20, 3, 56, 57, 58, 0, 10, 0, 0, 16, + 13, 0, 14, 0, 0, 0, 0, 0, 0, 32, + 54, 0, 1, 3, 3, 3, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 54, 17, 46, 45, 48, + 44, 0, 15, 4, 7, 5, 0, 6, 28, 26, + 24, 25, 27, 33, 34, 35, 36, 30, 29, 31, + 0, 0, 11, 12, 0, 0, 55, 47, 49, 51, + 23, 3, 52, 0, 3, 0, 0, 0, 0, 0, + 59, 3, 52, 0, 3, 62, 0, 53, 3, 0, + 60, 0, 61, 50 + }; + } + + /* YYPGOTO[NTERM-NUM]. */ + private static final byte[] yypgoto_ = yypgoto_init(); + private static final byte[] yypgoto_init() + { + return new byte[] + { + -44, -44, -28, -44, -44, -44, -4, -7, -44, -44, + -44, -44, -44, -44, 29, 23, -44, -44, -35, -43, + -44, -44, -44, -44 + }; + } + + /* YYDEFGOTO[NTERM-NUM]. */ + private static final byte[] yydefgoto_ = yydefgoto_init(); + private static final byte[] yydefgoto_init() + { + return new byte[] + { + -1, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 46, 48, 103, 30, 117, 42, + 31, 32, 33, 34 + }; + } + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ + private static final short[] yytable_ = yytable_init(); + private static final short[] yytable_init() + { + return new short[] + { + 40, 41, 43, 70, 47, 49, 45, 81, 56, 50, + 120, 36, 35, 44, 121, 37, 38, 56, 52, 51, + 72, 73, 78, 67, 68, 83, 84, 85, 71, 87, + 56, 74, 106, 68, 53, 58, 54, 59, 60, 61, + 62, 55, 50, 41, 82, 67, 68, 69, 51, 86, + 77, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 80, 56, 102, 104, 109, 41, 58, + 111, 56, 47, 45, 112, 114, 116, 122, 123, 67, + 68, 69, 124, 115, 125, 128, 119, 127, 130, 132, + 1, 133, 2, 126, 3, 4, 129, 113, 5, 56, + 131, 6, 108, 7, 8, 9, 107, 10, 0, 11, + 3, 4, 0, 0, 67, 68, 69, 0, 101, 0, + 0, 9, 0, 10, 0, 11, 0, 12, 13, 14, + 15, 16, 0, 0, 0, 0, 0, 3, 4, 0, + 0, 0, 0, 12, 13, 14, 15, 39, 9, 56, + 10, 57, 11, 0, 58, 0, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 0, 0, 0, + 12, 13, 14, 15, 39, 76, 0, 0, 56, 0, + 0, 0, 0, 58, 0, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 100, 0, 0, 56, + 0, 0, 0, 0, 58, 0, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 105, 0, 0, + 56, 0, 0, 0, 0, 58, 0, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 118, 0, + 0, 56, 0, 0, 0, 0, 58, 0, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 56, + 0, 0, 75, 0, 58, 0, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 56, 0, 0, + 79, 0, 58, 0, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 56, 110, 0, 0, 0, + 58, 0, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 56, 0, 0, 0, 0, 58, 0, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 56, 0, 0, 0, 0, 58, 0, 59, 60, + 61, 62, 0, 0, 65, 66, 67, 68, 69 + }; + } + + private static final short[] yycheck_ = yycheck_init(); + private static final short[] yycheck_init() + { + return new short[] + { + 7, 8, 9, 31, 11, 12, 10, 50, 22, 18, + 6, 44, 18, 44, 10, 18, 18, 22, 0, 28, + 28, 44, 21, 37, 38, 53, 54, 55, 35, 57, + 22, 38, 75, 38, 24, 27, 24, 29, 30, 31, + 32, 24, 18, 50, 51, 37, 38, 39, 28, 56, + 25, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 23, 22, 72, 13, 19, 75, 27, + 9, 22, 79, 77, 18, 12, 44, 25, 19, 37, + 38, 39, 12, 111, 6, 4, 114, 122, 6, 6, + 3, 6, 5, 121, 7, 8, 124, 104, 11, 22, + 128, 14, 79, 16, 17, 18, 77, 20, -1, 22, + 7, 8, -1, -1, 37, 38, 39, -1, 15, -1, + -1, 18, -1, 20, -1, 22, -1, 40, 41, 42, + 43, 44, -1, -1, -1, -1, -1, 7, 8, -1, + -1, -1, -1, 40, 41, 42, 43, 44, 18, 22, + 20, 24, 22, -1, 27, -1, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, -1, -1, -1, + 40, 41, 42, 43, 44, 19, -1, -1, 22, -1, + -1, -1, -1, 27, -1, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 19, -1, -1, 22, + -1, -1, -1, -1, 27, -1, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 19, -1, -1, + 22, -1, -1, -1, -1, 27, -1, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 19, -1, + -1, 22, -1, -1, -1, -1, 27, -1, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 22, + -1, -1, 25, -1, 27, -1, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 22, -1, -1, + 25, -1, 27, -1, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 22, 23, -1, -1, -1, + 27, -1, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 22, -1, -1, -1, -1, 27, -1, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 22, -1, -1, -1, -1, 27, -1, 29, 30, + 31, 32, -1, -1, 35, 36, 37, 38, 39 + }; + } + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ + private static final byte[] yystos_ = yystos_init(); + private static final byte[] yystos_init() + { + return new byte[] + { + 0, 3, 5, 7, 8, 11, 14, 16, 17, 18, + 20, 22, 40, 41, 42, 43, 44, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 62, 65, 66, 67, 68, 18, 44, 18, 18, 44, + 52, 52, 64, 52, 44, 51, 59, 52, 60, 52, + 18, 28, 0, 24, 24, 24, 22, 24, 27, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 47, 52, 28, 44, 52, 25, 19, 25, 21, 25, + 23, 64, 52, 47, 47, 47, 52, 47, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 19, 15, 52, 61, 13, 19, 64, 59, 60, 19, + 23, 9, 18, 52, 12, 47, 44, 63, 19, 47, + 6, 10, 25, 19, 12, 6, 47, 63, 4, 47, + 6, 47, 6, 6 + }; + } + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ + private static final byte[] yyr1_ = yyr1_init(); + private static final byte[] yyr1_init() + { + return new byte[] + { + 0, 45, 46, 47, 47, 47, 47, 47, 47, 47, + 48, 48, 48, 49, 50, 51, 52, 52, 52, 52, + 52, 52, 52, 53, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 55, 55, 55, 55, 56, 56, 56, + 56, 56, 56, 56, 57, 58, 59, 59, 60, 60, + 61, 62, 63, 63, 64, 64, 65, 65, 65, 66, + 66, 67, 68 + }; + } + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ + private static final byte[] yyr2_ = yyr2_init(); + private static final byte[] yyr2_init() + { + return new byte[] + { + 0, 2, 1, 0, 3, 3, 3, 3, 2, 1, + 2, 4, 4, 2, 2, 3, 1, 3, 1, 1, + 1, 1, 1, 4, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 3, 3, 3, 3, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 0, 3, 0, 3, + 7, 4, 0, 3, 0, 3, 1, 1, 1, 7, + 9, 9, 7 + }; + } + + + + + /* YYTRANSLATE_(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ + private static final SymbolKind yytranslate_(int t) + { + // Last valid token kind. + int code_max = 299; + if (t <= 0) + return SymbolKind.S_YYEOF; + else if (t <= code_max) + return SymbolKind.get(yytranslate_table_[t]); + else + return SymbolKind.S_YYUNDEF; + } + private static final byte[] yytranslate_table_ = yytranslate_table_init(); + private static final byte[] yytranslate_table_init() + { + return new byte[] + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44 + }; + } + + + private static final int YYLAST_ = 348; + private static final int YYEMPTY_ = -2; + private static final int YYFINAL_ = 52; + private static final int YYNTOKENS_ = 45; + + /* Unqualified %code blocks. */ + /* "parser.y":15 */ + + public static void main(String args[]) throws IOException { + ParserLexer lexer = new ParserLexer(System.in); + Parser parser = new Parser(lexer); + if(parser.parse()) + System.out.println("---------------------\n Parser Completed Successfully!"); + } + + /* "parser.java":1311 */ + +} +/* "parser.y":160 */ + + +class ParserLexer implements Parser.Lexer { + InputStreamReader it; + LexerAnalysis yylex; + + public ParserLexer(InputStream is){ + it = new InputStreamReader(is); + yylex = new LexerAnalysis(it); + } + + @Override + public void yyerror (String s){ + System.out.println("---------------------\nParser Completed with some errors"); + System.err.println("\t-> Error: " + s); + } + + @Override + public Object getLVal() { + return null; + } + + @Override + public int yylex () throws IOException{ + int token = yylex.yylex(); + return token; + } +} From c1b697c200d2d95b5e6e218c50baa49cbf137499 Mon Sep 17 00:00:00 2001 From: Talgat Bektleuov <67966867+TalgatBektleuov@users.noreply.github.com> Date: Fri, 4 Mar 2022 17:55:45 +0300 Subject: [PATCH 2/4] Update parser.y --- parser.y | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/parser.y b/parser.y index 178fcb9..f07f2d0 100644 --- a/parser.y +++ b/parser.y @@ -1 +1,136 @@ -%define api.prefix {Parser} %define api.parser.class {Parser} %define api.parser.public %define parse.error verbose %code imports{ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.IOException; } %code { public static void main(String args[]) throws IOException { ParserLexer lexer = new ParserLexer(System.in); Parser p = new Parser(lexer); if(parser.parse()) System.out.println("---------------------\n Parser Completed Successfully!"); return; } } %left PLUS MINUS %left MULT DIV //All keywords %token KW_IF KW_IS KW_VAR KW_END //Boolean %token BOOLEAN_LITERAL // Separators %token LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK SEMICOLON COMMA DOT // Operators %token EQ ASSIGN GT LT LTEQ GTEQ PLUS MINUS MULT DIV OR AND XOR NOT // Numeric %token INTEGER_LITERAL REAL_LITERAL //Other tokens %token COMMENT WHITESPACE STRING UNKNOWN_TOKEN EOF IDENTIFIER %% Prog : Body ; Body : /* empty */ | Declaration Body | Statement Body | Expression Body ; Declaration : KW_VAR IDENTIFIER SEMICOLON | KW_VAR IDENTIFIER ASSIGN Expression SEMICOLON | KW_VAR IDENTIFIER ASSIGN FunctionDef SEMICOLON ; Expression : | FunctionCall | Calc | Relation | IDENTIFIER | Value ; Relation : Expression LT Expression | Expression LTEQ Expression | Expression GT Expression | Expression GTEQ Expression | Expression EQ Expression | Expression AND Expression | Expression OR Expression | Expression XOR Expression | NOT Expression ; Calc : Expression PLUS Expression | Expression MINUS Expression | Expression MULT Expression | Expression DIV Expression ; Value : STRING | INTEGER_LITERAL | REAL_LITERAL ; FunctionDef : LPAREN Params RPAREN KW_IS Body KW_END ; FunctionCall : IDENTIFIER LPAREN Args RPAREN ; Params: //empty | IDENTIFIER COMMA Params ; Args: //empty | Expression COMMA Args ; %% class ParserLexer implements Parser.Lexer { InputStreamReader it; Yylex yylex; public ParserLexer(InputStream is){ it = new InputStreamReader(is); yylex = new Yylex(it); } @Override public void yyerror (String s){ System.out.println("---------------------\nParser Completed with some errors"); System.err.println("\t-> Error: " + s); } @Override public Object getLVal() { return null; } @Override public int yylex () throws IOException{ int token = yylex.yylex(); return token; } } \ No newline at end of file +%define api.prefix {Parser} +%define api.parser.class {Parser} +%define api.parser.public +%define parse.error verbose + +%code imports{ + import java.io.InputStream; + import java.io.InputStreamReader; + import java.io.Reader; + import java.io.IOException; +} + + +%code { + public static void main(String args[]) throws IOException { + ParserLexer lexer = new ParserLexer(System.in); + Parser p = new Parser(lexer); + if(parser.parse()) + System.out.println("---------------------\n Parser Completed Successfully!"); + return; + } +} + +%left PLUS MINUS +%left MULT DIV + +//All keywords +%token KW_IF KW_IS KW_VAR KW_END + +//Boolean +%token BOOLEAN_LITERAL + +// Separators +%token LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK SEMICOLON COMMA DOT + +// Operators +%token EQ ASSIGN GT LT LTEQ GTEQ PLUS MINUS MULT DIV OR AND XOR NOT + +// Numeric +%token INTEGER_LITERAL REAL_LITERAL + +//Other tokens +%token COMMENT WHITESPACE STRING UNKNOWN_TOKEN EOF IDENTIFIER + +%% + + +Prog : Body +; + +Body : /* empty */ + | Declaration Body + | Statement Body + | Expression Body +; + +Declaration : KW_VAR IDENTIFIER SEMICOLON + | KW_VAR IDENTIFIER ASSIGN Expression SEMICOLON + | KW_VAR IDENTIFIER ASSIGN FunctionDef SEMICOLON +; + +Expression : + | FunctionCall + | Calc + | Relation + | IDENTIFIER + | Value +; + +Relation : + Expression LT Expression + | Expression LTEQ Expression + | Expression GT Expression + | Expression GTEQ Expression + | Expression EQ Expression + | Expression AND Expression + | Expression OR Expression + | Expression XOR Expression + | NOT Expression +; + +Calc : + Expression PLUS Expression + | Expression MINUS Expression + | Expression MULT Expression + | Expression DIV Expression +; + +Value : + STRING + | INTEGER_LITERAL + | REAL_LITERAL +; + +FunctionDef : LPAREN Params RPAREN KW_IS Body KW_END +; + +FunctionCall : IDENTIFIER LPAREN Args RPAREN +; + +Params: //empty + | IDENTIFIER COMMA Params +; + +Args: //empty + | Expression COMMA Args +; + +%% + +class ParserLexer implements Parser.Lexer { + InputStreamReader it; + Yylex yylex; + + public ParserLexer(InputStream is){ + it = new InputStreamReader(is); + yylex = new Yylex(it); + } + + @Override + public void yyerror (String s){ + System.out.println("---------------------\nParser Completed with some errors"); + System.err.println("\t-> Error: " + s); + } + + @Override + public Object getLVal() { + return null; + } + + @Override + public int yylex () throws IOException{ + int token = yylex.yylex(); + return token; + } +} From a6d5c63fefbe8a5c0e2048ce1a028b6fc1039d6e Mon Sep 17 00:00:00 2001 From: Talgat Bektleuov <67966867+TalgatBektleuov@users.noreply.github.com> Date: Fri, 4 Mar 2022 17:56:01 +0300 Subject: [PATCH 3/4] Update lexer.l --- lexer.l | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/lexer.l b/lexer.l index 9c54124..a2f129e 100644 --- a/lexer.l +++ b/lexer.l @@ -1 +1,118 @@ -import java.util.*; %% %class Parser.Lexer %standalone %unicode %type JavaType %line %column %byaccj /* main character classes */ LineTerminator = \r|\n|\r\n Semicolon = ; Digit = [0-9] Letter = [a-zA-Z] LetterOrDigit = [a-zA-Z0-9] WhiteSpace = {LineTerminator} | [ \t\f] /* comments */ Comment = {TraditionalComment}|{EndOfLineComment} TraditionalComment = "/\**\*/" EndOfLineComment = "//*{LineTerminator}?" /* identifiers */ Identifier = {Letter}{LetterOrDigit}* /* integer literals */ IntegerLiteral = 0 | [1-9][0-9]* /* Real number literals */ RealLiteral = ({FLit1}|{FLit2}|{FLit3}){Exponent}?[fF] FLit1 = [0-9]+\.[0-9]* FLit2 = \.[0-9]+ FLit3 = [0-9]+ Exponent = [eE][+-]?[0-9]+ UNKNOWN_TOKEN = . %state STRING %% { /* keywords */ "is" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_IS; } "var" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_VAR; } "if" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_IF; } "then" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_THEN; } "else" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_ELSE; } "end" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_END; } "while" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_WHILE; } "for" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FOR; } "loop" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_LOOP; } "return" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_RETURN; } "print" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_PRINT; } "func" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FUNC; } /* boolean literals */ "true" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_TRUE; } "false" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FALSE; } /* separators */ "(" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LPAREN; } ")" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RPAREN; } "{" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LBRACE; } "}" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RBRACE; } "[" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LBRACK; } "]" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RBRACK; } ";" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.SEMICOLON; } "," { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.COMMA; } "." { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.DOT; } /* operators */ "=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.EQ; } ":=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.ASSIGN; } ">" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.GT; } "<" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LT; } "<=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LTEQ; } ">=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.GTEQ; } "+" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.PLUS; } "-" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.MINUS; } "*" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.MULT; } "/" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.DIV; } "=>" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LAMBDA; } "or" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.OR; } "and" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.AND; } "xor" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.XOR; } /* numeric literals */ {IntegerLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.INTEGER_LITERAL; } {RealLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.REAL_LITERAL; } {Identifier} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.IDENTIFIER; } /* comments */ {Comment} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.COMMENT; } /* whitespace */ {WhiteSpace} { return Lexeme.WHITESPACE; } "\"([^\\\"\n\r]*\\[^\n\r])*\"" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.STRING; } } /* UNKNOWN TOKENS */ {UNKNOWN_TOKEN} {return Lexeme.UNKNOWN_TOKEN;} /* error fallback */ [^] { throw new RuntimeException("Illegal character \""+yytext()+"\" at line "+yyline+", column "+yycolumn); } <> { return Lexeme.EOF; } \ No newline at end of file +import java.util.*; + +%% +%class Parser.Lexer +%standalone +%unicode +%type JavaType +%line +%column +%byaccj + + + +/* main character classes */ +LineTerminator = \r|\n|\r\n +Semicolon = ; +Digit = [0-9] +Letter = [a-zA-Z] +LetterOrDigit = [a-zA-Z0-9] + +WhiteSpace = {LineTerminator} | [ \t\f] + +/* comments */ +Comment = {TraditionalComment}|{EndOfLineComment} + +TraditionalComment = "/\**\*/" +EndOfLineComment = "//*{LineTerminator}?" + +/* identifiers */ +Identifier = {Letter}{LetterOrDigit}* + +/* integer literals */ +IntegerLiteral = 0 | [1-9][0-9]* + +/* Real number literals */ +RealLiteral = ({FLit1}|{FLit2}|{FLit3}){Exponent}?[fF] + +FLit1 = [0-9]+\.[0-9]* +FLit2 = \.[0-9]+ +FLit3 = [0-9]+ +Exponent = [eE][+-]?[0-9]+ + +UNKNOWN_TOKEN = . + +%state STRING + +%% + { + + /* keywords */ + "is" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_IS; } + "var" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_VAR; } + "if" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_IF; } + "then" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_THEN; } + "else" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_ELSE; } + "end" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_END; } + "while" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_WHILE; } + "for" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FOR; } + "loop" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_LOOP; } + "return" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_RETURN; } + "print" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_PRINT; } + "func" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FUNC; } + + + /* boolean literals */ + "true" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_TRUE; } + "false" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FALSE; } + + + /* separators */ + "(" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LPAREN; } + ")" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RPAREN; } + "{" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LBRACE; } + "}" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RBRACE; } + "[" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LBRACK; } + "]" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RBRACK; } + ";" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.SEMICOLON; } + "," { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.COMMA; } + "." { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.DOT; } + + /* operators */ + "=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.EQ; } + ":=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.ASSIGN; } + ">" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.GT; } + "<" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LT; } + "<=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LTEQ; } + ">=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.GTEQ; } + "+" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.PLUS; } + "-" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.MINUS; } + "*" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.MULT; } + "/" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.DIV; } + "=>" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LAMBDA; } + "or" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.OR; } + "and" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.AND; } + "xor" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.XOR; } + + /* numeric literals */ + + {IntegerLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.INTEGER_LITERAL; } + {RealLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.REAL_LITERAL; } + {Identifier} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.IDENTIFIER; } + + /* comments */ + {Comment} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.COMMENT; } + + /* whitespace */ + {WhiteSpace} { return Lexeme.WHITESPACE; } + + "\"([^\\\"\n\r]*\\[^\n\r])*\"" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.STRING; } +} + +/* UNKNOWN TOKENS */ +{UNKNOWN_TOKEN} {return Lexeme.UNKNOWN_TOKEN;} + +/* error fallback */ +[^] { throw new RuntimeException("Illegal character \""+yytext()+"\" at line "+yyline+", column "+yycolumn); } +<> { return Lexeme.EOF; } + From ee723a00543f8af8fbf199b6a8fb151034ab0974 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 4 Mar 2022 17:58:05 +0300 Subject: [PATCH 4/4] EOL fix --- lexer.l | 117 +++++++++++++++++++++++++++++++++- parser.y | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 303 insertions(+), 2 deletions(-) diff --git a/lexer.l b/lexer.l index 9c54124..5a69ece 100644 --- a/lexer.l +++ b/lexer.l @@ -1 +1,116 @@ -import java.util.*; %% %class Parser.Lexer %standalone %unicode %type JavaType %line %column %byaccj /* main character classes */ LineTerminator = \r|\n|\r\n Semicolon = ; Digit = [0-9] Letter = [a-zA-Z] LetterOrDigit = [a-zA-Z0-9] WhiteSpace = {LineTerminator} | [ \t\f] /* comments */ Comment = {TraditionalComment}|{EndOfLineComment} TraditionalComment = "/\**\*/" EndOfLineComment = "//*{LineTerminator}?" /* identifiers */ Identifier = {Letter}{LetterOrDigit}* /* integer literals */ IntegerLiteral = 0 | [1-9][0-9]* /* Real number literals */ RealLiteral = ({FLit1}|{FLit2}|{FLit3}){Exponent}?[fF] FLit1 = [0-9]+\.[0-9]* FLit2 = \.[0-9]+ FLit3 = [0-9]+ Exponent = [eE][+-]?[0-9]+ UNKNOWN_TOKEN = . %state STRING %% { /* keywords */ "is" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_IS; } "var" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_VAR; } "if" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_IF; } "then" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_THEN; } "else" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_ELSE; } "end" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_END; } "while" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_WHILE; } "for" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FOR; } "loop" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_LOOP; } "return" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_RETURN; } "print" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_PRINT; } "func" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FUNC; } /* boolean literals */ "true" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_TRUE; } "false" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.KW_FALSE; } /* separators */ "(" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LPAREN; } ")" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RPAREN; } "{" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LBRACE; } "}" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RBRACE; } "[" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LBRACK; } "]" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.RBRACK; } ";" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.SEMICOLON; } "," { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.COMMA; } "." { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.DOT; } /* operators */ "=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.EQ; } ":=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.ASSIGN; } ">" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.GT; } "<" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LT; } "<=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LTEQ; } ">=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.GTEQ; } "+" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.PLUS; } "-" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.MINUS; } "*" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.MULT; } "/" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.DIV; } "=>" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.LAMBDA; } "or" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.OR; } "and" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.AND; } "xor" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.XOR; } /* numeric literals */ {IntegerLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.INTEGER_LITERAL; } {RealLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.REAL_LITERAL; } {Identifier} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.IDENTIFIER; } /* comments */ {Comment} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.COMMENT; } /* whitespace */ {WhiteSpace} { return Lexeme.WHITESPACE; } "\"([^\\\"\n\r]*\\[^\n\r])*\"" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexeme.STRING; } } /* UNKNOWN TOKENS */ {UNKNOWN_TOKEN} {return Lexeme.UNKNOWN_TOKEN;} /* error fallback */ [^] { throw new RuntimeException("Illegal character \""+yytext()+"\" at line "+yyline+", column "+yycolumn); } <> { return Lexeme.EOF; } \ No newline at end of file +import java.util.*; + +%% +%class LexerAnalysis +%standalone +%unicode +%type int +%line +%column +%byaccj + + +/* main character classes */ +LineTerminator = \r|\n|\r\n +Letter = [a-zA-Z] +LetterOrDigit = [a-zA-Z0-9] + +WhiteSpace = {LineTerminator} | [ \t\f] + +/* comments */ +Comment = {TraditionalComment}|{EndOfLineComment} + +TraditionalComment = "/\**\*/" +EndOfLineComment = "//*{LineTerminator}?" + +/* identifiers */ +Identifier = {Letter}{LetterOrDigit}* + +/* integer literals */ +IntegerLiteral = 0 | [1-9][0-9]* + +/* Real number literals */ +RealLiteral = ({FLit1}|{FLit2}|{FLit3}){Exponent}?[fF] + +FLit1 = [0-9]+\.[0-9]* +FLit2 = \.[0-9]+ +FLit3 = [0-9]+ +Exponent = [eE][+-]?[0-9]+ + +UNKNOWN_TOKEN = . + +%state STRING + +%% + { + + /* keywords */ + "is" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_IS; } + "var" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_VAR; } + "if" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_IF; } + "then" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_THEN; } + "else" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_ELSE; } + "end" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_END; } + "while" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_WHILE; } + "for" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_FOR; } + "in" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_IN; } + "loop" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_LOOP; } + "return" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_RETURN; } + "print" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_PRINT; } + "func" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_FUNC; } + + + /* boolean literals */ + "true" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_TRUE; } + "false" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.KW_FALSE; } + + + /* separators */ + "(" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.LPAREN; } + ")" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.RPAREN; } + "{" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.LBRACE; } + "}" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.RBRACE; } + "[" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.LBRACK; } + "]" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.RBRACK; } + ";" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.SEMICOLON; } + "," { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.COMMA; } + "." { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.DOT; } + + /* operators */ + "=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.EQ; } + ":=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.ASSIGN; } + ">" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.GT; } + "<" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.LT; } + "<=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.LTEQ; } + ">=" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.GTEQ; } + "+" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.PLUS; } + "-" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.MINUS; } + "*" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.MULT; } + "/" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.DIV; } + "or" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.OR; } + "and" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.AND; } + "xor" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.XOR; } + "not" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.NOT; } + + /* numeric literals */ + + {IntegerLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.INTEGER_LITERAL; } + {RealLiteral} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.REAL_LITERAL; } + {Identifier} { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.IDENTIFIER; } + + /* comments */ + {Comment} ; + + /* whitespace */ + {WhiteSpace} ; + + "\"([^\\\"\n\r]*\\[^\n\r])*\"" { System.out.println("[token at line " + yyline + ":" + yycolumn + " = \"" + yytext() + "\"]"); return Lexer.STRING; } +} + +/* UNKNOWN TOKENS */ +{UNKNOWN_TOKEN} {return Lexer.UNKNOWN_TOKEN;} + +/* error fallback */ +[^] { throw new RuntimeException("Illegal character \""+yytext()+"\" at line "+yyline+", column "+yycolumn); } +<> { return Lexer.EOF; } + diff --git a/parser.y b/parser.y index 178fcb9..e0dba95 100644 --- a/parser.y +++ b/parser.y @@ -1 +1,187 @@ -%define api.prefix {Parser} %define api.parser.class {Parser} %define api.parser.public %define parse.error verbose %code imports{ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.IOException; } %code { public static void main(String args[]) throws IOException { ParserLexer lexer = new ParserLexer(System.in); Parser p = new Parser(lexer); if(parser.parse()) System.out.println("---------------------\n Parser Completed Successfully!"); return; } } %left PLUS MINUS %left MULT DIV //All keywords %token KW_IF KW_IS KW_VAR KW_END //Boolean %token BOOLEAN_LITERAL // Separators %token LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK SEMICOLON COMMA DOT // Operators %token EQ ASSIGN GT LT LTEQ GTEQ PLUS MINUS MULT DIV OR AND XOR NOT // Numeric %token INTEGER_LITERAL REAL_LITERAL //Other tokens %token COMMENT WHITESPACE STRING UNKNOWN_TOKEN EOF IDENTIFIER %% Prog : Body ; Body : /* empty */ | Declaration Body | Statement Body | Expression Body ; Declaration : KW_VAR IDENTIFIER SEMICOLON | KW_VAR IDENTIFIER ASSIGN Expression SEMICOLON | KW_VAR IDENTIFIER ASSIGN FunctionDef SEMICOLON ; Expression : | FunctionCall | Calc | Relation | IDENTIFIER | Value ; Relation : Expression LT Expression | Expression LTEQ Expression | Expression GT Expression | Expression GTEQ Expression | Expression EQ Expression | Expression AND Expression | Expression OR Expression | Expression XOR Expression | NOT Expression ; Calc : Expression PLUS Expression | Expression MINUS Expression | Expression MULT Expression | Expression DIV Expression ; Value : STRING | INTEGER_LITERAL | REAL_LITERAL ; FunctionDef : LPAREN Params RPAREN KW_IS Body KW_END ; FunctionCall : IDENTIFIER LPAREN Args RPAREN ; Params: //empty | IDENTIFIER COMMA Params ; Args: //empty | Expression COMMA Args ; %% class ParserLexer implements Parser.Lexer { InputStreamReader it; Yylex yylex; public ParserLexer(InputStream is){ it = new InputStreamReader(is); yylex = new Yylex(it); } @Override public void yyerror (String s){ System.out.println("---------------------\nParser Completed with some errors"); System.err.println("\t-> Error: " + s); } @Override public Object getLVal() { return null; } @Override public int yylex () throws IOException{ int token = yylex.yylex(); return token; } } \ No newline at end of file +%define api.prefix {Parser} +%define api.parser.class {Parser} +%define api.package {Parser} +%define api.parser.public +%define parse.error verbose + +%code imports{ + import java.io.InputStream; + import java.io.InputStreamReader; + import java.io.Reader; + import java.io.IOException; +} + + +%code { + public static void main(String args[]) throws IOException { + ParserLexer lexer = new ParserLexer(System.in); + Parser parser = new Parser(lexer); + if(parser.parse()) + System.out.println("---------------------\n Parser Completed Successfully!"); + } +} + + +%left KW_RETURN KW_PRINT + +%left COMMA + +%left PLUS MINUS +%left MULT DIV + +%left GT LT GTEQ LTEQ + +%left EQ + +%left NOT +%left XOR +%left OR +%left AND +%left ASSIGN + +%left LPAREN LBRACE LBRACK + +//All keywords +%token KW_IF KW_IS KW_VAR KW_END KW_TRUE KW_FALSE KW_THEN KW_ELSE KW_FOR KW_LOOP KW_IN KW_WHILE KW_FUNC KW_RETURN KW_PRINT + +// Separators +%token LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK SEMICOLON COMMA DOT + +// Operators +%token EQ ASSIGN GT LT LTEQ GTEQ PLUS MINUS MULT DIV OR AND XOR NOT + +// Numeric +%token INTEGER_LITERAL REAL_LITERAL + +//Other tokens +%token STRING IDENTIFIER + +%% + +Prog : Body +; + +Body : /* empty */ + | Declaration SEMICOLON Body + | Assignment SEMICOLON Body + | Expression SEMICOLON Body + | PrintStatement SEMICOLON Body + | Statement Body + | ReturnStatement +; + +Declaration : KW_VAR IDENTIFIER + | KW_VAR IDENTIFIER ASSIGN Expression + | KW_VAR IDENTIFIER ASSIGN FunctionDef +; + +ReturnStatement : KW_RETURN Expression ; + +PrintStatement : KW_PRINT Args ; + +Assignment : IDENTIFIER ASSIGN Expression ; + +Expression : IDENTIFIER + | LPAREN Expression RPAREN + | Relation + | Value + | FunctionCall + | Calc + | ArrayAccess +; + +ArrayAccess : Expression LBRACK Expression RBRACK ; + +Relation : Expression LT Expression + | Expression LTEQ Expression + | Expression GT Expression + | Expression GTEQ Expression + | Expression EQ Expression + | Expression AND Expression + | Expression OR Expression + | Expression XOR Expression + | NOT Expression +; + +Calc : Expression PLUS Expression + | Expression MINUS Expression + | Expression MULT Expression + | Expression DIV Expression +; + +Value : STRING + | INTEGER_LITERAL + | REAL_LITERAL + | KW_TRUE + | KW_FALSE + | ArrayValue + | DictValue +; + +ArrayValue : LBRACK ArrayValues RBRACK ; + +DictValue : LBRACE DictValues RBRACE ; + +DictValues : //empty + | Assignment COMMA DictValues +; + +ArrayValues : //empty + | Expression COMMA ArrayValues +; + +FunctionDef : KW_FUNC LPAREN Params RPAREN KW_IS Body KW_END ; + +FunctionCall : IDENTIFIER LPAREN Args RPAREN ; + +Params: //empty + | IDENTIFIER COMMA Params +; + +Args: //empty + | Expression COMMA Args +; + +Statement : IfStatement + | ForStatement + | WhileStatement +; + +IfStatement : KW_IF LPAREN Expression RPAREN KW_THEN Body KW_END + | KW_IF LPAREN Expression RPAREN KW_THEN Body KW_ELSE Body KW_END +; + +ForStatement : KW_FOR LPAREN IDENTIFIER KW_IN Expression RPAREN KW_LOOP Body KW_END ; + +WhileStatement : KW_WHILE LPAREN Expression RPAREN KW_LOOP Body KW_END ; + + + +%% + +class ParserLexer implements Parser.Lexer { + InputStreamReader it; + Lexer yylex; + + public ParserLexer(InputStream is){ + it = new InputStreamReader(is); + yylex = new Lexer(it); + } + + @Override + public void yyerror (String s){ + System.out.println("---------------------\nParser Completed with some errors"); + System.err.println("\t-> Error: " + s); + } + + @Override + public Object getLVal() { + return null; + } + + @Override + public int yylex () throws IOException{ + int token = yylex.yylex(); + return token; + } +} \ No newline at end of file