diff --git a/sources/zweic/Parser.scala b/sources/zweic/Parser.scala index d0c1157..e05a133 100755 --- a/sources/zweic/Parser.scala +++ b/sources/zweic/Parser.scala @@ -1,414 +1,414 @@ -/* zweic -- a compiler for zwei - * - * Stephane Micheloud & LAMP - * - * $Id$ - */ - -package zweic; - -/** - * This class implements the parser of the zwei compiler. - */ -class Parser(in: java.io.InputStream) extends Scanner(in) { - - import Tokens._; - - var pushedBack: Option[Triple[Int,String,Token]] = None; - - var pos: Int = 0; - - /** - * Reports an error that a specific token was expected but - * a different token found. - */ - private def error(expected: Token): Unit = - error("token of class " + expected); - - /** - * Reports an error that a specific token was expected but - * a different token found. - */ - private def error(expected: String): Unit = { - val message = "syntax error\n" + - "expected: " + expected + "\n" + - "found : " + representation; - Report.fail(start, message); - } - - /** - * If the current token corresponds to the token class 'expected' - * then skip it, otherwise signal an error. - */ - private def accept(expected: Token): Unit = - if (token == expected) - nextToken; - else - error(expected); - - /** - * If the current token corresponds to the token class 'expected' - * then skip it and return success. - */ - private def check(expected: Token): Boolean = - if (token == expected) { - nextToken; - true - } else - false; - - override def nextToken: Unit = pushedBack match { - case Some(Triple(p, c, t)) => - token = t; - chars = c; - pos = p; - pushedBack = None; - case None => return super.nextToken; - } - - def peekAhead: Token = pushedBack match { - case Some(Triple(p, c, t)) => return t; - case None => - val savedToken = token; - val savedChars = chars; - val savedPos = pos; - val rval = token; - nextToken; - pushedBack = Some(Triple(pos, chars, token)); - token = savedToken; - chars = savedChars; - pos = savedPos; - return rval; - } - - /** - * Parse the input and return an abstract syntax tree. - */ - def parse: Program = { - val result = program(); - accept(EOF); - //return result; - return null; - } - - /* --------------------------------------------------*/ - - /** - * Program = { ClassDecl } Expression - */ - private def program(): Program = { - while (token == CLASS) { - classDecl(); - } - expression(); - return null; - } - - /** - * ClassDecl = "class" ident ["extends" ident] "{" {Member} "}" - */ - private def classDecl(): Tree = { - accept(CLASS); - accept(IDENT); - if (check (EXTENDS)) { - accept(IDENT); - } - accept (LACCOLADE); - while (token != RACCOLADE) { - member(); - } - return null; - } - - /** - * Member = Formal - * (";" | - * "(" [Formal {"," Formal}] ")" Block) - */ - private def member(): Tree = { - formal(); - if (check (SEMICOLON)) { - return null; - } else { - accept (LPAREN); - //TODO: is this neccessary? - if (token == IDENT || token == INT || token == NULLTYPE) { - formal(); - while (token != RPAREN) { - accept (PERIOD); - formal(); - } - } - accept (RPAREN); - block; - return null; - } - } - - /** - * Formal = Type ident - */ - private def formal(): Tree = { - type1(); - accept(IDENT); - return null; - } - - /** - * Block = "{" {Statements} ["return" Expression] "}" - */ - private def block(): Tree = { - accept (LACCOLADE); - while (token != RETURN && token != RACCOLADE) { - statement(); - } - if (check (RETURN)) { - expression(); - } - accept(RACCOLADE); - return null; - } - - /** - * Type1 = "Int" | "Null" | ident - */ - private def type1(): Tree = token match { - case INT => nextToken; return null; - case NULLTYPE => nextToken; return null; - case ident => nextToken; return null; - //TODO: better error message - case _ => error("illegal start of expression"); return null; - } - - /** - * Statement = "while" "(" Expression ")" "{" {Statement} "}" - * | Formal "=" Expression ";" - * | ident "=" Expression ";" - * | Expression ";" - * | "printInt" "(" Expression ")" ";" - * | "printChar" "(" Expression ")" ";" - */ - private def statement(): Tree = { - if (token == IDENT) { - peekAhead match { - case IDENT => - //type definition and affection - formal(); - accept(EQUALS); - expression(); - accept(SEMICOLON); - - case EQUALS => - //affection - accept(IDENT); - accept(EQUALS); - expression(); - accept(SEMICOLON); - - case _ => - //expression - expression(); - accept(SEMICOLON); - } - - } else { - if (check(WHILE)) { - //while - accept(LPAREN); - expression(); - accept(RPAREN); - accept(LACCOLADE); - statement(); - accept(RACCOLADE); - - } else if (token == NULLTYPE || token == INT) { - //type definition and affection - formal(); - accept(EQUALS); - expression(); - accept(SEMICOLON); - - } else if (check(PRINTINT)) { - //printInt - accept(LPAREN); - expression(); - accept(RPAREN); - accept(SEMICOLON); - - } else if (check(PRINTCHAR)) { - //printChar - accept(LPAREN); - expression(); - accept(RPAREN); - accept(SEMICOLON); - } else { - //expression - expression(); - accept(SEMICOLON); - } - } - return null; - } - - /** - * Expression = "if" "(" Expression ")" Expression [ "else" Expression ] - */ - private def expression(): Tree = { - accept(IF); - accept(LPAREN); - expression(); - accept(RPAREN); - expression(); - if ( check(ELSE) ) { - expression(); - } - return null; - } - - /** - * CmpExpression = [ SumExpression CompOp ] SumExpression - * MyCmpExpression = SumExpression [ CompOp SumExpression ] - */ - private def cmpExpression(): Tree = { - sumExpression(); - if ( token == EQ || token == NE || token == LT - || token == GT || token == LE || token == GE ) { - compOp(); - sumExpression(); - } - return null; - } - - /** - * SumExpression = Term | SumExpression SumOp Term - * MySumExpression = Term [ SumOp SumExpression ] - */ - private def sumExpression(): Tree = { - term(); - if ( token == ADD || token == SUB || token == OR ) { - sumOp(); - sumExpression(); - } - return null; - } - - /** - * Term = [ Term ProdOp ] [ NegateOp ] Factor - * MyTerm = [ NegateOp ] Factor [ ProdOp Term ] - */ - private def term(): Tree = { - if ( token == SUB || token == NOT ) { - nextToken; - } - factor(); - if ( token == MUL || token == DIV || token == MOD || token == AND ) { - prodOp(); - term(); - } - return null; - } - - /** - * Factor = look it up yourself! - */ - private def factor(): Tree = { - token match { - case IDENT => nextToken; - case NUMBER => nextToken; - case STRING => nextToken; - case TRUE => nextToken; - case FALSE => nextToken; - case THIS => nextToken; - case NULLFACTOR => nextToken; - case READINT => nextToken; - case READCHAR => nextToken; - case LPAREN => nextToken; expression(); accept(RPAREN); - case LACCOLADE => block(); - case NEW => nextToken; accept(IDENT); params(); - case _ => error("illegal start of expression"); - } - - if ( check(DOT) ) { - accept(IDENT); - if ( token == LPAREN ) { - params(); - } - } - - return null; - } - - /** - * Expressions = [ Expression { "," Expression } ] - */ - private def expressions(): Tree = { - if ( token == IF || token == SUB || token == NOT - || token == IDENT || token == NUMBER - || token == STRING || token == TRUE - || token == FALSE || token == THIS - || token == NULLFACTOR || token == READINT - || token == READCHAR || token == LPAREN - || token == NEW || token == LACCOLADE ) { - expression(); - while ( token == PERIOD ) { - expression(); - } - } - return null; - } - - /** - * Params = "(" Expressions ")" - */ - private def params(): Tree = { - accept(LPAREN); - expressions(); - accept(RPAREN); - return null; - } - - /** - * ProdOp = "*" | "/" | "%" | "&&" - */ - private def prodOp(): Tree = token match { - case MUL => nextToken; return null; - case DIV => nextToken; return null; - case MOD => nextToken; return null; - case AND => nextToken; return null; - case _ => error("illegal start of expression"); return null; - } - - /** - * NegateOp = "-" | "!" - */ - private def negateOp(): Tree = token match { - case SUB => nextToken; return null; - case NOT => nextToken; return null; - case _ => error("illegal start of expression"); return null; - } - - /** - * SumOp = "+" | "-" | "||" - */ - private def sumOp(): Tree = token match { - case ADD => nextToken; return null; - case SUB => nextToken; return null; - case OR => nextToken; return null; - case _ => error("illegal start of expression"); return null; - } - - - /** - * CompOp = "==" | "!" | "<" | ">" | "<=" | ">=" - */ - private def compOp(): Tree = token match { - case EQ => nextToken; return null; - case NE => nextToken; return null; - case LT => nextToken; return null; - case GT => nextToken; return null; - case LE => nextToken; return null; - case GE => nextToken; return null; - case _ => error("illegal start of expression"); return null; - } - -} +/* zweic -- a compiler for zwei + * + * Stephane Micheloud & LAMP + * + * $Id$ + */ + +package zweic; + +/** + * This class implements the parser of the zwei compiler. + */ +class Parser(in: java.io.InputStream) extends Scanner(in) { + + import Tokens._; + + var pushedBack: Option[Triple[Int,String,Token]] = None; + + var pos: Int = 0; + + /** + * Reports an error that a specific token was expected but + * a different token found. + */ + private def error(expected: Token): Unit = + error("token of class " + expected); + + /** + * Reports an error that a specific token was expected but + * a different token found. + */ + private def error(expected: String): Unit = { + val message = "syntax error\n" + + "expected: " + expected + "\n" + + "found : " + representation; + Report.fail(start, message); + } + + /** + * If the current token corresponds to the token class 'expected' + * then skip it, otherwise signal an error. + */ + private def accept(expected: Token): Unit = + if (token == expected) + nextToken; + else + error(expected); + + /** + * If the current token corresponds to the token class 'expected' + * then skip it and return success. + */ + private def check(expected: Token): Boolean = + if (token == expected) { + nextToken; + true + } else + false; + + override def nextToken: Unit = pushedBack match { + case Some(Triple(p, c, t)) => + token = t; + chars = c; + pos = p; + pushedBack = None; + case _ => return super.nextToken; + } + + def peekAhead: Token = pushedBack match { + case Some(Triple(p, c, t)) => return t; + case _ => + val savedToken = token; + val savedChars = chars; + val savedPos = pos; + val rval = token; + nextToken; + pushedBack = Some(Triple(pos, chars, token)); + token = savedToken; + chars = savedChars; + pos = savedPos; + return rval; + } + + /** + * Parse the input and return an abstract syntax tree. + */ + def parse: Program = { + val result = program(); + accept(EOF); + //return result; + return null; + } + + /* --------------------------------------------------*/ + + /** + * Program = { ClassDecl } Expression + */ + private def program(): Program = { + while (token == CLASS) { + classDecl(); + } + expression(); + return null; + } + + /** + * ClassDecl = "class" ident ["extends" ident] "{" {Member} "}" + */ + private def classDecl(): Tree = { + accept(CLASS); + accept(IDENT); + if (check (EXTENDS)) { + accept(IDENT); + } + accept (LACCOLADE); + while (token != RACCOLADE) { + member(); + } + return null; + } + + /** + * Member = Formal + * (";" | + * "(" [Formal {"," Formal}] ")" Block) + */ + private def member(): Tree = { + formal(); + if (check (SEMICOLON)) { + return null; + } else { + accept (LPAREN); + //TODO: is this neccessary? + if (token == IDENT || token == INT || token == NULLTYPE) { + formal(); + while (token != RPAREN) { + accept (PERIOD); + formal(); + } + } + accept (RPAREN); + block; + return null; + } + } + + /** + * Formal = Type ident + */ + private def formal(): Tree = { + type1(); + accept(IDENT); + return null; + } + + /** + * Block = "{" {Statements} ["return" Expression] "}" + */ + private def block(): Tree = { + accept (LACCOLADE); + while (token != RETURN && token != RACCOLADE) { + statement(); + } + if (check (RETURN)) { + expression(); + } + accept(RACCOLADE); + return null; + } + + /** + * Type1 = "Int" | "Null" | ident + */ + private def type1(): Tree = token match { + case INT => nextToken; return null; + case NULLTYPE => nextToken; return null; + case ident => nextToken; return null; + //TODO: better error message + case _ => error("illegal start of expression"); return null; + } + + /** + * Statement = "while" "(" Expression ")" "{" {Statement} "}" + * | Formal "=" Expression ";" + * | ident "=" Expression ";" + * | Expression ";" + * | "printInt" "(" Expression ")" ";" + * | "printChar" "(" Expression ")" ";" + */ + private def statement(): Tree = { + if (token == IDENT) { + peekAhead match { + case IDENT => + //type definition and affection + formal(); + accept(EQUALS); + expression(); + accept(SEMICOLON); + + case EQUALS => + //affection + accept(IDENT); + accept(EQUALS); + expression(); + accept(SEMICOLON); + + case _ => + //expression + expression(); + accept(SEMICOLON); + } + + } else { + if (check(WHILE)) { + //while + accept(LPAREN); + expression(); + accept(RPAREN); + accept(LACCOLADE); + statement(); + accept(RACCOLADE); + + } else if (token == NULLTYPE || token == INT) { + //type definition and affection + formal(); + accept(EQUALS); + expression(); + accept(SEMICOLON); + + } else if (check(PRINTINT)) { + //printInt + accept(LPAREN); + expression(); + accept(RPAREN); + accept(SEMICOLON); + + } else if (check(PRINTCHAR)) { + //printChar + accept(LPAREN); + expression(); + accept(RPAREN); + accept(SEMICOLON); + } else { + //expression + expression(); + accept(SEMICOLON); + } + } + return null; + } + + /** + * Expression = "if" "(" Expression ")" Expression [ "else" Expression ] + */ + private def expression(): Tree = { + accept(IF); + accept(LPAREN); + expression(); + accept(RPAREN); + expression(); + if ( check(ELSE) ) { + expression(); + } + return null; + } + + /** + * CmpExpression = [ SumExpression CompOp ] SumExpression + * MyCmpExpression = SumExpression [ CompOp SumExpression ] + */ + private def cmpExpression(): Tree = { + sumExpression(); + if ( token == EQ || token == NE || token == LT + || token == GT || token == LE || token == GE ) { + compOp(); + sumExpression(); + } + return null; + } + + /** + * SumExpression = Term | SumExpression SumOp Term + * MySumExpression = Term [ SumOp SumExpression ] + */ + private def sumExpression(): Tree = { + term(); + if ( token == ADD || token == SUB || token == OR ) { + sumOp(); + sumExpression(); + } + return null; + } + + /** + * Term = [ Term ProdOp ] [ NegateOp ] Factor + * MyTerm = [ NegateOp ] Factor [ ProdOp Term ] + */ + private def term(): Tree = { + if ( token == SUB || token == NOT ) { + nextToken; + } + factor(); + if ( token == MUL || token == DIV || token == MOD || token == AND ) { + prodOp(); + term(); + } + return null; + } + + /** + * Factor = look it up yourself! + */ + private def factor(): Tree = { + token match { + case IDENT => nextToken; + case NUMBER => nextToken; + case STRING => nextToken; + case TRUE => nextToken; + case FALSE => nextToken; + case THIS => nextToken; + case NULLFACTOR => nextToken; + case READINT => nextToken; + case READCHAR => nextToken; + case LPAREN => nextToken; expression(); accept(RPAREN); + case LACCOLADE => block(); + case NEW => nextToken; accept(IDENT); params(); + case _ => error("illegal start of expression"); + } + + if ( check(DOT) ) { + accept(IDENT); + if ( token == LPAREN ) { + params(); + } + } + + return null; + } + + /** + * Expressions = [ Expression { "," Expression } ] + */ + private def expressions(): Tree = { + if ( token == IF || token == SUB || token == NOT + || token == IDENT || token == NUMBER + || token == STRING || token == TRUE + || token == FALSE || token == THIS + || token == NULLFACTOR || token == READINT + || token == READCHAR || token == LPAREN + || token == NEW || token == LACCOLADE ) { + expression(); + while ( token == PERIOD ) { + expression(); + } + } + return null; + } + + /** + * Params = "(" Expressions ")" + */ + private def params(): Tree = { + accept(LPAREN); + expressions(); + accept(RPAREN); + return null; + } + + /** + * ProdOp = "*" | "/" | "%" | "&&" + */ + private def prodOp(): Tree = token match { + case MUL => nextToken; return null; + case DIV => nextToken; return null; + case MOD => nextToken; return null; + case AND => nextToken; return null; + case _ => error("illegal start of expression"); return null; + } + + /** + * NegateOp = "-" | "!" + */ + private def negateOp(): Tree = token match { + case SUB => nextToken; return null; + case NOT => nextToken; return null; + case _ => error("illegal start of expression"); return null; + } + + /** + * SumOp = "+" | "-" | "||" + */ + private def sumOp(): Tree = token match { + case ADD => nextToken; return null; + case SUB => nextToken; return null; + case OR => nextToken; return null; + case _ => error("illegal start of expression"); return null; + } + + + /** + * CompOp = "==" | "!" | "<" | ">" | "<=" | ">=" + */ + private def compOp(): Tree = token match { + case EQ => nextToken; return null; + case NE => nextToken; return null; + case LT => nextToken; return null; + case GT => nextToken; return null; + case LE => nextToken; return null; + case GE => nextToken; return null; + case _ => error("illegal start of expression"); return null; + } + +}