Fahad/MCG-CS/Parser.cs
changeset 45 7545b1bc1514
equal deleted inserted replaced
44:a751aa1ee4f7 45:7545b1bc1514
       
     1 using System;
       
     2 using System.Collections.Generic;
       
     3 using System.Text;
       
     4 
       
     5 public sealed class Parser
       
     6 {
       
     7     private int currentToken;    
       
     8     private readonly Statement parsingOutput;
       
     9     private IList<object> listTokens;
       
    10 
       
    11 
       
    12     public Parser(IList<object> tokens)
       
    13     {
       
    14         listTokens = tokens;
       
    15         currentToken = 0;
       
    16         parsingOutput = ParseStatement();
       
    17 
       
    18     }
       
    19 
       
    20     public Statement GetParsedStatement
       
    21     {
       
    22         get { return parsingOutput; }
       
    23     }
       
    24 
       
    25     public void ExceptionHandler(string strException)
       
    26     {
       
    27         throw new Exception(strException);
       
    28     }
       
    29     
       
    30     private Statement ParseStatement()
       
    31     {
       
    32         Statement parsedStatement;
       
    33 
       
    34         if (currentToken == listTokens.Count)
       
    35         {
       
    36             ExceptionHandler("statement was expected before end of file");
       
    37         }
       
    38 
       
    39         if (listTokens[currentToken].Equals("print"))
       
    40         {
       
    41             currentToken++;
       
    42             Write _Write = new Write();
       
    43             _Write.Expression = ParseExpression();
       
    44             parsedStatement = _Write;
       
    45         }
       
    46 
       
    47         else if (listTokens[currentToken].Equals("var"))
       
    48         {
       
    49             currentToken++;
       
    50             DeclareVariable _DeclareVariable = new DeclareVariable();
       
    51 
       
    52             if (currentToken < listTokens.Count && listTokens[currentToken] is string)
       
    53             {
       
    54                 _DeclareVariable.Identifier = (string)listTokens[currentToken];
       
    55             }
       
    56             else
       
    57             {
       
    58                 ExceptionHandler("variable name was expected after 'var'");
       
    59             }
       
    60 
       
    61             currentToken++;
       
    62 
       
    63             if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
       
    64             {
       
    65                 ExceptionHandler("= sign was expected after 'var identifier'");
       
    66             }
       
    67 
       
    68             currentToken++;
       
    69 
       
    70             _DeclareVariable.Expression = ParseExpression();
       
    71             parsedStatement = _DeclareVariable;
       
    72         }
       
    73 
       
    74         else if (listTokens[currentToken].Equals("call"))
       
    75         {
       
    76             currentToken++;
       
    77             CallFunction _CallFunction = new CallFunction();
       
    78             if (currentToken < listTokens.Count && listTokens[currentToken] is string)
       
    79             {
       
    80                 _CallFunction.FunctionName = (string)listTokens[currentToken];
       
    81             }
       
    82             else
       
    83             {
       
    84                 ExceptionHandler("function name is expected after 'call'");
       
    85             }
       
    86             currentToken++;
       
    87 
       
    88             _CallFunction.Parameter1 = ParseExpression();
       
    89 
       
    90             //index++;
       
    91 
       
    92             if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Comma.ToString())
       
    93             {
       
    94                 ExceptionHandler("',' sign was expected after first parameter");
       
    95             }
       
    96 
       
    97             currentToken++;
       
    98 
       
    99             _CallFunction.Parameter2 = ParseExpression();
       
   100 
       
   101             //index++;
       
   102 
       
   103             if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Comma.ToString())
       
   104             {
       
   105                 ExceptionHandler("',' sign was expected after second parameter");
       
   106             }
       
   107 
       
   108             currentToken++;
       
   109 
       
   110             _CallFunction.Parameter3 = ParseExpression();
       
   111 
       
   112             //index++;
       
   113 
       
   114             if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Terminator.ToString())
       
   115             {
       
   116                 ExceptionHandler("';' sign was expected after third parameter");
       
   117             }
       
   118 
       
   119             parsedStatement = _CallFunction;
       
   120         }
       
   121 
       
   122         else if (listTokens[currentToken].Equals("string") || listTokens[currentToken].Equals("numeric") || listTokens[currentToken].Equals("void"))
       
   123         {            
       
   124             DeclareFunction _DeclareFunction = new DeclareFunction();
       
   125             _DeclareFunction.ReturnType = listTokens[currentToken].ToString();
       
   126             currentToken++;
       
   127 
       
   128             if (currentToken < listTokens.Count && listTokens[currentToken] is string)
       
   129             {
       
   130                 _DeclareFunction.FunctionName = (string)listTokens[currentToken];
       
   131             }
       
   132             else
       
   133             {
       
   134                 ExceptionHandler("function name is expected after return type");
       
   135             }
       
   136 
       
   137             currentToken++;
       
   138 
       
   139             if (listTokens[currentToken].Equals("var"))
       
   140             {
       
   141                 currentToken++;
       
   142                 DeclareVariable _DeclareVariable = new DeclareVariable();
       
   143 
       
   144                 if (currentToken < listTokens.Count && listTokens[currentToken] is string)
       
   145                 {
       
   146                     _DeclareVariable.Identifier = (string)listTokens[currentToken];
       
   147                 }
       
   148                 else
       
   149                 {
       
   150                     ExceptionHandler("variable name was expected after 'var'");
       
   151                 }
       
   152 
       
   153                 currentToken++;
       
   154 
       
   155                 if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
       
   156                 {
       
   157                     ExceptionHandler("= sign was expected after 'var identifier'");
       
   158                 }
       
   159 
       
   160                 currentToken++;
       
   161 
       
   162                 _DeclareVariable.Expression = ParseExpression();
       
   163                 _DeclareFunction.Parameter1 = _DeclareVariable;
       
   164             }
       
   165 
       
   166             currentToken++;
       
   167 
       
   168             if (listTokens[currentToken].Equals("var"))
       
   169             {
       
   170                 currentToken++;
       
   171                 DeclareVariable _DeclareVariable = new DeclareVariable();
       
   172 
       
   173                 if (currentToken < listTokens.Count && listTokens[currentToken] is string)
       
   174                 {
       
   175                     _DeclareVariable.Identifier = (string)listTokens[currentToken];
       
   176                 }
       
   177                 else
       
   178                 {
       
   179                     ExceptionHandler("variable name was expected after 'var'");
       
   180                 }
       
   181 
       
   182                 currentToken++;
       
   183 
       
   184                 if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
       
   185                 {
       
   186                     ExceptionHandler("= sign was expected after 'var identifier'");
       
   187                 }
       
   188 
       
   189                 currentToken++;
       
   190 
       
   191                 _DeclareVariable.Expression = ParseExpression();
       
   192 
       
   193                 _DeclareFunction.Parameter2 = _DeclareVariable;
       
   194             }
       
   195 
       
   196             currentToken++;
       
   197 
       
   198             if (listTokens[currentToken].Equals("var"))
       
   199             {
       
   200                 currentToken++;
       
   201                 DeclareVariable _DeclareVariable = new DeclareVariable();
       
   202 
       
   203                 if (currentToken < listTokens.Count && listTokens[currentToken] is string)
       
   204                 {
       
   205                     _DeclareVariable.Identifier = (string)listTokens[currentToken];
       
   206                 }
       
   207                 else
       
   208                 {
       
   209                     ExceptionHandler("variable name was expected after 'var'");
       
   210                 }
       
   211 
       
   212                 currentToken++;
       
   213 
       
   214                 if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
       
   215                 {
       
   216                     ExceptionHandler("= sign was expected after 'var identifier'");
       
   217                 }
       
   218 
       
   219                 currentToken++;
       
   220 
       
   221                 _DeclareVariable.Expression = ParseExpression();
       
   222 
       
   223                 _DeclareFunction.Parameter3 = _DeclareVariable;
       
   224             }
       
   225 
       
   226             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("begin"))
       
   227             {
       
   228                 ExceptionHandler("expected 'begin' after input parameters");
       
   229             }
       
   230 
       
   231             currentToken++;
       
   232             _DeclareFunction.Body = ParseStatement();
       
   233             parsedStatement = _DeclareFunction;
       
   234             
       
   235             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endfunc"))
       
   236             {
       
   237                 ExceptionHandler("unterminated function', 'endfunc' expected at the end");
       
   238             }
       
   239 
       
   240             currentToken++;
       
   241         }
       
   242 
       
   243         else if (listTokens[currentToken].Equals("read"))
       
   244         {
       
   245             currentToken++;
       
   246             ReadInput _ReadInput = new ReadInput();
       
   247 
       
   248             if (currentToken < listTokens.Count && listTokens[currentToken] is string)
       
   249             {
       
   250                 _ReadInput.Identifier = (string)listTokens[currentToken++];
       
   251                 parsedStatement = _ReadInput;
       
   252             }
       
   253             else
       
   254             {
       
   255                 ExceptionHandler("variable name is expected after 'read'");
       
   256                 parsedStatement = null;
       
   257             }
       
   258         }
       
   259 
       
   260 
       
   261         //    IfThenElse ifThenElse = new IfThenElse();
       
   262 
       
   263         //    RelationalExpression relExpr = new RelationalExpression();
       
   264         //    relExpr.Left = ParseExpression();
       
   265         //    if (listTokens[index] == Scanner.EqualTo)
       
   266         //        relExpr.Operand = RelationalOperands.EqualTo;
       
   267         //    else if (listTokens[index] == Scanner.LessThan)
       
   268         //        relExpr.Operand = RelationalOperands.LessThan;
       
   269         //    else if (listTokens[index] == Scanner.GreaterThan)
       
   270         //        relExpr.Operand = RelationalOperands.GreaterThan;
       
   271         //    else
       
   272         //    {
       
   273         //        ExceptionHandler("expected relational operand");
       
   274         //    }
       
   275 
       
   276         //    index++;
       
   277         //    relExpr.Right = ParseExpression();
       
   278         //    ifThenElse.If = relExpr;
       
   279         //    index++;
       
   280         //    ifThenElse.Then = ParseStatement();
       
   281 
       
   282         //    parsedStatement = ifThenElse;
       
   283 
       
   284         //    //index++;
       
   285 
       
   286 
       
   287 
       
   288         else if (listTokens[this.currentToken].Equals("while"))
       
   289         {
       
   290             currentToken++;
       
   291             While _while = new While();
       
   292 
       
   293             _while.LeftExpression = ParseExpression();
       
   294 
       
   295             if (listTokens[currentToken].ToString() == Lexer.Tokens.EqualTo.ToString())
       
   296                 _while.Operand = RelationalOperands.EqualTo;
       
   297             else if (listTokens[currentToken].ToString() == Lexer.Tokens.LessThan.ToString())
       
   298                 _while.Operand = RelationalOperands.LessThan;
       
   299             else if (listTokens[currentToken].ToString() == Lexer.Tokens.GreaterThan.ToString())
       
   300                 _while.Operand = RelationalOperands.GreaterThan;
       
   301             currentToken++;
       
   302 
       
   303             _while.RightExpression = ParseExpression();
       
   304 
       
   305             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("do"))
       
   306             {
       
   307                 ExceptionHandler("expected 'do' after while");
       
   308             }
       
   309             currentToken++;
       
   310             _while.Body = ParseStatement();
       
   311             parsedStatement = _while;
       
   312 
       
   313             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endwhile"))
       
   314             {
       
   315                 ExceptionHandler("unterminated 'while', endwhile expected at the end");
       
   316             }
       
   317 
       
   318             currentToken++;
       
   319         }
       
   320 
       
   321         else if (listTokens[this.currentToken].Equals("if"))
       
   322         {
       
   323             currentToken++;
       
   324             IfThen _IfThen = new IfThen();
       
   325 
       
   326             _IfThen.LeftExpression = ParseExpression();
       
   327 
       
   328             if (listTokens[currentToken].ToString() == Lexer.Tokens.EqualTo.ToString())
       
   329                 _IfThen.Operand = RelationalOperands.EqualTo;
       
   330             else if (listTokens[currentToken].ToString() == Lexer.Tokens.LessThan.ToString())
       
   331                 _IfThen.Operand = RelationalOperands.LessThan;
       
   332             else if (listTokens[currentToken].ToString() == Lexer.Tokens.GreaterThan.ToString())
       
   333                 _IfThen.Operand = RelationalOperands.GreaterThan;
       
   334             currentToken++;
       
   335 
       
   336             _IfThen.RightExpression = ParseExpression();
       
   337 
       
   338             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("then"))
       
   339             {
       
   340                 ExceptionHandler("expected 'then' after if");
       
   341             }
       
   342             currentToken++;
       
   343             _IfThen.ThenBody = ParseStatement();
       
   344 
       
   345             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("else"))
       
   346             {
       
   347                 ExceptionHandler("'else' is expected");
       
   348             }
       
   349             currentToken++;
       
   350             _IfThen.ElseBody = ParseStatement();
       
   351 
       
   352             parsedStatement = _IfThen;
       
   353 
       
   354             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endif"))
       
   355             {
       
   356                 ExceptionHandler("unterminated 'if', endif expected at the end");
       
   357             }
       
   358 
       
   359             currentToken++;
       
   360         }
       
   361 
       
   362         else if (listTokens[currentToken].Equals("for"))
       
   363         {
       
   364             currentToken++;
       
   365             For _For = new For();
       
   366 
       
   367             if (currentToken < listTokens.Count && listTokens[currentToken] is string)
       
   368             {
       
   369                 _For.Identifier = (string)listTokens[currentToken];
       
   370             }
       
   371             else
       
   372             {
       
   373                 ExceptionHandler("expected identifier after 'for'");
       
   374             }
       
   375 
       
   376             currentToken++;
       
   377 
       
   378             if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
       
   379             {
       
   380                 ExceptionHandler("for missing '='");
       
   381             }
       
   382 
       
   383             currentToken++;
       
   384 
       
   385             _For.From = ParseExpression();
       
   386 
       
   387             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("to"))
       
   388             {
       
   389                 ExceptionHandler("expected 'to' after for");
       
   390             }
       
   391 
       
   392             currentToken++;
       
   393 
       
   394             _For.To = ParseExpression();
       
   395 
       
   396             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("do"))
       
   397             {
       
   398                 ExceptionHandler("expected 'do' after from expression in for loop");
       
   399             }
       
   400 
       
   401             currentToken++;
       
   402 
       
   403             _For.Body = ParseStatement();
       
   404             parsedStatement = _For;
       
   405 
       
   406             if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("end"))
       
   407             {
       
   408                 ExceptionHandler("unterminated 'for' loop body");
       
   409             }
       
   410 
       
   411             currentToken++;
       
   412         }
       
   413 
       
   414         else if (listTokens[currentToken] is string)
       
   415         {
       
   416             // assignment
       
   417 
       
   418             Assignment _Assignment = new Assignment();
       
   419             _Assignment.Identifier = (string)listTokens[currentToken++];
       
   420 
       
   421             if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
       
   422             {
       
   423                 ExceptionHandler("expected '='");
       
   424             }
       
   425 
       
   426             currentToken++;
       
   427 
       
   428             _Assignment.Expression = ParseExpression();
       
   429             parsedStatement = _Assignment;
       
   430         }
       
   431         else
       
   432         {
       
   433             ExceptionHandler("parse error at token " + currentToken + ": " + listTokens[currentToken]);
       
   434             parsedStatement = null;
       
   435         }
       
   436 
       
   437         if (currentToken < listTokens.Count && listTokens[currentToken].ToString() == Lexer.Tokens.Terminator.ToString())
       
   438         {
       
   439             currentToken++;
       
   440 
       
   441             if (currentToken < listTokens.Count && !listTokens[currentToken].Equals("end") 
       
   442                 && !listTokens[currentToken].Equals("else") && !listTokens[currentToken].Equals("endif")
       
   443                 && !listTokens[currentToken].Equals("endwhile") && !listTokens[currentToken].Equals("endfunc"))
       
   444             {
       
   445                 StatementSequence sequence = new StatementSequence();
       
   446                 sequence.Left = parsedStatement;
       
   447                 sequence.Right = ParseStatement();
       
   448                 parsedStatement = sequence;
       
   449             }
       
   450         }
       
   451 
       
   452         return parsedStatement;
       
   453     }
       
   454 
       
   455     private Expression ParseExpression()
       
   456     {
       
   457         Expression parsedExpression;
       
   458 
       
   459         if (currentToken == listTokens.Count)
       
   460         {
       
   461             ExceptionHandler("expected expression, got EOF");
       
   462         }
       
   463 
       
   464         if (listTokens[currentToken] is StringBuilder)
       
   465         {
       
   466             string value = ((StringBuilder)listTokens[currentToken++]).ToString();
       
   467             AlphaNumericValue _AlphaNumericValue = new AlphaNumericValue();
       
   468             _AlphaNumericValue.Value = value;
       
   469             parsedExpression = _AlphaNumericValue;
       
   470         }
       
   471         else if (listTokens[currentToken] is int)
       
   472         {
       
   473             int intValue = (int)listTokens[currentToken++];
       
   474             NumericValue _NumericValue = new NumericValue();
       
   475             _NumericValue.Value = intValue;
       
   476             parsedExpression = _NumericValue;
       
   477         }
       
   478         else if (listTokens[currentToken] is string)
       
   479         {
       
   480             string identifier = (string)listTokens[currentToken++];
       
   481             Identifier _Identifier = new Identifier();
       
   482             _Identifier.IdentifierName = identifier;
       
   483             parsedExpression = _Identifier;
       
   484         }
       
   485         else
       
   486         {
       
   487             ExceptionHandler("expected string literal, int literal, or variable");
       
   488             return null;
       
   489         }
       
   490 
       
   491         //if (index < listTokens.Count && listTokens[index] != Scanner.Terminator && listTokens[index].GetType() != typeof(StringBuilder))
       
   492         if (listTokens[currentToken].ToString() != Lexer.Tokens.Terminator.ToString())
       
   493         {
       
   494             if (listTokens[currentToken].ToString() == Lexer.Tokens.Add.ToString() || listTokens[currentToken].ToString() == Lexer.Tokens.Subtract.ToString()
       
   495                 || listTokens[currentToken].ToString() == Lexer.Tokens.Multiply.ToString() || listTokens[currentToken].ToString() == Lexer.Tokens.Divide.ToString())
       
   496             {
       
   497                 ArithmaticExpression arithmaticExpression = new ArithmaticExpression();
       
   498                 arithmaticExpression.Left = parsedExpression;
       
   499                 if (listTokens[currentToken].ToString() == Lexer.Tokens.Add.ToString())
       
   500                     arithmaticExpression.Operand = ArithmaticOperands.Add;
       
   501                 else if (listTokens[currentToken].ToString() == Lexer.Tokens.Subtract.ToString())
       
   502                     arithmaticExpression.Operand = ArithmaticOperands.Subtract;
       
   503                 else if (listTokens[currentToken].ToString() == Lexer.Tokens.Multiply.ToString())
       
   504                     arithmaticExpression.Operand = ArithmaticOperands.Multiply;
       
   505                 else if (listTokens[currentToken].ToString() == Lexer.Tokens.Divide.ToString())
       
   506                     arithmaticExpression.Operand = ArithmaticOperands.Division;
       
   507                 currentToken++;
       
   508 
       
   509                 arithmaticExpression.Right = ParseExpression();
       
   510                 parsedExpression = arithmaticExpression;
       
   511             }
       
   512         }
       
   513         return parsedExpression;
       
   514     }
       
   515 }