趁两个晚上的时间 学习了一下if, for, while语句的编译, 现在可以模拟程序的运行
目前仅支持int变量声明 其他的还有些问题 , 可以得到程序运行结果
代码如下 仅供感兴趣者参考
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Reflection.Emit;
namespace compiler
{
class CompilerTable
{
public static string[] tables = new string[] { "{", "}", "(", ")", "+", "-", "*", "/", "=", "if", "else","while","for", ",", ";", "i" };
public static string[] typeTable = new string[] { "int", "double", "string" };
public static string[] logicOperators = new string[] { ">", "<", ">=", "<=", "==", "!=", "||", "&&" };
public static string Sym(string str)
{
foreach (string s in tables)
{
if (str == s) return s;
}
foreach (string s in typeTable)
{
if (str == s) return "type";
}
foreach (string s in logicOperators)
{
if (str == s) return "logicOP";
}
return "i";
}
public static bool IsDigit(string str)
{
if (str == "") return false;
if ((str[0] >= '0') && (str[0] <= '9')) return true;
return false;
}
}
class OP
{
public string op;
public string result;
public string arg1;
public string arg2;
}
class CompilerExcute
{
SortedList<string, object> variables = new SortedList<string, object>();
static object NewObject(string Name, object[] objs)
{
object obj = null;
try
{
Assembly _Assembly = Assembly.GetEntryAssembly();
Type type = _Assembly.GetType(Name);
if (type == null)
{
_Assembly = Assembly.GetCallingAssembly();
type = _Assembly.GetType(Name);
}
if (type == null)
{
_Assembly = Assembly.GetExecutingAssembly();
type = _Assembly.GetType(Name);
}
if (type == null) return null;
if (objs != null)
obj = Activator.CreateInstance(type, objs);
else
obj = Activator.CreateInstance(type);
}
catch (TypeLoadException e)
{
MessageBox.Show("I dont know this kind of class =" + Name, e.Message);
}
return obj;
}
SortedList<string, string> typeMapping = new SortedList<string, string>();
public CompilerExcute()
{
if (typeMapping.Count == 0)
{
typeMapping.Add("int", typeof(int).ToString());
typeMapping.Add("double", typeof(double).ToString());
typeMapping.Add("string", typeof(string).ToString());
}
}
public void Excute(List<OP> op_list)
{
variables.Clear();
int IP = 0;
while (IP < op_list.Count)
{
OP op = op_list[IP];
if (op.op == "Variable")
{
string typename=op.arg1;
if (typename == "int") variables.Add(op.result, new int());
if (typename == "double") variables.Add(op.result, new double());
if (typename == "string") variables.Add(op.result, new string(' ', 1));
if (!typeMapping.ContainsKey(typename))
{
object obj = NewObject(typename, null);
if (obj == null)
{
MessageBox.Show("can new variable of type " + typename);
return;
}
variables.Add(op.result, obj);
}
IP++;
continue;
}
object arg1_obj = 0, arg2_obj = 0;
Type type = null;
if (variables.IndexOfKey(op.result) < 0) variables.Add(op.result, 0);
if (op.arg1 != "")
{
if (CompilerTable.IsDigit(op.arg1))
{
arg1_obj = int.Parse(op.arg1);
}
else
{
arg1_obj = variables[op.arg1];
}
}
if (op.arg2 != "")
{
if (CompilerTable.IsDigit(op.arg2))
arg2_obj = int.Parse(op.arg2);
else if (op.arg2 != "")
arg2_obj = (int)variables[op.arg2];
}
string code = ToCode(IP,op);
if (arg1_obj is int)
{
int arg1 = (int)arg1_obj;
int arg2 = (int)arg2_obj;
if (op.op == "=") variables[op.result] = arg1;
if (op.op == "+") variables[op.result] = arg1 + arg2;
if (op.op == "*") variables[op.result] = arg1 * arg2;
if (op.op == "-") variables[op.result] = arg1 - arg2;
if (op.op == "/") variables[op.result] = arg1 / arg2;
if (op.op == ">") variables[op.result] = Convert.ToInt32(arg1 > arg2);
if (op.op == "<") variables[op.result] = Convert.ToInt32(arg1 < arg2);
if (op.op == ">=") variables[op.result] = Convert.ToInt32(arg1 >= arg2);
if (op.op == "<=") variables[op.result] = Convert.ToInt32(arg1 <= arg2);
if (op.op == "==") variables[op.result] = Convert.ToInt32(arg1 == arg2);
if (op.op == "!=") variables[op.result] = Convert.ToInt32(arg1 != arg2);
if (op.op == "||") variables[op.result] = Convert.ToInt32(arg1 | arg2);
if (op.op == "&&") variables[op.result] = Convert.ToInt32(arg1 & arg2);
}
if (arg1_obj is double)
{
double arg1 = (double)arg1_obj;
double arg2 = (double)arg2_obj;
if (op.op == "=") variables[op.result] = arg1;
if (op.op == "+") variables[op.result] = arg1 + arg2;
if (op.op == "*") variables[op.result] = arg1 * arg2;
if (op.op == "-") variables[op.result] = arg1 - arg2;
if (op.op == "/") variables[op.result] = arg1 / arg2;
if (op.op == ">") variables[op.result] = Convert.ToInt32(arg1 > arg2);
if (op.op == "<") variables[op.result] = Convert.ToInt32(arg1 < arg2);
if (op.op == ">=") variables[op.result] = Convert.ToInt32(arg1 >= arg2);
if (op.op == "<=") variables[op.result] = Convert.ToInt32(arg1 <= arg2);
if (op.op == "==") variables[op.result] = Convert.ToInt32(arg1 == arg2);
if (op.op == "!=") variables[op.result] = Convert.ToInt32(arg1 != arg2);
}
if (arg1_obj is string )
{
string arg1 = (string)arg1_obj;
string arg2 = (string)arg2_obj;
if (op.op == "=") variables[op.result] = arg1;
if (op.op == "+") variables[op.result] = arg1 + arg2;
if (op.op == "==") variables[op.result] = Convert.ToInt32(arg1 == arg2);
if (op.op == "!=") variables[op.result] = Convert.ToInt32(arg1 != arg2);
}
IP++;
if (op.op == "IfGoto")
{
int arg1 = (int)arg1_obj;
if (arg1 > 0) IP = int.Parse(op.result);
}
if (op.op == "Goto")
{
IP = int.Parse(op.result);
}
}
}
public string ToCode(int line, OP op)
{
string code = "(" + line.ToString() + ") ";
if (op.op == "=")
{
return code + op.result + op.op + op.arg1 + "; ";
}
if ((op.op == "+") || (op.op == "-") || (op.op == "*") || (op.op == "/"))
{
return code + op.result + "=" + op.arg1 + op.op + op.arg2 + "; ";
}
if ((op.op == ">") || (op.op == ">=") || (op.op == "<") || (op.op == "<=") || (op.op == "==") || (op.op == "!=") || (op.op == "||")|| (op.op == "&&"))
{
return code + op.result + "=" + op.arg1 + op.op + op.arg2 + "; ";
}
if (op.op == "Variable")
{
return code + " : " + op.op + " " + op.arg1+" "+ op.result + "; ";
}
if (op.op == "Goto")
{
return code + " : " + op.op + op.result + "; ";
}
if (op.op == "IfGoto")
{
return code + " If " + op.arg1.ToString() + " Goto " + op.result + "; ";
}
return "";
}
public string ToCode(List<OP> op_list)
{
string code = "";
int line = 0;
foreach (OP op in op_list)
{
code += ToCode(line++, op);
}
return code;
}
public object GetValue(string name)
{
if(variables.ContainsKey(name)) return variables[name];
return null;
}
}
class Compiler
{
int count = 0;
string[] words;
List<OP> op_list = new List<OP>();
//string code = "int a ; int b , c ; a = a + 10 + b + c ; #";
// string code = "a = a + 10 + b * 10 * 3 + c ; ";
// string code = " int a , b = 5 , c = 4 ; int d , e ; a = 5 ; if ( a + c ) { d = 10 ; d = 5 + 5 : if ( d ) d = 100 ; } else { d = 20 ; d = 10 + 10 ; d = 200 ; } a = 10 + d ; a = a + d ; d = d ; ; ";
// string code = " int a , b = 5 ; a = 5 ; while ( a > 1 ) { a = a - 1 ; b = b + 1 ; } ; ";
string code = " int a , b = 0 , i ; a = 5 ; for ( i = 0 ; i < 10 ; i = i + 1 ) { a = a - 1 ; b = b + 1 ; } ; ";
public Compiler()
{
string[] ss = code.Split(' ');
words = new string[5000];
foreach (string s in ss)
{
if (s.Length > 0) words[count++] = s;
}
count = 0;
//int a = 10;
//int a2 = 10;
//object b = a;
//object b2 = a2;
//object bb = b + b2;
//string s1=b.GetType().ToString();
//string s2 = ((object)a).GetType().ToString();
//object ss1 = s1;
//object ss2 = s2;
//object ss = ss1 + ss2;
Start();
CompilerExcute excute = new CompilerExcute();
string sss = excute.ToCode(op_list);
excute.Excute(op_list);
int aa= (int)excute.GetValue("a");
int bb = (int)excute.GetValue("b");
}
string sym;
string id;
public void Scaner()
{
if (words[count] == null) return;
sym = CompilerTable.Sym(words[count]);
id = words[count];
count++;
}
public void Start()
{
Scaner();
Code();
}
static int _t = 0;
public string NewTemp()
{
return "T" + (_t++).ToString();
}
public int Emit(string opt, string result, string arg1, string arg2)
{
OP op = new OP();
op.op = opt;
op.result = result;
op.arg1 = arg1;
op.arg2 = arg2;
op_list.Add(op);
return op_list.Count - 1;
}
public int Emit(string opt, int result, string arg1, string arg2)
{
return Emit(opt, result.ToString(), arg1, arg2);
}
public string Lookup(string name)
{
return name;
}
// // 产生式如下
//Statement->st{st} //声明变量
//st->int st1{,st1} ;
//st1->i{=i};
//Body->S{S}|{Body} //主体赋值表达式
//Expression->Term{+Term|-Term}
//Term->Factor{*Factor|/Factor}
//Factor->i|(Expression)
//Code->{ Statement} Body //
// >, <, >=, <=, !=, ==, ||, &&
public void Code()
{
Body(0);
}
public void Body(int level)
{
if (sym == "{")
{
Scaner(); // {
Body(level+1);
Scaner(); // }
return;
}
while ((sym == "type") || (sym == "i") || (sym == "if") || (sym == "while") || (sym == "for")) Sentence(level);
}
void backpatch(int index, int address)
{
op_list[index].result = address.ToString();
}
public void Sentence(int level)
{
if (sym == "i") { Assignment(level); return; }
if (sym == "if") { If_Sentence(level); return; }
if (sym == "while") { While_Sentence(level); return; }
if (sym == "for") { For_Sentence(level); return; }
if (sym == "type") { Statement( ); return; }
if (sym == ";") { Scaner(); return; }
}
public void Statement()
{
string typeKind = id;
Scaner();
StatementOne(typeKind);
while (sym == ",")
{
Scaner();
StatementOne(typeKind);
}
Scaner(); // shouble be ;
}
public void StatementOne(string typekind)
{
if (sym != "i") return; //error
string variable = id;
Emit("Variable", variable, typekind, "");
Scaner();
if (sym == "=")
{
Scaner();
//得到初始值
Emit("=", variable, id, "");
Scaner(); //should be , or ;
}
}
public void For_Sentence(int level)
{
Scaner(); // for
Scaner(); // shouble be (
Sentence(level);
int E_Decide=op_list.Count;
String E = LogicExpression();
int E_True=Emit("IfGoto", 0, E, "");
int E_False = Emit("Goto", 0, "", "");
Scaner(); //shouble be ;
int nextLoop = op_list.Count;
Sentence(level);
Scaner(); // shouble be )
Emit("Goto", E_Decide, "", "");
backpatch(E_True, op_list.Count);
Body(level);
Emit("Goto", nextLoop, "", "");
backpatch(E_False, op_list.Count);
}
public void While_Sentence(int level)
{
Scaner();
Scaner(); // shouble be (
int E_decide=op_list.Count;
string E = LogicExpression();
Scaner(); //shouble be )
Emit("IfGoto", op_list.Count + 2, E, "");
int E_false = Emit("Goto", 0, "", "");
Body(level );
Emit("Goto", E_decide,"","");
backpatch(E_false, op_list.Count);
}
public void If_Sentence(int level)
{
Scaner(); //should be if
Scaner(); // shouble be (
string E = LogicExpression();
Scaner(); //shouble be )
Emit("IfGoto", op_list.Count + 2, E, "");
int E_false = Emit("Goto", 0, "", "");
Body(level+1);
int E_True_Done = Emit("Goto", 0, "", "");
backpatch(E_false, op_list.Count);
if (sym == "else")
{
Scaner(); // should be else
Body(level + 1);
}
backpatch(E_True_Done, op_list.Count);
}
public string Assignment(int level)
{
if (sym != "i") return "error"; ;
string A1 = id;
Scaner();
if (sym == "=")
{
Scaner();
Emit("=", A1, Expression(), "");
}
if (sym == ";")
Scaner(); //should be ; but in for loop ,the last sentence has no ; for end
else if (sym != ")")
return "error";
return A1;
}
public string LogicExpression()
{
String L = Expression();
if (sym == "logicOP")
{
string rop = id;
Scaner(); // >
string L2 = Expression();
string temp = NewTemp();
Emit(rop, temp, L, L2);
L = temp;
}
return L;
}
public string Expression()
{
string E1 = Term();
while ((sym == "+") || (sym == "-"))
{
string op = sym;
Scaner();
string E2 = Term();
string temp = NewTemp();
Emit(op, temp, E1, E2);
E1 = temp;
}
return E1;
}
public string Term()
{
string T1 = Factor();
while ((sym == "*") || (sym == "/"))
{
string op = sym;
Scaner();
string T2 = Factor();
string temp = NewTemp();
Emit(op, temp, T1, T2);
T1 = temp;
}
return T1;
}
public string Factor()
{
if (sym == "i")
{
string F1 = id;
Scaner();
return F1;
}
if (sym == "(")
{
Scaner(); // (
string F1 = Expression();
Scaner(); // )
return F1;
}
return "error";
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Reflection.Emit;
namespace compiler
{
class CompilerTable
{
public static string[] tables = new string[] { "{", "}", "(", ")", "+", "-", "*", "/", "=", "if", "else","while","for", ",", ";", "i" };
public static string[] typeTable = new string[] { "int", "double", "string" };
public static string[] logicOperators = new string[] { ">", "<", ">=", "<=", "==", "!=", "||", "&&" };
public static string Sym(string str)
{
foreach (string s in tables)
{
if (str == s) return s;
}
foreach (string s in typeTable)
{
if (str == s) return "type";
}
foreach (string s in logicOperators)
{
if (str == s) return "logicOP";
}
return "i";
}
public static bool IsDigit(string str)
{
if (str == "") return false;
if ((str[0] >= '0') && (str[0] <= '9')) return true;
return false;
}
}
class OP
{
public string op;
public string result;
public string arg1;
public string arg2;
}
class CompilerExcute
{
SortedList<string, object> variables = new SortedList<string, object>();
static object NewObject(string Name, object[] objs)
{
object obj = null;
try
{
Assembly _Assembly = Assembly.GetEntryAssembly();
Type type = _Assembly.GetType(Name);
if (type == null)
{
_Assembly = Assembly.GetCallingAssembly();
type = _Assembly.GetType(Name);
}
if (type == null)
{
_Assembly = Assembly.GetExecutingAssembly();
type = _Assembly.GetType(Name);
}
if (type == null) return null;
if (objs != null)
obj = Activator.CreateInstance(type, objs);
else
obj = Activator.CreateInstance(type);
}
catch (TypeLoadException e)
{
MessageBox.Show("I dont know this kind of class =" + Name, e.Message);
}
return obj;
}
SortedList<string, string> typeMapping = new SortedList<string, string>();
public CompilerExcute()
{
if (typeMapping.Count == 0)
{
typeMapping.Add("int", typeof(int).ToString());
typeMapping.Add("double", typeof(double).ToString());
typeMapping.Add("string", typeof(string).ToString());
}
}
public void Excute(List<OP> op_list)
{
variables.Clear();
int IP = 0;
while (IP < op_list.Count)
{
OP op = op_list[IP];
if (op.op == "Variable")
{
string typename=op.arg1;
if (typename == "int") variables.Add(op.result, new int());
if (typename == "double") variables.Add(op.result, new double());
if (typename == "string") variables.Add(op.result, new string(' ', 1));
if (!typeMapping.ContainsKey(typename))
{
object obj = NewObject(typename, null);
if (obj == null)
{
MessageBox.Show("can new variable of type " + typename);
return;
}
variables.Add(op.result, obj);
}
IP++;
continue;
}
object arg1_obj = 0, arg2_obj = 0;
Type type = null;
if (variables.IndexOfKey(op.result) < 0) variables.Add(op.result, 0);
if (op.arg1 != "")
{
if (CompilerTable.IsDigit(op.arg1))
{
arg1_obj = int.Parse(op.arg1);
}
else
{
arg1_obj = variables[op.arg1];
}
}
if (op.arg2 != "")
{
if (CompilerTable.IsDigit(op.arg2))
arg2_obj = int.Parse(op.arg2);
else if (op.arg2 != "")
arg2_obj = (int)variables[op.arg2];
}
string code = ToCode(IP,op);
if (arg1_obj is int)
{
int arg1 = (int)arg1_obj;
int arg2 = (int)arg2_obj;
if (op.op == "=") variables[op.result] = arg1;
if (op.op == "+") variables[op.result] = arg1 + arg2;
if (op.op == "*") variables[op.result] = arg1 * arg2;
if (op.op == "-") variables[op.result] = arg1 - arg2;
if (op.op == "/") variables[op.result] = arg1 / arg2;
if (op.op == ">") variables[op.result] = Convert.ToInt32(arg1 > arg2);
if (op.op == "<") variables[op.result] = Convert.ToInt32(arg1 < arg2);
if (op.op == ">=") variables[op.result] = Convert.ToInt32(arg1 >= arg2);
if (op.op == "<=") variables[op.result] = Convert.ToInt32(arg1 <= arg2);
if (op.op == "==") variables[op.result] = Convert.ToInt32(arg1 == arg2);
if (op.op == "!=") variables[op.result] = Convert.ToInt32(arg1 != arg2);
if (op.op == "||") variables[op.result] = Convert.ToInt32(arg1 | arg2);
if (op.op == "&&") variables[op.result] = Convert.ToInt32(arg1 & arg2);
}
if (arg1_obj is double)
{
double arg1 = (double)arg1_obj;
double arg2 = (double)arg2_obj;
if (op.op == "=") variables[op.result] = arg1;
if (op.op == "+") variables[op.result] = arg1 + arg2;
if (op.op == "*") variables[op.result] = arg1 * arg2;
if (op.op == "-") variables[op.result] = arg1 - arg2;
if (op.op == "/") variables[op.result] = arg1 / arg2;
if (op.op == ">") variables[op.result] = Convert.ToInt32(arg1 > arg2);
if (op.op == "<") variables[op.result] = Convert.ToInt32(arg1 < arg2);
if (op.op == ">=") variables[op.result] = Convert.ToInt32(arg1 >= arg2);
if (op.op == "<=") variables[op.result] = Convert.ToInt32(arg1 <= arg2);
if (op.op == "==") variables[op.result] = Convert.ToInt32(arg1 == arg2);
if (op.op == "!=") variables[op.result] = Convert.ToInt32(arg1 != arg2);
}
if (arg1_obj is string )
{
string arg1 = (string)arg1_obj;
string arg2 = (string)arg2_obj;
if (op.op == "=") variables[op.result] = arg1;
if (op.op == "+") variables[op.result] = arg1 + arg2;
if (op.op == "==") variables[op.result] = Convert.ToInt32(arg1 == arg2);
if (op.op == "!=") variables[op.result] = Convert.ToInt32(arg1 != arg2);
}
IP++;
if (op.op == "IfGoto")
{
int arg1 = (int)arg1_obj;
if (arg1 > 0) IP = int.Parse(op.result);
}
if (op.op == "Goto")
{
IP = int.Parse(op.result);
}
}
}
public string ToCode(int line, OP op)
{
string code = "(" + line.ToString() + ") ";
if (op.op == "=")
{
return code + op.result + op.op + op.arg1 + "; ";
}
if ((op.op == "+") || (op.op == "-") || (op.op == "*") || (op.op == "/"))
{
return code + op.result + "=" + op.arg1 + op.op + op.arg2 + "; ";
}
if ((op.op == ">") || (op.op == ">=") || (op.op == "<") || (op.op == "<=") || (op.op == "==") || (op.op == "!=") || (op.op == "||")|| (op.op == "&&"))
{
return code + op.result + "=" + op.arg1 + op.op + op.arg2 + "; ";
}
if (op.op == "Variable")
{
return code + " : " + op.op + " " + op.arg1+" "+ op.result + "; ";
}
if (op.op == "Goto")
{
return code + " : " + op.op + op.result + "; ";
}
if (op.op == "IfGoto")
{
return code + " If " + op.arg1.ToString() + " Goto " + op.result + "; ";
}
return "";
}
public string ToCode(List<OP> op_list)
{
string code = "";
int line = 0;
foreach (OP op in op_list)
{
code += ToCode(line++, op);
}
return code;
}
public object GetValue(string name)
{
if(variables.ContainsKey(name)) return variables[name];
return null;
}
}
class Compiler
{
int count = 0;
string[] words;
List<OP> op_list = new List<OP>();
//string code = "int a ; int b , c ; a = a + 10 + b + c ; #";
// string code = "a = a + 10 + b * 10 * 3 + c ; ";
// string code = " int a , b = 5 , c = 4 ; int d , e ; a = 5 ; if ( a + c ) { d = 10 ; d = 5 + 5 : if ( d ) d = 100 ; } else { d = 20 ; d = 10 + 10 ; d = 200 ; } a = 10 + d ; a = a + d ; d = d ; ; ";
// string code = " int a , b = 5 ; a = 5 ; while ( a > 1 ) { a = a - 1 ; b = b + 1 ; } ; ";
string code = " int a , b = 0 , i ; a = 5 ; for ( i = 0 ; i < 10 ; i = i + 1 ) { a = a - 1 ; b = b + 1 ; } ; ";
public Compiler()
{
string[] ss = code.Split(' ');
words = new string[5000];
foreach (string s in ss)
{
if (s.Length > 0) words[count++] = s;
}
count = 0;
//int a = 10;
//int a2 = 10;
//object b = a;
//object b2 = a2;
//object bb = b + b2;
//string s1=b.GetType().ToString();
//string s2 = ((object)a).GetType().ToString();
//object ss1 = s1;
//object ss2 = s2;
//object ss = ss1 + ss2;
Start();
CompilerExcute excute = new CompilerExcute();
string sss = excute.ToCode(op_list);
excute.Excute(op_list);
int aa= (int)excute.GetValue("a");
int bb = (int)excute.GetValue("b");
}
string sym;
string id;
public void Scaner()
{
if (words[count] == null) return;
sym = CompilerTable.Sym(words[count]);
id = words[count];
count++;
}
public void Start()
{
Scaner();
Code();
}
static int _t = 0;
public string NewTemp()
{
return "T" + (_t++).ToString();
}
public int Emit(string opt, string result, string arg1, string arg2)
{
OP op = new OP();
op.op = opt;
op.result = result;
op.arg1 = arg1;
op.arg2 = arg2;
op_list.Add(op);
return op_list.Count - 1;
}
public int Emit(string opt, int result, string arg1, string arg2)
{
return Emit(opt, result.ToString(), arg1, arg2);
}
public string Lookup(string name)
{
return name;
}
// // 产生式如下
//Statement->st{st} //声明变量
//st->int st1{,st1} ;
//st1->i{=i};
//Body->S{S}|{Body} //主体赋值表达式
//Expression->Term{+Term|-Term}
//Term->Factor{*Factor|/Factor}
//Factor->i|(Expression)
//Code->{ Statement} Body //
// >, <, >=, <=, !=, ==, ||, &&
public void Code()
{
Body(0);
}
public void Body(int level)
{
if (sym == "{")
{
Scaner(); // {
Body(level+1);
Scaner(); // }
return;
}
while ((sym == "type") || (sym == "i") || (sym == "if") || (sym == "while") || (sym == "for")) Sentence(level);
}
void backpatch(int index, int address)
{
op_list[index].result = address.ToString();
}
public void Sentence(int level)
{
if (sym == "i") { Assignment(level); return; }
if (sym == "if") { If_Sentence(level); return; }
if (sym == "while") { While_Sentence(level); return; }
if (sym == "for") { For_Sentence(level); return; }
if (sym == "type") { Statement( ); return; }
if (sym == ";") { Scaner(); return; }
}
public void Statement()
{
string typeKind = id;
Scaner();
StatementOne(typeKind);
while (sym == ",")
{
Scaner();
StatementOne(typeKind);
}
Scaner(); // shouble be ;
}
public void StatementOne(string typekind)
{
if (sym != "i") return; //error
string variable = id;
Emit("Variable", variable, typekind, "");
Scaner();
if (sym == "=")
{
Scaner();
//得到初始值
Emit("=", variable, id, "");
Scaner(); //should be , or ;
}
}
public void For_Sentence(int level)
{
Scaner(); // for
Scaner(); // shouble be (
Sentence(level);
int E_Decide=op_list.Count;
String E = LogicExpression();
int E_True=Emit("IfGoto", 0, E, "");
int E_False = Emit("Goto", 0, "", "");
Scaner(); //shouble be ;
int nextLoop = op_list.Count;
Sentence(level);
Scaner(); // shouble be )
Emit("Goto", E_Decide, "", "");
backpatch(E_True, op_list.Count);
Body(level);
Emit("Goto", nextLoop, "", "");
backpatch(E_False, op_list.Count);
}
public void While_Sentence(int level)
{
Scaner();
Scaner(); // shouble be (
int E_decide=op_list.Count;
string E = LogicExpression();
Scaner(); //shouble be )
Emit("IfGoto", op_list.Count + 2, E, "");
int E_false = Emit("Goto", 0, "", "");
Body(level );
Emit("Goto", E_decide,"","");
backpatch(E_false, op_list.Count);
}
public void If_Sentence(int level)
{
Scaner(); //should be if
Scaner(); // shouble be (
string E = LogicExpression();
Scaner(); //shouble be )
Emit("IfGoto", op_list.Count + 2, E, "");
int E_false = Emit("Goto", 0, "", "");
Body(level+1);
int E_True_Done = Emit("Goto", 0, "", "");
backpatch(E_false, op_list.Count);
if (sym == "else")
{
Scaner(); // should be else
Body(level + 1);
}
backpatch(E_True_Done, op_list.Count);
}
public string Assignment(int level)
{
if (sym != "i") return "error"; ;
string A1 = id;
Scaner();
if (sym == "=")
{
Scaner();
Emit("=", A1, Expression(), "");
}
if (sym == ";")
Scaner(); //should be ; but in for loop ,the last sentence has no ; for end
else if (sym != ")")
return "error";
return A1;
}
public string LogicExpression()
{
String L = Expression();
if (sym == "logicOP")
{
string rop = id;
Scaner(); // >
string L2 = Expression();
string temp = NewTemp();
Emit(rop, temp, L, L2);
L = temp;
}
return L;
}
public string Expression()
{
string E1 = Term();
while ((sym == "+") || (sym == "-"))
{
string op = sym;
Scaner();
string E2 = Term();
string temp = NewTemp();
Emit(op, temp, E1, E2);
E1 = temp;
}
return E1;
}
public string Term()
{
string T1 = Factor();
while ((sym == "*") || (sym == "/"))
{
string op = sym;
Scaner();
string T2 = Factor();
string temp = NewTemp();
Emit(op, temp, T1, T2);
T1 = temp;
}
return T1;
}
public string Factor()
{
if (sym == "i")
{
string F1 = id;
Scaner();
return F1;
}
if (sym == "(")
{
Scaner(); // (
string F1 = Expression();
Scaner(); // )
return F1;
}
return "error";
}
}
}