diff --git a/sources/zweic/Parser.scala b/sources/zweic/Parser.scala
new file mode 100755
index 0000000..d0c1157
--- /dev/null
+++ b/sources/zweic/Parser.scala
@@ -0,0 +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;
+  }
+
+}