用C#实现的简单PL0 to C 编译器
2005-12-28 12:33
176 查看
用C#实现的简单PL0 to C编译器
作者:yxin1322
blog:http://blog.csdn.net/yxin1322 转载请注明出处
这个程序是我《编译原理》的期末大作业,要求实现PL0到C语言的编译器,其实叫翻译器更贴切点。程序的实现目标是能把具有基本Pascal语法的pl0语言源程序转换成C语言程序。pl0支持变量定义、条件语句、循环语句、赋值语句,变量的控制台输入与输出。翻译出的C语言程序需能被常见的C编译器编译通过。
本程序分为两大模块:词法分析模块和语法制导翻译及输出模块。
词法分析模块:通过程序指定一个由pl0语言编写的程序源文件,词法分析器能够将源文件内容分解为一组单词序列,并判别每个单词的所属类别(分别有运算符、分界符、关键字、变量名和数字),当遇到非法字符串时,能报出错误发生的位置。如果分析成功而未遇到任何错误,则词法分析器返回给编译程序一个单词集合,以用来做语法分析。每个单词存放在一个WordTableEntry结果中。
词法分析模块代码如下:GETSYM.CS
〈分程序〉∷=[〈常量说明部分〉][〈变量说明部分〉][〈过程说明部分〉]〈语句〉
〈常量说明部分〉∷=CONST〈常量定义〉 {,〈常量定义〉};
〈常量定义〉∷=〈标识符〉=〈无符号整数〉
〈无符号整数〉∷=〈数字〉{〈数字〉}
〈变量说明部分〉∷=VAR〈标识符〉{,〈标识符〉};
〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}
〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉};
〈过程首部〉∷=PROCEDURE〈标识符〉;
〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈当型循环语句〉|
〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉
〈赋值语句〉∷=〈标识符〉∶=〈表达式〉
〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END
〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉|ODD〈表达式〉
〈表达式〉∷=[+|-]〈项〉{〈加法运算符〉〈项〉}
〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}
〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')'
〈加法运算符〉∷=+|-
〈乘法运算符〉∷=*|/
〈关系运算符〉∷=#|=|<|<=|>|>=
〈条件语句〉∷=IF〈条件〉THEN〈语句〉
〈过程调用语句〉∷=CALL〈标识符〉
〈当型循环语句〉∷=WHILE〈条件〉DO〈语句〉
〈读语句〉∷=READ'('〈标识符〉{,〈标识符〉}')'
〈写语句〉∷=WRITE'('〈表达式〉{,〈表达式〉}')'
〈字母〉∷=a|b|…|X|Y|Z
〈数字〉∷=0|1|2|…|8|9 根据EBNF就可以很快写出语法分析和翻译程序,代码如下:
程序打包下载地址:http://free5.ys168.com/?yxin1322
作者:yxin1322
blog:http://blog.csdn.net/yxin1322 转载请注明出处
这个程序是我《编译原理》的期末大作业,要求实现PL0到C语言的编译器,其实叫翻译器更贴切点。程序的实现目标是能把具有基本Pascal语法的pl0语言源程序转换成C语言程序。pl0支持变量定义、条件语句、循环语句、赋值语句,变量的控制台输入与输出。翻译出的C语言程序需能被常见的C编译器编译通过。
本程序分为两大模块:词法分析模块和语法制导翻译及输出模块。
词法分析模块:通过程序指定一个由pl0语言编写的程序源文件,词法分析器能够将源文件内容分解为一组单词序列,并判别每个单词的所属类别(分别有运算符、分界符、关键字、变量名和数字),当遇到非法字符串时,能报出错误发生的位置。如果分析成功而未遇到任何错误,则词法分析器返回给编译程序一个单词集合,以用来做语法分析。每个单词存放在一个WordTableEntry结果中。
词法分析模块代码如下:GETSYM.CS
1 /* 2 code by: yxin1322 3 date: 2005.6 4 blog: http://blog.csdn.net/yxin1322 5 Email: yxin1322@gmail.com 6 */ 7 8 9 using System; 10 using System.Collections; 11 using System.Text.RegularExpressions; 12 using System.IO; 13 14 namespace GETSYM 15 { 16 /// <summary> 17 /// 词法分析器类 18 /// </summary> 19 public class GETSYM 20 { 21 public static string[] OperatorList={"+","-","*","/",":=","#", 22 ">=","<=","<",">","=","&&","||"}; //运算符列表,可以扩充 23 public static string[] Bound_OperatorList={",",".",";","(",")"}; //分界符列表,可以扩充 24 public static string[] Reserved_WordsList= 25 {"CONST","VAR","PROCEDURE","BEGIN","END","ODD","IF", 26 CALL","WHILE","READ","DO","WRITE","THEN"}; //关键字列表,可以扩充 27 28 29 public ArrayList WordTable; //存储词法分析后的单词列表,列表的元素是WordTableEntry的对象 30 private string pl0FilePath; //存储需要分析的pl0源文件路径 31 32 //默认构造函数 33 public GETSYM() 34 { 35 WordTable=new ArrayList(); 36 PL0FilePath=""; 37 } 38 39 //初始化文件路径的构造函数 40 public GETSYM(string filepath) 41 { 42 WordTable=new ArrayList(); 43 PL0FilePath=filepath; 44 } 45 46 //属性 47 public string PL0FilePath 48 { 49 get{return pl0FilePath;} 50 set{pl0FilePath=value;} 51 } 52 53 //将分析好的单词表写入文件 54 public void WriteSYMToFile() 55 { 56 if(pl0FilePath.Equals("")) 57 { 58 System.Console.WriteLine("Unknown output file name!"); 59 return ; 60 } 61 62 string temfilename=Regex.Replace(PL0FilePath,@"./w+$",""); 63 string OutPutFileName=temfilename+".SYM"; 64 65 System.IO.StreamWriter sw=null;//创建输出文件 66 67 sw=File.CreateText(OutPutFileName); 68 69 sw.WriteLine("//------------------------------------------------------------"); 70 sw.WriteLine("//pl0语言词法分析器 v0.2 Copyright 2005 yxin1322"); 71 sw.WriteLine("//单词表创建自文件[{0}]",pl0FilePath); 72 sw.WriteLine("//生成时间:{0}",System.DateTime.Now.ToString()); 73 sw.WriteLine("//------------------------------------------------------------"); 74 75 System.Console.WriteLine("/n生成单词表.../n"); 76 for(int i=0;i<WordTable.Count;i++) 77 { 78 sw.WriteLine("{0,15}: {1,-15}",((WordTableEntry)WordTable[i]).WordType.ToString(), 79 ((WordTableEntry)WordTable[i]).Word); 80 } 81 sw.Close(); 82 83 System.Console.WriteLine("已经将单词写入文件:{0}",OutPutFileName); 84 } 85 86 //对pl0源文件进行分析,划分出单词并分析其类别,存储进WoedTable 87 public bool getSYM() 88 { 89 System.Console.WriteLine("------------------------------------------------------------"); 90 System.Console.WriteLine("[pl0语言词法分析器 v0.2] Copyright 2005 yxin1322"); 91 System.Console.WriteLine("------------------------------------------------------------"); 92 93 ArrayList ErrorList=new ArrayList(); 94 if(pl0FilePath.Equals("")) 95 { 96 System.Console.WriteLine("你没有指定源文件!"); 97 return false; 98 } 99 if(!File.Exists(pl0FilePath)) 100 { 101 System.Console.WriteLine("找不到指定源文件!"); 102 return false; 103 } 104 else 105 { 106 System.Console.WriteLine("正在对文件内容进行词法分析..."); 107 StreamReader sr=File.OpenText(PL0FilePath); 108 109 int LineNum=0; //对当前分析的行进行记数 110 string Line=sr.ReadLine();//读入第一行 111 112 LineNum++; 113 while(Line!=null) 114 { 115 if(Regex.IsMatch(Line,@"^//")) //忽略注释 116 { 117 Line=sr.ReadLine(); 118 LineNum++; 119 } 120 121 else 122 { 123 Line=Regex.Replace(Line,@"//.*$",""); 124 125 for(int i=0;i<OperatorList.Length;i++) //对运算符和界符两边添加空格 126 Line=Line.Replace(OperatorList[i]," "+OperatorList[i]+" "); 127 for(int i=0;i<Bound_OperatorList.Length;i++) 128 Line=Line.Replace(Bound_OperatorList[i]," "+Bound_OperatorList[i]+" "); 129 130 Line=Regex.Replace(Line,@"/s+"," ");//将多个空格替换成一个空格 131 Line=Line.Trim(); //去掉一行两边的空格 132 133 string [] WordSplit=Regex.Split(Line," ");//用空格分割字符串 134 for(int k=0;k<WordSplit.Length;k++)//遍历分割后的字符串 135 { 136 string str1=WordSplit[k]; 137 string str2=(k<WordSplit.Length-1)?WordSplit[k+1]:""; 138 139 if(str1.Equals("")) 140 continue; 141 if(GETSYM.IsOperator(ref str1,str2,ref k)) 142 WordTable.Add(new WordTableEntry(Word_Type.Operator,str1)); 143 else if(GETSYM.IsNumber(str1)) 144 WordTable.Add(new WordTableEntry(Word_Type.Number,str1)); 145 else if(GETSYM.IsBound_Operator(str1)) 146 WordTable.Add(new WordTableEntry(Word_Type.Bound_Operator,str1)); 147 else if(GETSYM.IsReserved_Words(str1)) 148 WordTable.Add(new WordTableEntry(Word_Type.Reserved_Words,str1)); 149 else if(GETSYM.IsIdentifier(str1)) 150 WordTable.Add(new WordTableEntry(Word_Type.Identifier,str1)); 151 else 152 { 153 string error="Error Accur in Line:"+LineNum+" '"+str1+"'不是合法的单词"; 154 ErrorList.Add(error); 155 } 156 157 } 158 159 // System.Console.WriteLine(Line); 160 Line=sr.ReadLine(); 161 LineNum++; 162 } 163 164 } 165 sr.Close(); 166 } 167 if(ErrorList.Count==0) 168 return true; 169 else 170 { 171 for(int i=0;i<ErrorList.Count;i++) 172 Console.WriteLine((string)ErrorList[i]); 173 return false; 174 } 175 } 176 177 public static bool IsBound_Operator(string a) 178 { 179 foreach(string str in Bound_OperatorList) 180 { 181 if(a.Equals(str)) 182 return true; 183 } 184 return false; 185 } 186 187 public static bool IsOperator(ref string a,string b,ref int c) 188 { 189 string tem=a+b; 190 foreach(string str in OperatorList) 191 { 192 if(tem.Equals(str)) 193 { 194 a=a+b; 195 c++; 196 return true; 197 } 198 } 199 foreach(string str in OperatorList) 200 { 201 if(a.Equals(str)) 202 return true; 203 } 204 return false; 205 206 } 207 208 public static bool IsReserved_Words(string a) 209 { 210 foreach(string str in Reserved_WordsList) 211 { 212 if((a.ToUpper()).Equals(str)) 213 return true; 214 } 215 return false; 216 } 217 218 public static bool IsNumber(string str) 219 { 220 Regex r=new Regex(@"^/d+$"); 221 if(r.IsMatch(str)) 222 return true; 223 else 224 return false; 225 } 226 public static bool IsIdentifier(string str) 227 { 228 Regex r=new Regex(@"^[a-zA-Z][a-zA-Z0-9]*$"); 229 if(r.IsMatch(str)) 230 return true; 231 else 232 return false; 233 234 } 235 236 } 237 }WordTableEntry.CS
1 /* code by: yxin1322 2 date: 2005.6 3 blog: http://blog.csdn.net/yxin1322 4 Email: yxin1322@gmail.com 5 */ 6 7 using System; 8 9 //字符串类型定义 10 public enum Word_Type{Reserved_Words,Number,Operator,Bound_Operator,Identifier,other} 11 namespace GETSYM 12 { 13 14 15 /// <summary> 16 /// WordTalbeEntry定义一个词汇表的节点 17 /// </summary> 18 public class WordTableEntry 19 { 20 21 22 23 private Word_Type wordtype;//单词种类 24 private string word;//单词值 25 26 public WordTableEntry() //默认构造函数 27 { 28 wordtype=Word_Type.other; 29 word=""; 30 } 31 32 public WordTableEntry(Word_Type a,string b)//带参数的构造函数 33 { 34 wordtype=a; 35 word=b; 36 } 37 38 public string Word //属性 39 { 40 get 41 { 42 return word; 43 } 44 set 45 { 46 word=value; 47 } 48 } 49 50 public Word_Type WordType //属性 51 { 52 get 53 { 54 return wordtype; 55 } 56 set 57 { 58 wordtype=value; 59 } 60 } 61 62 63 } 64 }语法制导翻译及输出模块:为了翻译的简便,我采用了语法制导翻译的方式,即一边进行语法分析,一边将pl0语言翻译成C语言,若遇到语法错误则停止翻译,报告错误。在实现方式上采用了递归子程序法,递归子程序法简单直观,只要分析出了pl0语言的语法范式(EBNF),就能为每个范式构造对应的子程序。这里我已经得到了pl0语言的EBNF,如下: 〈程序〉∷=〈分程序〉.
〈分程序〉∷=[〈常量说明部分〉][〈变量说明部分〉][〈过程说明部分〉]〈语句〉
〈常量说明部分〉∷=CONST〈常量定义〉 {,〈常量定义〉};
〈常量定义〉∷=〈标识符〉=〈无符号整数〉
〈无符号整数〉∷=〈数字〉{〈数字〉}
〈变量说明部分〉∷=VAR〈标识符〉{,〈标识符〉};
〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}
〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉};
〈过程首部〉∷=PROCEDURE〈标识符〉;
〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈当型循环语句〉|
〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉
〈赋值语句〉∷=〈标识符〉∶=〈表达式〉
〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END
〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉|ODD〈表达式〉
〈表达式〉∷=[+|-]〈项〉{〈加法运算符〉〈项〉}
〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}
〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')'
〈加法运算符〉∷=+|-
〈乘法运算符〉∷=*|/
〈关系运算符〉∷=#|=|<|<=|>|>=
〈条件语句〉∷=IF〈条件〉THEN〈语句〉
〈过程调用语句〉∷=CALL〈标识符〉
〈当型循环语句〉∷=WHILE〈条件〉DO〈语句〉
〈读语句〉∷=READ'('〈标识符〉{,〈标识符〉}')'
〈写语句〉∷=WRITE'('〈表达式〉{,〈表达式〉}')'
〈字母〉∷=a|b|…|X|Y|Z
〈数字〉∷=0|1|2|…|8|9 根据EBNF就可以很快写出语法分析和翻译程序,代码如下:
1 /*------------------------------------------------------------ 2 <pl0 to C Convertor v0.1> Copyright 2005 3 code by: yxin1322 4 date: 2005.6 5 blog: http://blog.csdn.net/yxin1322 6 Email: yxin1322@gmail.com 7 运行环境:.Net FrameWork 1.1 8 --------------------------------------------------------------*/ 9 10 using System; 11 using System.Collections; 12 using System.IO; 13 using System.Text.RegularExpressions; 14 using GETSYM; 15 16 namespace Pascal_to_C_Convertor 17 { 18 /// <summary> 19 /// Pascal_to_C 的摘要说明。 20 /// 进行Pascal到C转换的实现类 21 /// </summary> 22 public class Pascal_to_C 23 { 24 private string pascal_file_name;//pascal源文件名 25 static private int word_count;//分析pascal单词表的记数器 26 private ArrayList pascal_word_table; 27 public ArrayList C_Source;//存储转换好的C语言源程序 28 public ArrayList ErrorList; 29 30 31 public Pascal_to_C() 32 { 33 this.pascal_file_name=""; 34 word_count=-1;//初始值为-1 35 this.pascal_word_table=new ArrayList(); 36 this.C_Source=new ArrayList(); 37 this.ErrorList=new ArrayList(); 38 39 } 40 41 public Pascal_to_C(string filename) 42 { 43 this.PascalFileName=filename; 44 word_count=-1;//初始值为-1 45 this.pascal_word_table=new ArrayList(); 46 this.C_Source=new ArrayList(); 47 this.ErrorList=new ArrayList(); 48 } 49 50 public string PascalFileName 51 { 52 get{return this.pascal_file_name;} 53 set{this.pascal_file_name=value;} 54 } 55 56 //获得分解好的PASCAL单词表 57 private ArrayList LoadWordTableFromFile() 58 { 59 GETSYM.GETSYM gs=new GETSYM.GETSYM(this.PascalFileName); 60 if(gs.getSYM()) 61 return gs.WordTable; 62 else 63 return null; 64 } 65 66 public bool CreateCSourceCode() 67 { 68 this.pascal_word_table=this.LoadWordTableFromFile();//得到pl0单词表 69 70 if(this.pascal_word_table==null)//词法分析出错 71 { 72 return false; 73 } 74 this.pascal_word_table.Add(new WordTableEntry(Word_Type.other,"####"));//添加单词表尾 75 76 WordTableEntry w=this.getNextWord(); 77 78 System.Console.WriteLine("/n正在进行语法分析..."); 79 80 this.Program(ref w); //调用递归分析程序 81 if(word_count==this.pascal_word_table.Count-1 && ErrorList.Count==0) 82 { 83 return true; 84 } 85 else 86 { 87 this.PrintErrorList();//打印错误列表 88 return false; 89 } 90 } 91 92 //得到pascal单词表的下一个单词 93 private WordTableEntry getNextWord() 94 { 95 word_count++; 96 return ((WordTableEntry)this.pascal_word_table[word_count]); 97 } 98 99 //递归子程序从次开始 100 101 //"程序"递归程序 102 //〈程序〉∷=〈分程序〉. 103 private void Program(ref WordTableEntry w) 104 { 105 Subprogram(ref w); 106 if(!w.Word.Equals(".")) 107 { 108 ErrorList.Add("分程序结束期待一个."); 109 } 110 else 111 { 112 this.C_Source.Add("/n"); 113 114 w=this.getNextWord(); 115 } 116 117 } 118 119 //"分程序"递归程序 120 //〈分程序〉∷=[〈常量说明部分〉][〈变量说明部分〉][〈过程说明部分〉]〈语句〉 121 private void Subprogram(ref WordTableEntry w) 122 { 123 if(w.Word.ToUpper().Equals("CONST")) 124 this.ConstValueExplain(ref w); 125 if(w.Word.ToUpper().Equals("VAR")) 126 this.VariableExplain(ref w); 127 if(w.Word.ToUpper().Equals("PROCEDURE")) 128 this.ProcedureExplain(ref w); 129 this.Sentence(ref w); 130 131 } 132 133 //"常量说明部分"递归程序 134 //〈常量说明部分〉∷=CONST〈常量定义〉 {,〈常量定义〉}; 135 private void ConstValueExplain(ref WordTableEntry w) 136 { 137 if(w.Word.ToUpper().Equals("CONST")) 138 { 139 this.C_Source.Add("const int"); 140 141 w=this.getNextWord(); 142 this.ConstValue(ref w); 143 while(w.Word.ToUpper().Equals(",")) 144 { 145 this.C_Source.Add(","); 146 147 w=this.getNextWord(); 148 this.ConstValue(ref w); 149 } 150 if(!w.Word.Equals(";")) 151 { 152 ErrorList.Add("常量定义后没有加分号!"); 153 } 154 else 155 { 156 this.C_Source.Add(";/n"); 157 w=this.getNextWord(); 158 } 159 160 } 161 } 162 163 //"常量定义"递归程序 164 //〈常量定义〉∷=〈标识符〉=〈无符号整数〉 165 private void ConstValue(ref WordTableEntry w) 166 { 167 this.Identifier(ref w); 168 169 if(w.Word.Equals("=")) 170 { 171 this.C_Source.Add("="); 172 173 w=this.getNextWord(); 174 this.UnsignedNumber(ref w); 175 } 176 else 177 { 178 this.ErrorList.Add("变量定义缺少等号!"); 179 } 180 } 181 182 //"无符号整数"递归程序 183 //〈无符号整数〉∷=〈数字〉{〈数字〉} 184 private void UnsignedNumber(ref WordTableEntry w) 185 { 186 if(w.WordType==Word_Type.Number) 187 { 188 this.C_Source.Add(w.Word); 189 190 w=this.getNextWord(); 191 } 192 else 193 ErrorList.Add("期望一个无符号整数!"); 194 } 195 196 //"变量说明部分"递归程序 197 //〈变量说明部分〉∷=VAR〈标识符〉{,〈标识符〉}; 198 private void VariableExplain(ref WordTableEntry w) 199 { 200 if(w.Word.ToUpper().Equals("VAR")) 201 { 202 this.C_Source.Add("int"); 203 204 w=this.getNextWord(); 205 this.Identifier(ref w); 206 while(w.Word.ToUpper().Equals(",")) 207 { 208 this.C_Source.Add(","); 209 210 w=this.getNextWord(); 211 this.Identifier(ref w); 212 } 213 if(!w.Word.Equals(";")) 214 { 215 ErrorList.Add("变量定义后没有加分号!"); 216 } 217 else 218 { 219 this.C_Source.Add(";/n"); 220 221 w=this.getNextWord(); 222 } 223 224 } 225 } 226 227 //"标识符"递归程序 228 //〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉} 229 private void Identifier(ref WordTableEntry w) 230 { 231 if (w.WordType==Word_Type.Identifier) 232 { 233 this.C_Source.Add(w.Word); 234 235 w=this.getNextWord(); 236 } 237 else 238 { 239 ErrorList.Add("期望一个标识符!"); 240 } 241 } 242 243 //"过程说明部分"递归程序 244 //〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉}; 245 private void ProcedureExplain(ref WordTableEntry w) 246 { 247 this.ProcedureHead(ref w); 248 249 this.C_Source.Add("{"); 250 251 this.Subprogram(ref w); 252 while(w.Word.Equals(";")) 253 { 254 this.C_Source.Add(";/n"); 255 256 w=this.getNextWord(); 257 this.ProcedureExplain(ref w); 258 } 259 if (!w.Word.Equals(";")) 260 { 261 ErrorList.Add("过程的结束没有加分号!"); 262 } 263 else 264 { 265 this.C_Source.Add(";}/n"); 266 267 w=this.getNextWord(); 268 } 269 } 270 271 //"过程首部"递归程序 272 //〈过程首部〉∷=PROCEDURE〈标识符〉; 273 private void ProcedureHead(ref WordTableEntry w) 274 { 275 if(w.Word.ToUpper().Equals("PROCEDURE")) 276 { 277 this.C_Source.Add("void"); 278 279 w=this.getNextWord(); 280 this.Identifier(ref w); 281 if (!w.Word.Equals(";")) 282 { 283 ErrorList.Add("过程名后缺少分号!"); 284 } 285 else 286 { 287 this.C_Source.Add("()/n"); 288 w=this.getNextWord(); 289 } 290 } 291 else 292 ErrorList.Add("过程需要从关键字PROCEDURE开始!"); 293 } 294 295 //"语句"递归程序 296 //〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈当型循环语句〉|〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉 297 private void Sentence(ref WordTableEntry w) 298 { 299 if (w.WordType==Word_Type.Identifier) 300 { 301 this.EvaluateSentence(ref w); 302 } 303 else if (w.Word.ToUpper().Equals("IF")) 304 { 305 this.ConditionSentence(ref w); 306 } 307 else if (w.Word.ToUpper().Equals("WHILE")) 308 { 309 this.WhileSentence(ref w); 310 } 311 else if (w.Word.ToUpper().Equals("CALL")) 312 { 313 this.WhileSentence(ref w); 314 } 315 else if (w.Word.ToUpper().Equals("READ")) 316 { 317 this.ReadSentence(ref w); 318 } 319 else if (w.Word.ToUpper().Equals("WRITE")) 320 { 321 this.WriteSentence(ref w); 322 } 323 else if (w.Word.ToUpper().Equals("BEGIN")) 324 { 325 this.ComplexSentence(ref w); 326 } 327 else 328 { 329 ; 330 } 331 } 332 333 //"赋值语句"递归程序 334 //〈赋值语句〉∷=〈标识符〉∶=〈表达式〉 335 private void EvaluateSentence(ref WordTableEntry w) 336 { 337 this.Identifier(ref w); 338 if (w.Word.Equals(":=")) 339 { 340 this.C_Source.Add("="); 341 342 w=this.getNextWord(); 343 this.Expression(ref w); 344 } 345 else 346 ErrorList.Add("赋值语句缺少等号!"); 347 } 348 349 //"复合语句"递归程序 350 //〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END 351 private void ComplexSentence(ref WordTableEntry w) 352 { 353 if (w.Word.ToUpper().Equals("BEGIN")) 354 { 355 this.C_Source.Add("{/n"); 356 357 w=this.getNextWord(); 358 this.Sentence(ref w); 359 while(w.Word.Equals(";")) 360 { 361 this.C_Source.Add(";/n"); 362 363 w=this.getNextWord(); 364 this.Sentence(ref w); 365 } 366 367 this.C_Source.Add(";/n"); 368 369 if (!w.Word.ToUpper().Equals("END")) 370 { 371 ErrorList.Add("缺少END标识符!"); 372 } 373 else 374 { 375 this.C_Source.Add("}/n"); 376 377 w=this.getNextWord(); 378 } 379 } 380 381 } 382 383 //"条件"递归程序 384 //〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉|ODD〈表达式〉 385 private void Condition(ref WordTableEntry w) 386 { 387 if ((w.Word.Equals("+") || w.Word.Equals("-")) || w.WordType==Word_Type.Identifier) 388 { 389 this.Expression(ref w); 390 this.RelationSymbol(ref w); 391 this.Expression(ref w); 392 } 393 else if (w.Word.ToUpper().Equals("ODD")) 394 { 395 this.C_Source.Add("("); 396 397 w=this.getNextWord(); 398 this.Expression(ref w); 399 400 this.C_Source.Add(")%2==1"); 401 } 402 else 403 ErrorList.Add("条件表达式错误!"); 404 } 405 406 //"表达式"递归程序 407 //〈表达式〉∷=[+|-]〈项〉{〈加法运算符〉〈项〉} 408 private void Expression(ref WordTableEntry w) 409 { 410 if (w.Word.Equals("+")) 411 { 412 this.C_Source.Add("+"); 413 414 w=this.getNextWord(); 415 } 416 else if (w.Word.Equals("-")) 417 { 418 this.C_Source.Add("-"); 419 420 w=this.getNextWord(); 421 } 422 else 423 { 424 ; 425 } 426 this.ExpressionItem(ref w); 427 while (w.Word.Equals("+") || w.Word.Equals("-")) 428 { 429 this.AdditiveSymbol(ref w); 430 this.ExpressionItem(ref w); 431 } 432 } 433 434 //"项"递归程序 435 //〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉} 436 private void ExpressionItem(ref WordTableEntry w) 437 { 438 this.Gene(ref w); 439 while (w.Word.Equals("*") || w.Word.Equals("/")) 440 { 441 this.MultiplicativeSymbol(ref w); 442 this.Gene(ref w); 443 } 444 } 445 446 //"因子"递归程序 447 //〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')' 448 private void Gene(ref WordTableEntry w) 449 { 450 if (w.WordType==Word_Type.Identifier) 451 { 452 453 this.Identifier(ref w); 454 } 455 else if (w.WordType==Word_Type.Number) 456 { 457 458 this.UnsignedNumber(ref w); 459 } 460 else if (w.Word.Equals("(")) 461 { 462 this.C_Source.Add("("); 463 464 w=this.getNextWord(); 465 this.Expression(ref w); 466 if (!w.Word.Equals(")")) 467 { 468 ErrorList.Add("表达式括号不匹配!"); 469 } 470 else 471 { 472 this.C_Source.Add(")"); 473 474 w=this.getNextWord(); 475 } 476 } 477 else 478 ErrorList.Add("表达式错误!"); 479 } 480 481 //"加法运算符"递归程序 482 //〈加法运算符〉∷=+|- 483 private void AdditiveSymbol(ref WordTableEntry w) 484 { 485 if (w.Word.Equals("+") || w.Word.Equals("-")) 486 { 487 this.C_Source.Add(w.Word); 488 489 w=this.getNextWord(); 490 } 491 else 492 ErrorList.Add("缺少加减法运算符!"); 493 } 494 495 //"乘法运算符"递归程序 496 //〈乘法运算符〉∷=*|/ 497 private void MultiplicativeSymbol(ref WordTableEntry w) 498 { 499 if (w.Word.Equals("*") || w.Word.Equals("/")) 500 { 501 this.C_Source.Add(w.Word); 502 503 w=this.getNextWord(); 504 } 505 else 506 ErrorList.Add("缺少乘除法运算符!"); 507 } 508 509 //"关系运算符"递归程序 510 //〈关系运算符〉∷=#|=|<|<=|>|>= 511 private void RelationSymbol(ref WordTableEntry w) 512 { 513 if (w.Word.Equals("#") || w.Word.Equals("=")) 514 { 515 this.C_Source.Add(w.Word); 516 517 w=this.getNextWord(); 518 } 519 else if (w.Word.Equals("<") || w.Word.Equals("<=")) 520 { 521 this.C_Source.Add(w.Word); 522 523 w=this.getNextWord(); 524 } 525 else if (w.Word.Equals(">") || w.Word.Equals(">=")) 526 { 527 this.C_Source.Add(w.Word); 528 529 w=this.getNextWord(); 530 } 531 else 532 ErrorList.Add("缺少关系运算符!"); 533 } 534 535 //"条件语句"递归程序 536 //〈条件语句〉∷=IF〈条件〉THEN〈语句〉 537 private void ConditionSentence(ref WordTableEntry w) 538 { 539 if (w.Word.ToUpper().Equals("IF")) 540 { 541 this.C_Source.Add("if("); 542 543 w=this.getNextWord(); 544 this.Condition(ref w); 545 546 this.C_Source.Add(")/n"); 547 548 if (w.Word.ToUpper().Equals("THEN")) 549 { 550 this.C_Source.Add("{/n"); 551 552 w=this.getNextWord(); 553 this.Sentence(ref w); 554 555 this.C_Source.Add(";/n}/n"); 556 } 557 else 558 ErrorList.Add("IF语句缺少THEN子句!"); 559 } 560 else 561 ErrorList.Add("条件语句缺少IF!"); 562 } 563 564 //"过程调用语句"递归程序 565 //〈过程调用语句〉∷=CALL〈标识符〉 566 private void ProcedureCall(ref WordTableEntry w) 567 { 568 if(w.Word.ToUpper().Equals("CALL")) 569 { 570 w=this.getNextWord(); 571 this.Identifier(ref w); 572 573 this.C_Source.Add("();/n"); 574 } 575 576 } 577 578 //"当型循环语句"递归程序 579 //〈当型循环语句〉∷=WHILE〈条件〉DO〈语句〉 580 private void WhileSentence(ref WordTableEntry w) 581 { 582 if (w.Word.ToUpper().Equals("WHILE")) 583 { 584 this.C_Source.Add("while("); 585 586 w=this.getNextWord(); 587 this.Condition(ref w); 588 589 this.C_Source.Add(")/n"); 590 591 if (w.Word.ToUpper().Equals("DO")) 592 { 593 this.C_Source.Add("{/n"); 594 595 w=this.getNextWord(); 596 this.Sentence(ref w); 597 598 this.C_Source.Add(";/n}/n"); 599 } 600 else 601 ErrorList.Add("WHILE语句缺少DO子句!"); 602 } 603 else 604 ErrorList.Add("循环语句缺少WHILE!"); 605 } 606 607 //"读语句"递归程序 608 //〈读语句〉∷=READ'('〈标识符〉{,〈标识符〉}')' 609 private void ReadSentence(ref WordTableEntry w) 610 { 611 if (w.Word.ToUpper().Equals("READ")) 612 { 613 w=this.getNextWord(); 614 if (w.Word.Equals("(")) 615 { 616 w=this.getNextWord(); 617 618 this.C_Source.Add("scanf(/"%d/",&"); 619 620 this.Identifier(ref w); 621 this.C_Source.Add(");/n"); 622 623 while (w.Word.Equals(",")) 624 { 625 this.C_Source.Add("scanf(/"%d/",&"); 626 627 w=this.getNextWord(); 628 this.Identifier(ref w); 629 630 this.C_Source.Add(")"); 631 632 } 633 if (!w.Word.Equals(")")) 634 { 635 ErrorList.Add("READ语句括号不匹配!"); 636 } 637 else 638 w=this.getNextWord(); 639 } 640 else 641 ErrorList.Add("READ语句缺少左括号!"); 642 } 643 } 644 645 //"写语句"递归程序 646 //〈写语句〉∷=WRITE'('〈表达式〉{,〈表达式〉}')' 647 private void WriteSentence(ref WordTableEntry w) 648 { 649 if (w.Word.ToUpper().Equals("WRITE")) 650 { 651 w=this.getNextWord(); 652 if (w.Word.Equals("(")) 653 { 654 this.C_Source.Add("printf(/"%d//n/","); 655 656 w=this.getNextWord(); 657 this.Expression(ref w); 658 659 this.C_Source.Add(");/n"); 660 661 while (w.Word.Equals(",")) 662 { 663 this.C_Source.Add("printf(/"%d//n/","); 664 665 w=this.getNextWord(); 666 this.Expression(ref w); 667 668 this.C_Source.Add(")"); 669 } 670 if (!w.Word.Equals(")")) 671 { 672 ErrorList.Add("WRITE语句括号不匹配!"); 673 } 674 else 675 w=this.getNextWord(); 676 } 677 else 678 ErrorList.Add("WRITE语句缺少左括号!"); 679 } 680 } 681 682 //***************递归子程序到此结束 683 684 //打印错误列表 685 private void PrintErrorList() 686 { 687 System.Console.WriteLine("/n-------------ErrorList-------------"); 688 if(ErrorList.Count==0) 689 System.Console.WriteLine("没有错误发生,编译顺利完成!"); 690 for(int i=0;i<ErrorList.Count;i++) 691 { 692 System.Console.WriteLine("[error{0}]:{1}",i,(string)ErrorList[i]); 693 } 694 } 695 696 //将转换好的c语言源程序写如文件 697 private void SaveToCFile() 698 { 699 if(this.PascalFileName.Equals("")) 700 { 701 System.Console.WriteLine("Unknown output file name!"); 702 return ; 703 } 704 705 string temfilename=Regex.Replace(this.PascalFileName,@"./w+$",""); 706 string OutPutFileName=temfilename+".C"; 707 708 System.IO.StreamWriter sw=null;//创建输出文件 709 710 sw=File.CreateText(OutPutFileName); 711 712 sw.WriteLine("/*------------------------------------------------------------"); 713 sw.WriteLine(" pl0 to C Convertor v0.1 Copyright 2005 yxin1322"); 714 sw.WriteLine(" C Source File: [{0}]",this.PascalFileName); 715 sw.WriteLine(" Create Time:{0}",System.DateTime.Now.ToString()); 716 sw.WriteLine(" ------------------------------------------------------------*/"); 717 718 System.Console.WriteLine("/n正在写入文件.../n"); 719 720 sw.WriteLine("#include <stdio.h>");//添加c文件头部 721 sw.WriteLine("main()/n{"); 722 723 724 for(int i=0;i<this.C_Source.Count;i++) 725 { 726 sw.Write("{0} ",this.C_Source[i]); 727 } 728 sw.WriteLine("}"); 729 sw.Close(); 730 731 732 System.Console.WriteLine("已经将C源程序写入文件:{0}",OutPutFileName); 733 } 734 735 public static void Main(string[] args) 736 { 737 string pl0FileName; 738 if(args.Length==0) 739 { 740 System.Console.WriteLine(" ------------------------------------------------------------"); 741 System.Console.WriteLine(" <pl0 to C Convertor v0.1> Copyright 2005 yxin1322/n"); 742 System.Console.WriteLine(" 运行环境:.Net FrameWork 1.1"); 743 System.Console.WriteLine(" ------------------------------------------------------------"); 744 745 System.Console.Write("请输入pl0文件的路径及文件名(*.pl0):"); 746 pl0FileName=System.Console.ReadLine(); 747 } 748 else 749 { 750 pl0FileName=args[0]; 751 } 752 753 System.Console.WriteLine(pl0FileName); 754 Pascal_to_C p2c=new Pascal_to_C(pl0FileName); 755 756 if(p2c.CreateCSourceCode()) 757 p2c.SaveToCFile(); 758 759 System.Console.ReadLine(); 760 } 761 } 762 }
程序打包下载地址:http://free5.ys168.com/?yxin1322
相关文章推荐
- (fujie724) C#:简单实现动态数据生成Word文档并保存
- C#前期绑定和后期绑定操作Excel-------实现简单打印功能
- 用C#简单的实现双色球抽奖
- 使用C#链表简单实现的约瑟夫环
- 使用C#开发HTTP服务器系列之更简单的实现方式
- c#实现为程序绑定电脑简单实现方法
- c# 判断指定文件是否存在的简单实现
- C#中使用Socket实现简单Web服务器
- [C# 网络编程系列]专题十:实现简单的邮件收发器
- 学习C#从俄罗斯方块开始(二)俄罗斯方块的规则和算法的简单实现
- 根据权重随机选取指定条数记录的简单算法实现(C#)【含源代码】
- C++标准 bind函数用法与C#简单实现
- 简单实现C#生成Excel 2007文件并下载
- 实现一个简单的编译器
- python在线编译器的简单原理及简单实现代码
- C#的局域网聊天软件的简单实现
- c#利用反射+特性实现简单的实体映射数据库操作类实现自动增删改查(三)带源码写好的持久层
- js 模拟实现类似c#下的hashtable的简单功能代码
- Wed页动态下拉菜单-----C#简单实现
- C#播放铃声最简单实现方法