diff -r a751aa1ee4f7 -r 7545b1bc1514 Fahad/MCG-CS/Parser.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fahad/MCG-CS/Parser.cs Wed Nov 12 12:24:26 2014 +0000 @@ -0,0 +1,515 @@ +using System; +using System.Collections.Generic; +using System.Text; + +public sealed class Parser +{ + private int currentToken; + private readonly Statement parsingOutput; + private IList listTokens; + + + public Parser(IList tokens) + { + listTokens = tokens; + currentToken = 0; + parsingOutput = ParseStatement(); + + } + + public Statement GetParsedStatement + { + get { return parsingOutput; } + } + + public void ExceptionHandler(string strException) + { + throw new Exception(strException); + } + + private Statement ParseStatement() + { + Statement parsedStatement; + + if (currentToken == listTokens.Count) + { + ExceptionHandler("statement was expected before end of file"); + } + + if (listTokens[currentToken].Equals("print")) + { + currentToken++; + Write _Write = new Write(); + _Write.Expression = ParseExpression(); + parsedStatement = _Write; + } + + else if (listTokens[currentToken].Equals("var")) + { + currentToken++; + DeclareVariable _DeclareVariable = new DeclareVariable(); + + if (currentToken < listTokens.Count && listTokens[currentToken] is string) + { + _DeclareVariable.Identifier = (string)listTokens[currentToken]; + } + else + { + ExceptionHandler("variable name was expected after 'var'"); + } + + currentToken++; + + if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) + { + ExceptionHandler("= sign was expected after 'var identifier'"); + } + + currentToken++; + + _DeclareVariable.Expression = ParseExpression(); + parsedStatement = _DeclareVariable; + } + + else if (listTokens[currentToken].Equals("call")) + { + currentToken++; + CallFunction _CallFunction = new CallFunction(); + if (currentToken < listTokens.Count && listTokens[currentToken] is string) + { + _CallFunction.FunctionName = (string)listTokens[currentToken]; + } + else + { + ExceptionHandler("function name is expected after 'call'"); + } + currentToken++; + + _CallFunction.Parameter1 = ParseExpression(); + + //index++; + + if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Comma.ToString()) + { + ExceptionHandler("',' sign was expected after first parameter"); + } + + currentToken++; + + _CallFunction.Parameter2 = ParseExpression(); + + //index++; + + if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Comma.ToString()) + { + ExceptionHandler("',' sign was expected after second parameter"); + } + + currentToken++; + + _CallFunction.Parameter3 = ParseExpression(); + + //index++; + + if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Terminator.ToString()) + { + ExceptionHandler("';' sign was expected after third parameter"); + } + + parsedStatement = _CallFunction; + } + + else if (listTokens[currentToken].Equals("string") || listTokens[currentToken].Equals("numeric") || listTokens[currentToken].Equals("void")) + { + DeclareFunction _DeclareFunction = new DeclareFunction(); + _DeclareFunction.ReturnType = listTokens[currentToken].ToString(); + currentToken++; + + if (currentToken < listTokens.Count && listTokens[currentToken] is string) + { + _DeclareFunction.FunctionName = (string)listTokens[currentToken]; + } + else + { + ExceptionHandler("function name is expected after return type"); + } + + currentToken++; + + if (listTokens[currentToken].Equals("var")) + { + currentToken++; + DeclareVariable _DeclareVariable = new DeclareVariable(); + + if (currentToken < listTokens.Count && listTokens[currentToken] is string) + { + _DeclareVariable.Identifier = (string)listTokens[currentToken]; + } + else + { + ExceptionHandler("variable name was expected after 'var'"); + } + + currentToken++; + + if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) + { + ExceptionHandler("= sign was expected after 'var identifier'"); + } + + currentToken++; + + _DeclareVariable.Expression = ParseExpression(); + _DeclareFunction.Parameter1 = _DeclareVariable; + } + + currentToken++; + + if (listTokens[currentToken].Equals("var")) + { + currentToken++; + DeclareVariable _DeclareVariable = new DeclareVariable(); + + if (currentToken < listTokens.Count && listTokens[currentToken] is string) + { + _DeclareVariable.Identifier = (string)listTokens[currentToken]; + } + else + { + ExceptionHandler("variable name was expected after 'var'"); + } + + currentToken++; + + if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) + { + ExceptionHandler("= sign was expected after 'var identifier'"); + } + + currentToken++; + + _DeclareVariable.Expression = ParseExpression(); + + _DeclareFunction.Parameter2 = _DeclareVariable; + } + + currentToken++; + + if (listTokens[currentToken].Equals("var")) + { + currentToken++; + DeclareVariable _DeclareVariable = new DeclareVariable(); + + if (currentToken < listTokens.Count && listTokens[currentToken] is string) + { + _DeclareVariable.Identifier = (string)listTokens[currentToken]; + } + else + { + ExceptionHandler("variable name was expected after 'var'"); + } + + currentToken++; + + if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) + { + ExceptionHandler("= sign was expected after 'var identifier'"); + } + + currentToken++; + + _DeclareVariable.Expression = ParseExpression(); + + _DeclareFunction.Parameter3 = _DeclareVariable; + } + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("begin")) + { + ExceptionHandler("expected 'begin' after input parameters"); + } + + currentToken++; + _DeclareFunction.Body = ParseStatement(); + parsedStatement = _DeclareFunction; + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endfunc")) + { + ExceptionHandler("unterminated function', 'endfunc' expected at the end"); + } + + currentToken++; + } + + else if (listTokens[currentToken].Equals("read")) + { + currentToken++; + ReadInput _ReadInput = new ReadInput(); + + if (currentToken < listTokens.Count && listTokens[currentToken] is string) + { + _ReadInput.Identifier = (string)listTokens[currentToken++]; + parsedStatement = _ReadInput; + } + else + { + ExceptionHandler("variable name is expected after 'read'"); + parsedStatement = null; + } + } + + + // IfThenElse ifThenElse = new IfThenElse(); + + // RelationalExpression relExpr = new RelationalExpression(); + // relExpr.Left = ParseExpression(); + // if (listTokens[index] == Scanner.EqualTo) + // relExpr.Operand = RelationalOperands.EqualTo; + // else if (listTokens[index] == Scanner.LessThan) + // relExpr.Operand = RelationalOperands.LessThan; + // else if (listTokens[index] == Scanner.GreaterThan) + // relExpr.Operand = RelationalOperands.GreaterThan; + // else + // { + // ExceptionHandler("expected relational operand"); + // } + + // index++; + // relExpr.Right = ParseExpression(); + // ifThenElse.If = relExpr; + // index++; + // ifThenElse.Then = ParseStatement(); + + // parsedStatement = ifThenElse; + + // //index++; + + + + else if (listTokens[this.currentToken].Equals("while")) + { + currentToken++; + While _while = new While(); + + _while.LeftExpression = ParseExpression(); + + if (listTokens[currentToken].ToString() == Lexer.Tokens.EqualTo.ToString()) + _while.Operand = RelationalOperands.EqualTo; + else if (listTokens[currentToken].ToString() == Lexer.Tokens.LessThan.ToString()) + _while.Operand = RelationalOperands.LessThan; + else if (listTokens[currentToken].ToString() == Lexer.Tokens.GreaterThan.ToString()) + _while.Operand = RelationalOperands.GreaterThan; + currentToken++; + + _while.RightExpression = ParseExpression(); + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("do")) + { + ExceptionHandler("expected 'do' after while"); + } + currentToken++; + _while.Body = ParseStatement(); + parsedStatement = _while; + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endwhile")) + { + ExceptionHandler("unterminated 'while', endwhile expected at the end"); + } + + currentToken++; + } + + else if (listTokens[this.currentToken].Equals("if")) + { + currentToken++; + IfThen _IfThen = new IfThen(); + + _IfThen.LeftExpression = ParseExpression(); + + if (listTokens[currentToken].ToString() == Lexer.Tokens.EqualTo.ToString()) + _IfThen.Operand = RelationalOperands.EqualTo; + else if (listTokens[currentToken].ToString() == Lexer.Tokens.LessThan.ToString()) + _IfThen.Operand = RelationalOperands.LessThan; + else if (listTokens[currentToken].ToString() == Lexer.Tokens.GreaterThan.ToString()) + _IfThen.Operand = RelationalOperands.GreaterThan; + currentToken++; + + _IfThen.RightExpression = ParseExpression(); + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("then")) + { + ExceptionHandler("expected 'then' after if"); + } + currentToken++; + _IfThen.ThenBody = ParseStatement(); + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("else")) + { + ExceptionHandler("'else' is expected"); + } + currentToken++; + _IfThen.ElseBody = ParseStatement(); + + parsedStatement = _IfThen; + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endif")) + { + ExceptionHandler("unterminated 'if', endif expected at the end"); + } + + currentToken++; + } + + else if (listTokens[currentToken].Equals("for")) + { + currentToken++; + For _For = new For(); + + if (currentToken < listTokens.Count && listTokens[currentToken] is string) + { + _For.Identifier = (string)listTokens[currentToken]; + } + else + { + ExceptionHandler("expected identifier after 'for'"); + } + + currentToken++; + + if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) + { + ExceptionHandler("for missing '='"); + } + + currentToken++; + + _For.From = ParseExpression(); + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("to")) + { + ExceptionHandler("expected 'to' after for"); + } + + currentToken++; + + _For.To = ParseExpression(); + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("do")) + { + ExceptionHandler("expected 'do' after from expression in for loop"); + } + + currentToken++; + + _For.Body = ParseStatement(); + parsedStatement = _For; + + if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("end")) + { + ExceptionHandler("unterminated 'for' loop body"); + } + + currentToken++; + } + + else if (listTokens[currentToken] is string) + { + // assignment + + Assignment _Assignment = new Assignment(); + _Assignment.Identifier = (string)listTokens[currentToken++]; + + if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) + { + ExceptionHandler("expected '='"); + } + + currentToken++; + + _Assignment.Expression = ParseExpression(); + parsedStatement = _Assignment; + } + else + { + ExceptionHandler("parse error at token " + currentToken + ": " + listTokens[currentToken]); + parsedStatement = null; + } + + if (currentToken < listTokens.Count && listTokens[currentToken].ToString() == Lexer.Tokens.Terminator.ToString()) + { + currentToken++; + + if (currentToken < listTokens.Count && !listTokens[currentToken].Equals("end") + && !listTokens[currentToken].Equals("else") && !listTokens[currentToken].Equals("endif") + && !listTokens[currentToken].Equals("endwhile") && !listTokens[currentToken].Equals("endfunc")) + { + StatementSequence sequence = new StatementSequence(); + sequence.Left = parsedStatement; + sequence.Right = ParseStatement(); + parsedStatement = sequence; + } + } + + return parsedStatement; + } + + private Expression ParseExpression() + { + Expression parsedExpression; + + if (currentToken == listTokens.Count) + { + ExceptionHandler("expected expression, got EOF"); + } + + if (listTokens[currentToken] is StringBuilder) + { + string value = ((StringBuilder)listTokens[currentToken++]).ToString(); + AlphaNumericValue _AlphaNumericValue = new AlphaNumericValue(); + _AlphaNumericValue.Value = value; + parsedExpression = _AlphaNumericValue; + } + else if (listTokens[currentToken] is int) + { + int intValue = (int)listTokens[currentToken++]; + NumericValue _NumericValue = new NumericValue(); + _NumericValue.Value = intValue; + parsedExpression = _NumericValue; + } + else if (listTokens[currentToken] is string) + { + string identifier = (string)listTokens[currentToken++]; + Identifier _Identifier = new Identifier(); + _Identifier.IdentifierName = identifier; + parsedExpression = _Identifier; + } + else + { + ExceptionHandler("expected string literal, int literal, or variable"); + return null; + } + + //if (index < listTokens.Count && listTokens[index] != Scanner.Terminator && listTokens[index].GetType() != typeof(StringBuilder)) + if (listTokens[currentToken].ToString() != Lexer.Tokens.Terminator.ToString()) + { + if (listTokens[currentToken].ToString() == Lexer.Tokens.Add.ToString() || listTokens[currentToken].ToString() == Lexer.Tokens.Subtract.ToString() + || listTokens[currentToken].ToString() == Lexer.Tokens.Multiply.ToString() || listTokens[currentToken].ToString() == Lexer.Tokens.Divide.ToString()) + { + ArithmaticExpression arithmaticExpression = new ArithmaticExpression(); + arithmaticExpression.Left = parsedExpression; + if (listTokens[currentToken].ToString() == Lexer.Tokens.Add.ToString()) + arithmaticExpression.Operand = ArithmaticOperands.Add; + else if (listTokens[currentToken].ToString() == Lexer.Tokens.Subtract.ToString()) + arithmaticExpression.Operand = ArithmaticOperands.Subtract; + else if (listTokens[currentToken].ToString() == Lexer.Tokens.Multiply.ToString()) + arithmaticExpression.Operand = ArithmaticOperands.Multiply; + else if (listTokens[currentToken].ToString() == Lexer.Tokens.Divide.ToString()) + arithmaticExpression.Operand = ArithmaticOperands.Division; + currentToken++; + + arithmaticExpression.Right = ParseExpression(); + parsedExpression = arithmaticExpression; + } + } + return parsedExpression; + } +}