private Stmt ParseStmt() { Stmt result; if (this.index == this.tokens.Count) { throw new System.Exception("expected statement, got EOF"); } // <stmt> := print <expr> // <expr> := <string> // | <int> // | <arith_expr> // | <ident> if (this.tokens[this.index].Equals("print")) { this.index++; Print print = new Print(); //Если есть текстовое описание if (this.index < this.tokens.Count && this.tokens[this.index] is Text.StringBuilder) { print.Expression = this.ParseExpr(); } if (this.index < this.tokens.Count && this.tokens[this.index] is string) { print.VarExpression = this.ParseExpr(); } result = print; } else if (this.tokens[this.index].Equals("var")) { this.index++; DeclareVar declareVar = new DeclareVar(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { declareVar.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected variable name after 'var'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected = after 'var ident'"); } this.index++; declareVar.Expression = this.ParseExpr(); result = declareVar; } else if (this.tokens[this.index].Equals("input")) { this.index++; ReadValue readValue = new ReadValue(); //Если есть текстовое описание if (this.index < this.tokens.Count && this.tokens[this.index] is Text.StringBuilder) { readValue.Exp = this.ParseExpr(); } if (this.index < this.tokens.Count && this.tokens[this.index] is string) { readValue.Ident = (string)this.tokens[this.index++]; result = readValue; } else { throw new System.Exception("expected variable name after 'input'"); } } /*else if (this.tokens[this.index].Equals("read_int")) * { * this.index++; * ReadValue readValue = new ReadValue(); * * if (this.index < this.tokens.Count && * this.tokens[this.index] is string) * { * readValue.Ident = (string)this.tokens[this.index++]; * result = readValue; * } * else * { * throw new System.Exception("expected variable name after 'read_int'"); * } * }*/ else if (this.tokens[this.index].Equals("for")) { this.index++; ForNext forNext = new ForNext(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { forNext.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected identifier after 'for'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("for missing '='"); } this.index++; forNext.From = this.ParseExpr(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("to")) { throw new System.Exception("expected 'to' after for"); } this.index++; forNext.To = this.ParseExpr(); /*if (this.index == this.tokens.Count || * !this.tokens[this.index].Equals("do")) * { * throw new System.Exception("expected 'do' after from expression in for next"); * }*/ this.index++; forNext.Body = this.ParseStmt(); result = forNext; if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("next")) { throw new System.Exception("unterminated 'for' loop body"); } this.index++; } else if (this.tokens[this.index].Equals("if")) { this.index++; IfElse ifthen = new IfElse(); ifthen.Condition = new ConExpression(); //Запишем первый операнд в условии if (this.index < this.tokens.Count && this.tokens[this.index] is string) { ifthen.Condition.Left = this.ParseExpr(); } else { throw new System.Exception("expected identifier after 'if'"); } // Запишем условный оператор if (this.tokens[this.index] == Scanner.More) //Больше { ifthen.Condition.Operation = ConOperation.More; } else if (this.tokens[this.index] == Scanner.MoreEqual) //Больше-равно { ifthen.Condition.Operation = ConOperation.MoreEqual; } else if (this.tokens[this.index] == Scanner.Less) //Меньше { ifthen.Condition.Operation = ConOperation.Less; } else if (this.tokens[this.index] == Scanner.LessEqual) //Меньше-равно { ifthen.Condition.Operation = ConOperation.LessEqual; } else if (this.tokens[this.index] == Scanner.Equal) //Равенство { ifthen.Condition.Operation = ConOperation.Equal; } else { throw new System.Exception("missing condition operator"); } //Запишем второй операнд в условии this.index++; ifthen.Condition.Right = this.ParseExpr(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("then")) { throw new System.Exception("expected 'then' after if"); } this.index++; ifthen.BodyThen = this.ParseStmt(); if (this.index < this.tokens.Count && this.tokens[this.index].Equals("else")) { this.index++; ifthen.BodyElse = this.ParseStmt(); } result = ifthen; if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("endif")) { throw new System.Exception("unterminated 'if' body"); } this.index++; } else if (this.tokens[this.index] is string) { //--------------------------------------------------------- // assignment Assign assign = new Assign(); assign.Ident = (string)this.tokens[this.index++]; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected '='"); } this.index++; assign.Expression = this.ParseExpr(); //Проверим наличие операции if (this.tokens[this.index] != Scanner.Semi) { assign.Expression = this.ParseBinExpr(assign.Expression); } result = assign; } else { throw new System.Exception("parse error at token " + this.index + ": " + this.tokens[this.index]); } if (this.index < this.tokens.Count && this.tokens[this.index] == Scanner.Semi) { this.index++; if (this.index < this.tokens.Count && !this.tokens[this.index].Equals("next") && !this.tokens[this.index].Equals("endif") && !this.tokens[this.index].Equals("else")) { Sequence sequence = new Sequence(); sequence.First = result; sequence.Second = this.ParseStmt(); result = sequence; } } return(result); }
private void GenStmt(Stmt stmt) { if (stmt is Sequence) { Sequence seq = (Sequence)stmt; this.GenStmt(seq.First); this.GenStmt(seq.Second); } else if (stmt is DeclareVar) { // declare a local DeclareVar declare = (DeclareVar)stmt; this.symbolTable[declare.Ident] = this.il.DeclareLocal(this.TypeOfExpr(declare.Expr)); // set the initial value Assign assign = new Assign(); assign.Ident = declare.Ident; assign.Expr = declare.Expr; this.GenStmt(assign); } else if (stmt is Assign) { Assign assign = (Assign)stmt; this.GenExpr(assign.Expr, this.TypeOfExpr(assign.Expr)); this.Store(assign.Ident, this.TypeOfExpr(assign.Expr)); } else if (stmt is Print) { // the "print" statement is an alias for System.Console.WriteLine. // it uses the string case this.GenExpr(((Print)stmt).Expr, typeof(string)); this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); } else if (stmt is ReadInt) { this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { }, null)); this.il.Emit(Emit.OpCodes.Call, typeof(int).GetMethod("Parse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { typeof(string) }, null)); this.Store(((ReadInt)stmt).Ident, typeof(int)); } //******************* else if (stmt is mcIf) { mcIf mcif = (mcIf)stmt; //this.GenExpr(mcif.compExpr, typeof(int)); Emit.Label Else = this.il.DefineLabel(); Emit.Label Then = this.il.DefineLabel(); Emit.Label Salida = this.il.DefineLabel(); if (mcif.compExpr is CompExpr) { CompExpr compExpr = (CompExpr)mcif.compExpr; this.GenExpr(compExpr.Left, typeof(int)); this.GenExpr(compExpr.Rigth, typeof(int)); genCodComp(compExpr.Op, Then); } else { GenExpr(mcif.compExpr, typeof(string)); this.il.Emit(Emit.OpCodes.Ldc_I4, 0); this.il.Emit(Emit.OpCodes.Bne_Un, Then); } if (mcif.Else != null) { this.il.Emit(Emit.OpCodes.Br, Else); } else { this.il.Emit(Emit.OpCodes.Br, Salida); } this.il.MarkLabel(Then); GenStmt(mcif.Then); this.il.Emit(Emit.OpCodes.Br, Salida); this.il.MarkLabel(Else); if (mcif.Else != null) { GenStmt(mcif.Else); } this.il.MarkLabel(Salida); } else if (stmt is WhileLoop) { WhileLoop whileLoop = (WhileLoop)stmt; Emit.Label Body = this.il.DefineLabel(); Emit.Label Salida = this.il.DefineLabel(); Emit.Label Cond = this.il.DefineLabel(); this.il.MarkLabel(Cond); if (whileLoop.Cond is CompExpr) { CompExpr compExpr = (CompExpr)whileLoop.Cond; this.GenExpr(compExpr.Left, typeof(int)); this.GenExpr(compExpr.Rigth, typeof(int)); genCodComp(compExpr.Op, Body); } else { GenExpr(whileLoop.Cond, typeof(string)); this.il.Emit(Emit.OpCodes.Ldc_I4, 0); this.il.Emit(Emit.OpCodes.Bne_Un, Body); } this.il.Emit(Emit.OpCodes.Br, Salida); this.il.MarkLabel(Body); GenStmt(whileLoop.Body); this.il.Emit(Emit.OpCodes.Br, Cond); this.il.MarkLabel(Salida); } //******************* else if (stmt is ForLoop) { // example: // for x = 0 to 100 do // print "hello"; // end; // x = 0 ForLoop forLoop = (ForLoop)stmt; Assign assign = new Assign(); assign.Ident = forLoop.Ident; assign.Expr = forLoop.From; this.GenStmt(assign); // jump to the test Emit.Label test = this.il.DefineLabel(); this.il.Emit(Emit.OpCodes.Br, test); // statements in the body of the for loop Emit.Label body = this.il.DefineLabel(); this.il.MarkLabel(body); this.GenStmt(forLoop.Body); // to (increment the value of x) this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.il.Emit(Emit.OpCodes.Ldc_I4, 1); this.il.Emit(Emit.OpCodes.Add); this.Store(forLoop.Ident, typeof(int)); // **test** does x equal 100? (do the test) this.il.MarkLabel(test); this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.GenExpr(forLoop.To, typeof(int)); this.il.Emit(Emit.OpCodes.Blt, body); } else { throw new System.Exception("imposible generar: " + stmt.GetType().Name); } }
private void GenStmt(Stmt stmt) { if (stmt is Sequence) { Sequence seq = (Sequence)stmt; this.GenStmt(seq.First); this.GenStmt(seq.Second); } else if (stmt is DeclareVar) { // declare a local DeclareVar declare = (DeclareVar)stmt; this.symbolTable[declare.Ident] = this.il.DeclareLocal(this.TypeOfExpr(declare.Expr)); // set the initial value Assign assign = new Assign(); assign.Ident = declare.Ident; assign.Expr = declare.Expr; this.GenStmt(assign); } else if (stmt is Assign) { Assign assign = (Assign)stmt; this.GenExpr(assign.Expr, this.TypeOfExpr(assign.Expr)); this.Store(assign.Ident, this.TypeOfExpr(assign.Expr)); } else if (stmt is Print) { // the "print" statement is an alias for System.Console.WriteLine. // it uses the string case this.GenExpr(((Print)stmt).Expr, typeof(string)); this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); } else if (stmt is ReadInt) { this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { }, null)); this.il.Emit(Emit.OpCodes.Call, typeof(int).GetMethod("Parse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { typeof(string) }, null)); this.Store(((ReadInt)stmt).Ident, typeof(int)); } else if (stmt is ForLoop) { // example: // for x = 0 to 100 do // print "hello"; // end; // x = 0 ForLoop forLoop = (ForLoop)stmt; Assign assign = new Assign(); assign.Ident = forLoop.Ident; assign.Expr = forLoop.From; this.GenStmt(assign); // jump to the test Emit.Label test = this.il.DefineLabel(); this.il.Emit(Emit.OpCodes.Br, test); // statements in the body of the for loop Emit.Label body = this.il.DefineLabel(); this.il.MarkLabel(body); this.GenStmt(forLoop.Body); // to (increment the value of x) this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.il.Emit(Emit.OpCodes.Ldc_I4, 1); this.il.Emit(Emit.OpCodes.Add); this.Store(forLoop.Ident, typeof(int)); // **test** does x equal 100? (do the test) this.il.MarkLabel(test); this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.GenExpr(forLoop.To, typeof(int)); this.il.Emit(Emit.OpCodes.Blt, body); } else { throw new System.Exception("don't know how to gen a " + stmt.GetType().Name); } }
private void GenStmt(Stmt stmt) { //Обработка элемента последовательности дерева if (stmt is Sequence) { Sequence seq = (Sequence)stmt; //Выполним обработку левой части дерева this.GenStmt(seq.First); //Выполним обработку правой части дерева this.GenStmt(seq.Second); } //Обработка элемента дерева - "Объявление" else if (stmt is DeclareVar) { // Добавим переменную в список переменных DeclareVar declare = (DeclareVar)stmt; this.varTable[declare.Ident] = this.TypeOfExpr(declare.Expression); //Приведем элемент типа "Объевление" к типу "Присвоение" Assign assign = new Assign(); assign.Ident = declare.Ident; assign.Expression = declare.Expression; //Запишем тип переменной accum.Append(string.Format("\n{0} ", this.TypeOfExpr(declare.Expression).Name)); //Запустим на обработку this.GenStmt(assign); } //Обработка элемента дерева - "Присвоение" else if (stmt is Assign) { Assign assign = (Assign)stmt; accum.Append(string.Format("{0}=", assign.Ident)); //Обработка правой части элемента this.GenAssign(assign.Expression); accum.Append(";"); } //Обработка элемента дерева - "Вывод данных" else if (stmt is Print) { Print print = (Print)stmt; accum.Append(print.VarExpression != null ? string.Format("\nConsole.WriteLine(\"{0}\", {1});", this.GetExprValue(print.Expression), this.GetExprValue(print.VarExpression)) : string.Format("\nConsole.WriteLine(\"{0}\");", this.GetExprValue(print.Expression))); } //Обработка элемента дерева - "Ввод данных" else if (stmt is ReadValue) { ReadValue readValue = (ReadValue)stmt; accum.Append(readValue.Exp != null ? string.Format("\n{0} = Console.ReadLine(\"{1}\");", readValue.Ident, this.GetExprValue(readValue.Exp)) : string.Format("\n{0} = Console.ReadLine();", readValue.Ident)); //Проверка, что переменная объявлена ранее //CheckVariable } else if (stmt is IfElse) { IfElse ifElse = (IfElse)stmt; string operation = string.Empty; switch (ifElse.Condition.Operation) { case ConOperation.Equal: operation = "="; break; case ConOperation.Less: operation = "<"; break; case ConOperation.LessEqual: operation = "<="; break; case ConOperation.More: operation = ">"; break; case ConOperation.MoreEqual: operation = ">="; break; } accum.Append(string.Format("\nif ({0}{1}{2})", this.GetExprValue(ifElse.Condition.Left), operation, this.GetExprValue(ifElse.Condition.Right))); if (ifElse.BodyThen != null) { accum.Append("\n{\n"); this.GenStmt(ifElse.BodyThen); accum.Append("\n}"); } if (ifElse.BodyElse != null) { if (ifElse.BodyThen == null) { throw new System.Exception("error if - else"); } accum.Append("\nelse\n{\n"); this.GenStmt(ifElse.BodyElse); accum.Append("\n}"); } } else if (stmt is ForNext) { ForNext forNext = (ForNext)stmt; accum.Append(string.Format("\nfor(")); Assign assign = new Assign(); assign.Ident = forNext.Ident; assign.Expression = forNext.From; this.GenStmt(assign); accum.Append(string.Format("{0}<{1};{2}++)", forNext.Ident, this.GetExprValue(forNext.To), forNext.Ident)); this.varTable[forNext.Ident] = typeof(int); if (forNext.Body != null) { accum.Append("\n{"); this.GenStmt(forNext.Body); accum.Append("\n}"); } } else { throw new System.Exception("Отсутствует инструкция для генерирования операции: " + stmt.GetType().Name); } }
private Stmt ParseStmt() { Stmt result = null; if (this.index == this.tokens.Count) { throw new System.Exception("expected statement, got EOF"); } // <stmt> := print <expr> // <expr> := <string> // | <int> // | <arith_expr> // | <ident> if (this.tokens[this.index].Equals(languageSetting["End"])) { this.index++; } else if (this.tokens[this.index].Equals(languageSetting["Start"])) { this.index++; return(ParseStmt()); } else if (this.tokens[this.index].Equals(languageSetting["Print"])) { this.index++; Print print = new Print(); print.Expr = this.ParseExpr(); result = print; } else if (this.tokens[this.index] == Scanner.Call) { VoidMethodCall vmc = new VoidMethodCall(); vmc.Expr = this.ParseExpr(); result = vmc; } else if (this.tokens[this.index].Equals(languageSetting["VariableDeclaration"])) { this.index++; DeclareVar declareVar = new DeclareVar(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { declareVar.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected variable name after 'var'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected = after 'var ident'"); } this.index++; declareVar.Expr = this.ParseExpr(); result = declareVar; } else if (this.tokens[this.index].Equals(languageSetting["if"])) { this.index++; IfCondition ifCon = new IfCondition(); ifCon.BooleanExp = this.ParseExpr(); if (!this.tokens[++this.index].Equals(languageSetting["Start"])) { throw new System.Exception("Start Expected"); } ifCon.Body = this.ParseStmt(); if (!this.tokens[this.index++].Equals(languageSetting["End"])) { throw new System.Exception("End Expected"); } result = ifCon; } else if (this.tokens[this.index].Equals(languageSetting["while"])) { this.index++; WhileLoop whileLoop = new WhileLoop(); whileLoop.BooleanExp = this.ParseExpr(); if (!this.tokens[++this.index].Equals(languageSetting["Start"])) { throw new System.Exception("Start Expected"); } whileLoop.Body = this.ParseStmt(); if (!this.tokens[this.index++].Equals(languageSetting["End"])) { throw new System.Exception("End Expected"); } result = whileLoop; } else if (this.tokens[this.index].Equals("read_int")) { this.index++; ReadInt readInt = new ReadInt(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { readInt.Ident = (string)this.tokens[this.index++]; result = readInt; } else { throw new System.Exception("expected variable name after 'read_int'"); } } else if (this.tokens[this.index].Equals("for")) { this.index++; ForLoop forLoop = new ForLoop(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { forLoop.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected identifier after 'for'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("for missing '='"); } this.index++; forLoop.From = this.ParseSingleExpression(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("to")) { throw new System.Exception("expected 'to' after for"); } this.index++; forLoop.To = this.ParseSingleExpression(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("do")) { throw new System.Exception("expected 'do' after from expression in for loop"); } this.index++; forLoop.Body = this.ParseStmt(); result = forLoop; if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("end")) { throw new System.Exception("unterminated 'for' loop body"); } this.index++; } else if (this.tokens[this.index] is string) { // assignment Assign assign = new Assign(); assign.Ident = (string)this.tokens[this.index++]; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected '='"); } this.index++; assign.Expr = this.ParseExpr(); result = assign; } else { throw new System.Exception("parse error at token " + this.index + ": " + this.tokens[this.index]); } if (this.index < this.tokens.Count && this.tokens[this.index] == Scanner.Semi) { this.index++; if (this.index < this.tokens.Count && !this.tokens[this.index].Equals(languageSetting["End"])) { Sequence sequence = new Sequence(); sequence.First = result; sequence.Second = this.ParseStmt(); result = sequence; } } return(result); }
private Stmt ParseStmt() { Stmt resultado; if (this.indice == this.tokens.Count) { throw new System.Exception("se esperaban sentencias, se llego al final del archivo"); } // <stmt> := print <expr> // <expr> := <string> // | <int> // | <arith_expr> // | <ident> if (this.tokens[this.indice].Equals("print")) { this.indice++; Print print = new Print(); print.Expr = this.ParseExpr(); resultado = print; } else if (this.tokens[this.indice].Equals("var")) { this.indice++; DeclareVar declareVar = new DeclareVar(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { declareVar.Ident = (string)this.tokens[this.indice]; } else { throw new System.Exception("Se esperaba nombre de variable despues de 'var'"); } this.indice++; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("se esperaba = despues de 'var ident'"); } this.indice++; declareVar.Expr = this.ParseExpr(); resultado = declareVar; } else if (this.tokens[this.indice].Equals("read_int")) { this.indice++; ReadInt readInt = new ReadInt(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { readInt.Ident = (string)this.tokens[this.indice++]; resultado = readInt; } else { throw new System.Exception("Se esperaba el nombre de la variable 'read_int'"); } } //******************* else if (this.tokens[this.indice].Equals("if")) { this.indice++; mcIf mcif = new mcIf(); Expr temp = ParseExpr(); if (this.tokens[this.indice] == Scanner.Eq || this.tokens[this.indice] == Scanner.Neq || this.tokens[this.indice] == Scanner.Gt || this.tokens[this.indice] == Scanner.Gte || this.tokens[this.indice] == Scanner.Lt || this.tokens[this.indice] == Scanner.Lte) { CompExpr compExpr = new CompExpr(); compExpr.Left = temp; object op = this.tokens[this.indice++]; if (op == Scanner.Eq) compExpr.Op = CompOp.Eq; else if (op == Scanner.Neq) compExpr.Op = CompOp.Neq; else if (op == Scanner.Gt) compExpr.Op = CompOp.Gt; else if (op == Scanner.Gte) compExpr.Op = CompOp.Gte; else if (op == Scanner.Lt) compExpr.Op = CompOp.Lt; else if (op == Scanner.Lte) compExpr.Op = CompOp.Lte; compExpr.Rigth = ParseExpr(); temp = compExpr; } mcif.compExpr = temp; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("then")) { throw new System.Exception("Se esperaba el identificador 'then' despues de 'if'"); } this.indice++; mcif.Then = ParseStmt(); if (this.tokens[this.indice].Equals("else")) { this.indice++; mcif.Else = ParseStmt(); } resultado = mcif; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("Sentencia if inconclusa"); } this.indice++; } else if (this.tokens[this.indice].Equals("while")) { this.indice++; WhileLoop whileLoop = new WhileLoop(); Expr temp = ParseExpr(); if (this.tokens[this.indice] == Scanner.Eq || this.tokens[this.indice] == Scanner.Neq || this.tokens[this.indice] == Scanner.Gt || this.tokens[this.indice] == Scanner.Gte || this.tokens[this.indice] == Scanner.Lt || this.tokens[this.indice] == Scanner.Lte) { CompExpr compExpr = new CompExpr(); compExpr.Left = temp; object op = this.tokens[this.indice++]; if (op == Scanner.Eq) compExpr.Op = CompOp.Eq; else if (op == Scanner.Neq) compExpr.Op = CompOp.Neq; else if (op == Scanner.Gt) compExpr.Op = CompOp.Gt; else if (op == Scanner.Gte) compExpr.Op = CompOp.Gte; else if (op == Scanner.Lt) compExpr.Op = CompOp.Lt; else if (op == Scanner.Lte) compExpr.Op = CompOp.Lte; compExpr.Rigth = ParseExpr(); temp = compExpr; } whileLoop.Cond = temp; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("do")) { throw new System.Exception("Se esperaba el identificador 'do' despues de 'while'"); } this.indice++; whileLoop.Body = ParseStmt(); resultado = whileLoop; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("sentencia while inconclusa"); } this.indice++; } //******************* else if (this.tokens[this.indice].Equals("for")) { this.indice++; ForLoop forLoop = new ForLoop(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { forLoop.Ident = (string)this.tokens[this.indice]; } else { throw new System.Exception("se esperaba un indentificador despues de 'for'"); } this.indice++; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("no se encontro en la sentencia for '='"); } this.indice++; forLoop.From = this.ParseExpr(); if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("to")) { throw new System.Exception("se epsaraba 'to' despues de for"); } this.indice++; forLoop.To = this.ParseExpr(); if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("do")) { throw new System.Exception("se esperaba 'do' despues de la expresion en el ciclo for"); } this.indice++; forLoop.Body = this.ParseStmt(); resultado = forLoop; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("setencia for inconclusa"); } this.indice++; } else if (this.tokens[this.indice] is string) { // assignment Assign assign = new Assign(); assign.Ident = (string)this.tokens[this.indice++]; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("se esperaba '='"); } this.indice++; assign.Expr = this.ParseExpr(); resultado = assign; } else { throw new System.Exception("Error en el token " + this.indice + ": " + this.tokens[this.indice]); } if (this.indice < this.tokens.Count && this.tokens[this.indice] == Scanner.PyC) { this.indice++; if (this.indice < this.tokens.Count && !this.tokens[this.indice].Equals("end") && !this.tokens[this.indice].Equals("else")) { Sequence sequence = new Sequence(); sequence.First = resultado; sequence.Second = this.ParseStmt(); resultado = sequence; } } return resultado; }
private Stmt ParseStmt() { Stmt result; if (this.index == this.tokens.Count) { throw new System.Exception("expected statement, got EOF"); } // <stmt> := print <expr> // <expr> := <string> // | <int> // | <arith_expr> // | <ident> if (this.tokens[this.index].Equals("print")) { this.index++; Print print = new Print(); print.Expr = this.ParseExpr(); result = print; } else if (this.tokens[this.index].Equals("var")) { this.index++; DeclareVar declareVar = new DeclareVar(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { declareVar.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected variable name after 'var'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected = after 'var ident'"); } this.index++; declareVar.Expr = this.ParseExpr(); result = declareVar; } else if (this.tokens[this.index].Equals("read_int")) { this.index++; ReadInt readInt = new ReadInt(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { readInt.Ident = (string)this.tokens[this.index++]; result = readInt; } else { throw new System.Exception("expected variable name after 'read_int'"); } } else if (this.tokens[this.index].Equals("for")) { this.index++; ForLoop forLoop = new ForLoop(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { forLoop.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected identifier after 'for'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("for missing '='"); } this.index++; forLoop.From = this.ParseExpr(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("to")) { throw new System.Exception("expected 'to' after for"); } this.index++; forLoop.To = this.ParseExpr(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("do")) { throw new System.Exception("expected 'do' after from expression in for loop"); } this.index++; forLoop.Body = this.ParseStmt(); result = forLoop; if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("end")) { throw new System.Exception("unterminated 'for' loop body"); } this.index++; } else if (this.tokens[this.index] is string) { // assignment Assign assign = new Assign(); assign.Ident = (string)this.tokens[this.index++]; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected '='"); } this.index++; assign.Expr = this.ParseExpr(); result = assign; } else { throw new System.Exception("parse error at token " + this.index + ": " + this.tokens[this.index]); } if (this.index < this.tokens.Count && this.tokens[this.index] == Scanner.Semi) { this.index++; if (this.index < this.tokens.Count && !this.tokens[this.index].Equals("end")) { Sequence sequence = new Sequence(); sequence.First = result; sequence.Second = this.ParseStmt(); result = sequence; } } return(result); }
private Stmt ParseStmt() { Stmt resultado; if (this.indice == this.tokens.Count) { throw new System.Exception("se esperaban sentencias, se llego al final del archivo"); } // <stmt> := print <expr> // <expr> := <string> // | <int> // | <arith_expr> // | <ident> if (this.tokens[this.indice].Equals("print")) { this.indice++; Print print = new Print(); print.Expr = this.ParseExpr(); resultado = print; } else if (this.tokens[this.indice].Equals("var")) { this.indice++; DeclareVar declareVar = new DeclareVar(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { declareVar.Ident = (string)this.tokens[this.indice]; } else { throw new System.Exception("Se esperaba nombre de variable despues de 'var'"); } this.indice++; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("se esperaba = despues de 'var ident'"); } this.indice++; declareVar.Expr = this.ParseExpr(); resultado = declareVar; } else if (this.tokens[this.indice].Equals("read_int")) { this.indice++; ReadInt readInt = new ReadInt(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { readInt.Ident = (string)this.tokens[this.indice++]; resultado = readInt; } else { throw new System.Exception("Se esperaba el nombre de la variable 'read_int'"); } } //******************* else if (this.tokens[this.indice].Equals("if")) { this.indice++; mcIf mcif = new mcIf(); Expr temp = ParseExpr(); if (this.tokens[this.indice] == Scanner.Eq || this.tokens[this.indice] == Scanner.Neq || this.tokens[this.indice] == Scanner.Gt || this.tokens[this.indice] == Scanner.Gte || this.tokens[this.indice] == Scanner.Lt || this.tokens[this.indice] == Scanner.Lte) { CompExpr compExpr = new CompExpr(); compExpr.Left = temp; object op = this.tokens[this.indice++]; if (op == Scanner.Eq) { compExpr.Op = CompOp.Eq; } else if (op == Scanner.Neq) { compExpr.Op = CompOp.Neq; } else if (op == Scanner.Gt) { compExpr.Op = CompOp.Gt; } else if (op == Scanner.Gte) { compExpr.Op = CompOp.Gte; } else if (op == Scanner.Lt) { compExpr.Op = CompOp.Lt; } else if (op == Scanner.Lte) { compExpr.Op = CompOp.Lte; } compExpr.Rigth = ParseExpr(); temp = compExpr; } mcif.compExpr = temp; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("then")) { throw new System.Exception("Se esperaba el identificador 'then' despues de 'if'"); } this.indice++; mcif.Then = ParseStmt(); if (this.tokens[this.indice].Equals("else")) { this.indice++; mcif.Else = ParseStmt(); } resultado = mcif; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("Sentencia if inconclusa"); } this.indice++; } else if (this.tokens[this.indice].Equals("while")) { this.indice++; WhileLoop whileLoop = new WhileLoop(); Expr temp = ParseExpr(); if (this.tokens[this.indice] == Scanner.Eq || this.tokens[this.indice] == Scanner.Neq || this.tokens[this.indice] == Scanner.Gt || this.tokens[this.indice] == Scanner.Gte || this.tokens[this.indice] == Scanner.Lt || this.tokens[this.indice] == Scanner.Lte) { CompExpr compExpr = new CompExpr(); compExpr.Left = temp; object op = this.tokens[this.indice++]; if (op == Scanner.Eq) { compExpr.Op = CompOp.Eq; } else if (op == Scanner.Neq) { compExpr.Op = CompOp.Neq; } else if (op == Scanner.Gt) { compExpr.Op = CompOp.Gt; } else if (op == Scanner.Gte) { compExpr.Op = CompOp.Gte; } else if (op == Scanner.Lt) { compExpr.Op = CompOp.Lt; } else if (op == Scanner.Lte) { compExpr.Op = CompOp.Lte; } compExpr.Rigth = ParseExpr(); temp = compExpr; } whileLoop.Cond = temp; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("do")) { throw new System.Exception("Se esperaba el identificador 'do' despues de 'while'"); } this.indice++; whileLoop.Body = ParseStmt(); resultado = whileLoop; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("sentencia while inconclusa"); } this.indice++; } //******************* else if (this.tokens[this.indice].Equals("for")) { this.indice++; ForLoop forLoop = new ForLoop(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { forLoop.Ident = (string)this.tokens[this.indice]; } else { throw new System.Exception("se esperaba un indentificador despues de 'for'"); } this.indice++; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("no se encontro en la sentencia for '='"); } this.indice++; forLoop.From = this.ParseExpr(); if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("to")) { throw new System.Exception("se epsaraba 'to' despues de for"); } this.indice++; forLoop.To = this.ParseExpr(); if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("do")) { throw new System.Exception("se esperaba 'do' despues de la expresion en el ciclo for"); } this.indice++; forLoop.Body = this.ParseStmt(); resultado = forLoop; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("setencia for inconclusa"); } this.indice++; } else if (this.tokens[this.indice] is string) { // assignment Assign assign = new Assign(); assign.Ident = (string)this.tokens[this.indice++]; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("se esperaba '='"); } this.indice++; assign.Expr = this.ParseExpr(); resultado = assign; } else { throw new System.Exception("Error en el token " + this.indice + ": " + this.tokens[this.indice]); } if (this.indice < this.tokens.Count && this.tokens[this.indice] == Scanner.PyC) { this.indice++; if (this.indice < this.tokens.Count && !this.tokens[this.indice].Equals("end") && !this.tokens[this.indice].Equals("else")) { Sequence sequence = new Sequence(); sequence.First = resultado; sequence.Second = this.ParseStmt(); resultado = sequence; } } return(resultado); }
private void GenStmt(Stmt stmt) { if (stmt is Sequence) { Sequence seq = (Sequence)stmt; this.GenStmt(seq.First); this.GenStmt(seq.Second); } else if (stmt is DeclareVar) { // declare a local DeclareVar declare = (DeclareVar)stmt; this.symbolTable[declare.Ident] = this.il.DeclareLocal(this.TypeOfExpr(declare.Expr)); // set the initial value Assign assign = new Assign(); assign.Ident = declare.Ident; assign.Expr = declare.Expr; this.GenStmt(assign); } else if (stmt is Assign) { Assign assign = (Assign)stmt; if (this.typefieldList.ContainsKey(assign.Ident)) { if (!this.typefieldList[assign.Ident].IsStatic) { this.il.Emit(Emit.OpCodes.Ldarg_0); } } // if(assign.Ident this.GenExpr(assign.Expr, this.TypeOfExpr(assign.Expr)); this.Store(assign.Ident, this.TypeOfExpr(assign.Expr)); } else if (stmt is Print) { // the "print" statement is an alias for System.Console.WriteLine. // it uses the string case this.GenExpr(((Print)stmt).Expr, typeof(string)); this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); // this.il.Emit( } else if (stmt is VoidMethodCall) { this.GenerteMethodCallCode((MethodCall)((VoidMethodCall)stmt).Expr); } else if (stmt is IfCondition) { IfCondition ifCon = (IfCondition)stmt; this.GenExpr(ifCon.BooleanExp, /*harcoded for string */ typeof(string)); Emit.Label endOfIfBlock = this.il.DefineLabel(); if (((BinExpr)ifCon.BooleanExp).Op == BinOp.EqualTo) { this.il.Emit(Emit.OpCodes.Brfalse_S, endOfIfBlock); } else { this.il.Emit(Emit.OpCodes.Brtrue_S, endOfIfBlock); } this.GenStmt(ifCon.Body); this.il.MarkLabel(endOfIfBlock); // this.GenerteMethodCallCode((MethodCall)((VoidMethodCall)stmt).Expr); } else if (stmt is WhileLoop) { WhileLoop whileLoop = (WhileLoop)stmt; Emit.Label whileBodyStart = this.il.DefineLabel(); Emit.Label whileBodyEnd = this.il.DefineLabel(); Emit.Label whileCondition = this.il.DefineLabel(); this.il.Emit(Emit.OpCodes.Br_S, whileBodyEnd); this.il.MarkLabel(whileBodyStart); this.GenStmt(whileLoop.Body); this.il.MarkLabel(whileBodyEnd); this.GenExpr(whileLoop.BooleanExp, /*harcoded for int */ typeof(int)); if (((BinExpr)whileLoop.BooleanExp).Op == BinOp.EqualTo) { this.il.Emit(Emit.OpCodes.Brtrue_S, whileBodyStart); } else { this.il.Emit(Emit.OpCodes.Brfalse_S, whileBodyStart); } } // System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch(); else if (stmt is ReadInt) { this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { }, null)); this.il.Emit(Emit.OpCodes.Call, typeof(int).GetMethod("Parse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { typeof(string) }, null)); this.Store(((ReadInt)stmt).Ident, typeof(int)); } else if (stmt is ForLoop) { // example: // for x = 0 to 100 do // print "hello"; // end; // x = 0 ForLoop forLoop = (ForLoop)stmt; Assign assign = new Assign(); assign.Ident = forLoop.Ident; assign.Expr = forLoop.From; this.GenStmt(assign); // jump to the test Emit.Label test = this.il.DefineLabel(); this.il.Emit(Emit.OpCodes.Br, test); // statements in the body of the for loop Emit.Label body = this.il.DefineLabel(); this.il.MarkLabel(body); this.GenStmt(forLoop.Body); // to (increment the value of x) this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.il.Emit(Emit.OpCodes.Ldc_I4, 1); this.il.Emit(Emit.OpCodes.Add); this.Store(forLoop.Ident, typeof(int)); // **test** does x equal 100? (do the test) this.il.MarkLabel(test); this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.GenExpr(forLoop.To, typeof(int)); this.il.Emit(Emit.OpCodes.Blt, body); } else { throw new System.Exception("don't know how to gen a " + stmt.GetType().Name); } }
private Stmt ParseStmt() { Stmt result; if (this.index == this.tokens.Count) { throw new System.Exception("expected statement, got EOF"); } // <stmt> := print <expr> // <expr> := <string> // | <int> // | <arith_expr> // | <ident> if (this.tokens[this.index].Equals("print")) { this.index++; Print print = new Print(); print.Expr = this.ParseExpr(); result = print; } else if (this.tokens[this.index].Equals("var")) { this.index++; DeclareVar declareVar = new DeclareVar(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { declareVar.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected variable name after 'var'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected = after 'var ident'"); } this.index++; declareVar.Expr = this.ParseExpr(); result = declareVar; } else if (this.tokens[this.index].Equals("read_int")) { this.index++; ReadInt readInt = new ReadInt(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { readInt.Ident = (string)this.tokens[this.index++]; result = readInt; } else { throw new System.Exception("expected variable name after 'read_int'"); } } else if (this.tokens[this.index].Equals("for")) { this.index++; ForLoop forLoop = new ForLoop(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { forLoop.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected identifier after 'for'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("for missing '='"); } this.index++; forLoop.From = this.ParseExpr(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("to")) { throw new System.Exception("expected 'to' after for"); } this.index++; forLoop.To = this.ParseExpr(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("do")) { throw new System.Exception("expected 'do' after from expression in for loop"); } this.index++; forLoop.Body = this.ParseStmt(); result = forLoop; if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("end")) { throw new System.Exception("unterminated 'for' loop body"); } this.index++; } else if (this.tokens[this.index] is string) { // assignment Assign assign = new Assign(); assign.Ident = (string)this.tokens[this.index++]; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected '='"); } this.index++; assign.Expr = this.ParseExpr(); result = assign; } else { throw new System.Exception("parse error at token " + this.index + ": " + this.tokens[this.index]); } if (this.index < this.tokens.Count && this.tokens[this.index] == Scanner.Semi) { this.index++; if (this.index < this.tokens.Count && !this.tokens[this.index].Equals("end")) { Sequence sequence = new Sequence(); sequence.First = result; sequence.Second = this.ParseStmt(); result = sequence; } } return result; }