您的位置:首页 > 编程语言 > C#

用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
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: