Fahad/MCG-CS/Parser.cs
changeset 45 7545b1bc1514
--- /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<object> listTokens;
+
+
+    public Parser(IList<object> 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;
+    }
+}