private Statement ParseStatement() { if (index == Tokens.Count) { throw new ParserException("Unexpected EOF - Expected Statement"); } Statement result; var currentToken = Tokens[index]; if (currentToken.Item1 == TokenType.Keyword && (Keywords)currentToken.Item2.Lexeme == Keywords.print) { // print statement index++; var endIndex = index; while (Tokens[endIndex].Item1 != TokenType.Semicolon) { endIndex++; } var print = new Print { Expr = ParseExpression(endIndex) }; result = print; } else if (currentToken.Item1 == TokenType.Keyword && (Keywords)currentToken.Item2.Lexeme == Keywords.var) { // variable declaration index++; var declareVar = new DeclareVariable(); if (index < Tokens.Count && Tokens[index].Item1 == TokenType.Identifier) { declareVar.Ident = (string)Tokens[index].Item2.Lexeme; } else { throw new ParserException("Expected variable name after 'var' keyword"); } index++; if (index == Tokens.Count || Tokens[index].Item1 != TokenType.EqualOp) { throw new ParserException("Expected assigning in variable declaration"); } index++; var endIndex = index; while (Tokens[endIndex].Item1 != TokenType.Semicolon) { endIndex++; } declareVar.Expr = ParseExpression(endIndex); result = declareVar; } else if (currentToken.Item1 == TokenType.Keyword && (Keywords)currentToken.Item2.Lexeme == Keywords.read_integer) { // read_integer statement index++; var readInt = new ReadInteger(); if (index < Tokens.Count && Tokens[index].Item1 == TokenType.Identifier) { readInt.Ident = (string)Tokens[index++].Item2.Lexeme; result = readInt; } else { throw new ParserException("Expected variable name after 'read_integer' expression"); } } else if (currentToken.Item1 == TokenType.Keyword && (Keywords)currentToken.Item2.Lexeme == Keywords.@for) { // for-loop statement index++; var forLoop = new ForLoop(); if (index < Tokens.Count && Tokens[index].Item1 == TokenType.Identifier) { forLoop.Ident = (string)Tokens[index].Item2.Lexeme; } else { throw new ParserException("Expected loop counter-variable after 'for'"); } index++; if (index == Tokens.Count || Tokens[index].Item1 != TokenType.EqualOp) { throw new ParserException("Missing '=' in for loop"); } index++; forLoop.From = ParseExpression(); if (index == Tokens.Count || (Tokens[index].Item1 != TokenType.Keyword || (Tokens[index].Item1 == TokenType.Keyword && (Keywords) Tokens[index].Item2.Lexeme != Keywords.to))) { throw new ParserException("Expected 'to' keyword in for-loop statement"); } index++; forLoop.To = ParseExpression(); if (index == Tokens.Count || (Tokens[index].Item1 != TokenType.Keyword || (Tokens[index].Item1 == TokenType.Keyword && (Keywords) Tokens[index].Item2.Lexeme != Keywords.@do))) { throw new ParserException("Expected 'do' keyword in for-loop statement"); } index++; forLoop.Body = ParseStatement(); result = forLoop; if (index == Tokens.Count || (Tokens[index].Item1 != TokenType.Keyword || (Tokens[index].Item1 == TokenType.Keyword && (Keywords) Tokens[index].Item2.Lexeme != Keywords.end))) { throw new ParserException("Unterminated for-loop body"); } index++; } else if (Tokens[index].Item1 == TokenType.Identifier) { // variable assigning statement var assignStatement = new Assign { Ident = (string)Tokens[index++].Item2.Lexeme }; if (index == Tokens.Count || Tokens[index].Item1 != TokenType.EqualOp) { throw new ParserException("Expected '=' operator"); } index++; var endIndex = index; while (Tokens[endIndex].Item1 != TokenType.Semicolon) { endIndex++; } assignStatement.Expr = ParseExpression(endIndex); result = assignStatement; } else { // unknown statement throw new ParserException("Parse error at token " + index + ": " + Tokens[index]); } if (index < Tokens.Count && Tokens[index].Item1 == TokenType.Semicolon) { index++; if (index < Tokens.Count) { if (Tokens[index].Item1 != TokenType.Keyword || (Tokens[index].Item1 == TokenType.Keyword && (Keywords) Tokens[index].Item2.Lexeme != Keywords.end)) { var sequenceStatement = new StatementList {First = result, Second = ParseStatement()}; result = sequenceStatement; } } } return result; }
private Statement ParseStatement() { if (index == Tokens.Count) { throw new ParserException("Unexpected EOF - Expected Statement"); } Statement result; var currentToken = Tokens[index]; if (currentToken.Item1 == TokenType.Keyword && (Keywords)currentToken.Item2.Lexeme == Keywords.print) { // print statement index++; var endIndex = index; while (Tokens[endIndex].Item1 != TokenType.Semicolon) { endIndex++; } var print = new Print { Expr = ParseExpression(endIndex) }; result = print; } else if (currentToken.Item1 == TokenType.Keyword && (Keywords)currentToken.Item2.Lexeme == Keywords.var) { // variable declaration index++; var declareVar = new DeclareVariable(); if (index < Tokens.Count && Tokens[index].Item1 == TokenType.Identifier) { declareVar.Ident = (string)Tokens[index].Item2.Lexeme; } else { throw new ParserException("Expected variable name after 'var' keyword"); } index++; if (index == Tokens.Count || Tokens[index].Item1 != TokenType.EqualOp) { throw new ParserException("Expected assigning in variable declaration"); } index++; var endIndex = index; while (Tokens[endIndex].Item1 != TokenType.Semicolon) { endIndex++; } declareVar.Expr = ParseExpression(endIndex); result = declareVar; } else if (currentToken.Item1 == TokenType.Keyword && (Keywords)currentToken.Item2.Lexeme == Keywords.read_integer) { // read_integer statement index++; var readInt = new ReadInteger(); if (index < Tokens.Count && Tokens[index].Item1 == TokenType.Identifier) { readInt.Ident = (string)Tokens[index++].Item2.Lexeme; result = readInt; } else { throw new ParserException("Expected variable name after 'read_integer' expression"); } } else if (currentToken.Item1 == TokenType.Keyword && (Keywords)currentToken.Item2.Lexeme == Keywords.@for) { // for-loop statement index++; var forLoop = new ForLoop(); if (index < Tokens.Count && Tokens[index].Item1 == TokenType.Identifier) { forLoop.Ident = (string)Tokens[index].Item2.Lexeme; } else { throw new ParserException("Expected loop counter-variable after 'for'"); } index++; if (index == Tokens.Count || Tokens[index].Item1 != TokenType.EqualOp) { throw new ParserException("Missing '=' in for loop"); } index++; forLoop.From = ParseExpression(); if (index == Tokens.Count || (Tokens[index].Item1 != TokenType.Keyword || (Tokens[index].Item1 == TokenType.Keyword && (Keywords)Tokens[index].Item2.Lexeme != Keywords.to))) { throw new ParserException("Expected 'to' keyword in for-loop statement"); } index++; forLoop.To = ParseExpression(); if (index == Tokens.Count || (Tokens[index].Item1 != TokenType.Keyword || (Tokens[index].Item1 == TokenType.Keyword && (Keywords)Tokens[index].Item2.Lexeme != Keywords.@do))) { throw new ParserException("Expected 'do' keyword in for-loop statement"); } index++; forLoop.Body = ParseStatement(); result = forLoop; if (index == Tokens.Count || (Tokens[index].Item1 != TokenType.Keyword || (Tokens[index].Item1 == TokenType.Keyword && (Keywords)Tokens[index].Item2.Lexeme != Keywords.end))) { throw new ParserException("Unterminated for-loop body"); } index++; } else if (Tokens[index].Item1 == TokenType.Identifier) { // variable assigning statement var assignStatement = new Assign { Ident = (string)Tokens[index++].Item2.Lexeme }; if (index == Tokens.Count || Tokens[index].Item1 != TokenType.EqualOp) { throw new ParserException("Expected '=' operator"); } index++; var endIndex = index; while (Tokens[endIndex].Item1 != TokenType.Semicolon) { endIndex++; } assignStatement.Expr = ParseExpression(endIndex); result = assignStatement; } else { // unknown statement throw new ParserException("Parse error at token " + index + ": " + Tokens[index]); } if (index < Tokens.Count && Tokens[index].Item1 == TokenType.Semicolon) { index++; if (index < Tokens.Count) { if (Tokens[index].Item1 != TokenType.Keyword || (Tokens[index].Item1 == TokenType.Keyword && (Keywords)Tokens[index].Item2.Lexeme != Keywords.end)) { var sequenceStatement = new StatementList { First = result, Second = ParseStatement() }; result = sequenceStatement; } } } return(result); }