用C#实现的简单PL0 to C 编译器

时间:2021-12-02 07:36:46
 用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: yxin13222                date: 2005.63                blog: http://blog.csdn.net/yxin13224               Email: yxin1322@gmail.com5    */6    7    using System;8    9    //字符串类型定义10    public enum Word_Type{Reserved_Words,Number,Operator,Bound_Operator,Identifier,other}11    namespace GETSYM12    {13    14    15    /// <summary>16    /// WordTalbeEntry定义一个词汇表的节点17    /// </summary>18    public class WordTableEntry19    {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    get41    {42    return word;43    }44    set45    {46    word=value;47    }48    }49    50    public Word_Type WordType //属性51    {52    get53    {54    return wordtype;55    }56    set57    {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 20053             code by: yxin13224                date: 2005.65                blog: http://blog.csdn.net/yxin13226               Email: yxin1322@gmail.com7      运行环境:.Net FrameWork 1.18    --------------------------------------------------------------*/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_Convertor17    {18    /// <summary>19    /// Pascal_to_C 的摘要说明。20    /// 进行Pascal到C转换的实现类21    /// </summary>22    public class Pascal_to_C23    {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;//初始值为-135    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;//初始值为-145    this.pascal_word_table=new ArrayList();46    this.C_Source=new ArrayList();47    this.ErrorList=new ArrayList();48    }49    50    public string PascalFileName51    {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    else63    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    else86    {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    else111    {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    else155    {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    else177    {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    else193    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    else218    {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    else238    {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    else264    {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    else286    {287    this.C_Source.Add("()/n");288    w=this.getNextWord();289    }290    }291    else292    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    else328    {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    else346    ErrorList.Add("赋值语句缺少等号!");347    }348    349    //"复合语句"递归程序350    //〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END351    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    else374    {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    else403    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    else423    {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    else471    {472    this.C_Source.Add(")");473    474    w=this.getNextWord();475    }476    }477    else478    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    else492    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    else506    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    else532    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    else558    ErrorList.Add("IF语句缺少THEN子句!");559    }560    else561    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    else601    ErrorList.Add("WHILE语句缺少DO子句!");602    }603    else604    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    else638    w=this.getNextWord();639    }640    else641    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    else675    w=this.getNextWord();676    }677    else678    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    else749    {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