⽂法分析之终结符和⾮终结符
经过⼀夜的努⼒,终于将终结符和⾮终结符区分问题搞定了。其实在判断过程中困难的不是区分终结符和⾮终结符,⽽是判断⼀个⽂法描述,是不是正确的,⽐如这个描述是否符合格式规则、内容的判断等。我只对描述是否符合规则进⾏了判断。在这个过程中使⽤了正则表达式。⽂法开始判断是在前⾯已经写过了。今天讲⼀讲⽂法格式的判断。
这个格式判断也就是从格式就⾏判断,⽐如格式为:* := ***。其实也是很简单的,使⽤正则表达式就可以搞定了。在这个模块中我使⽤了三个正则表达式,分别判断不同的集中情况,如 string patten = @"^[A-Z]\s{0,}:=\s{0,}$";这句,主要判断这样的⽂法句⼦:"A := ,",开始我没有判断这种情况。使⽤的正则表达式是:string pattenCon = @"^[A-Z]\s{0,}:=\s{0,}[a-z]{0,}[A-z]{0,}[a-z]{0,}[A-Z]{0,}$";,这句就是判断正常的⽂法句⼦。如果符合规则,则匹配成功就可以了。还有⼀个是string pattenStart = @"^[A-Z][0-9]{0,1}\[[A-Z]\]:$";,这个是判断⽂法开始的,就是G[S]:,这是模式匹配的代码,也是我认为最精彩的⼀段了。
1///<summary>
2///分析⽂法
3///</summary>
4///<param name="textArray">⽂法内容</param>
5///<param name="resultstextBox"></param>
6///<param name="start"></param>
7///<returns></returns>
8internal string grammarAnalysis(string[] textArray, TextBox resultstextBox, ref string start)
9        {
10string error = "";
11
12string result = "";
13string hello = "";
14
15//匹配正则表达式
16
17string pattenStart = @"^[A-Z][0-9]{0,1}\[[A-Z]\]:$";
18string pattenCon = @"^[A-Z]\s{0,}:=\s{0,}[a-z]{0,}[A-z]{0,}[a-z]{0,}[A-Z]{0,}$";
19string pattenValidate = @"^[A-Z]\s{0,}:=\s{0,}$";
20int length = textArray.Length;
21int temp = 0;
22
23for (int k = 0; k < length; k++)
24            {
25                Regex regVadidate = new Regex(pattenValidate);
26                Match mValidate = regVadidate.Match(textArray[k]);
27if (mValidate.Success)
python正则表达式判断28                {
29                    error += textArray[k]+"\r\n";
30                }
31            }
32
33if (error == "")
34            {
35                Regex regStart = new Regex(pattenStart);
36                Match mStart = regStart.Match(textArray[temp]);
37if (mStart.Success)
38                {
39                    start = textArray[temp];
40
41for (temp = 1; temp < length; temp++)
42                    {
43                        Regex regCon = new Regex(pattenCon);
44                        Match mCon = regCon.Match(textArray[temp]);
45if (mCon.Success)
46                        {
47                            result += textArray[temp];
48                        }
49else
50                        {
51                            error += textArray[temp] + "\r\n";
52                        }
53                    }
54                }
55else
56                {
57for (; temp < length; temp++)
58                    {
59                        Regex regCon = new Regex(pattenCon);
60                        Match mCon = regCon.Match(textArray[temp]);
61if (mCon.Success)
62                        {
63                            result += textArray[temp];
64                        }
65else
66                        {
67                            error += textArray[temp] + "\r\n";
68                        }
69                    }
70
71                }
72
73            }
74else
75            {
76                resultstextBox.Text = "以下输⼊的⽂法有错误:\r\n";
77                resultstextBox.Text += error;
78return hello;
79            }
80
81
82if (error == "")
83            {
84return result;
85            }
86else
87            {
88                resultstextBox.Text = "以下输⼊的⽂法有错误:\r\n";
89                resultstextBox.Text += error;
90return hello;
91            }
92        }
下⾯的代码是调⽤这段代码
1///<summary>
2///终结符、⾮终结符区分
3///</summary>
4///<param name="sender"></param>
5///<param name="e"></param>
6private void analysisButton_Click(object sender, EventArgs e)
7        {
8///
9///使⽤ref 返回⽂法开
10///
11string start = "";
12string flag = this.srctextBox.Text.ToString();
13if (sultstextBox.Text != "")
14            {
16            }
17//string textTemp = this.srctextBox.Text;
18if (flag != "")
19            {
20string[] textArray = this.srctextBox.Text.Replace("\r\n", "\r").Split('\r');
21
22string grammar = ammarAnalysis(textArray, resultstextBox, ref start);
23if (grammar == "")
24                {
26                }
27else
28                {
29//在srctextBox中打印出⽂法分析的结果
30
31                    PrintResult(grammar, start);
32                }
33            }
34else
35            {
37            }
38
39        }
还有⼀段将结果打印在resultstextBox中,显⽰给⽤户。
1///<summary>
2///在srctextBox中打印出⽂法分析的结果
3///</summary>
4///<param name="grammar">终结符和⾮终结符</param>
5///<param name="start">⽂法开始</param>
6private void PrintResult(string grammar, string start)
7        {
8int k = 0;
9int l = 0;
10//⽂法开始符
11string star = "";
12//终结符
13string terminal = "";
14//⾮终结符
15string nonterminal = "";
16if (start != "")
17            {
18int i = 0;
19char[] st = start.ToCharArray();
20
21while (st[i] != ']')
22                {
23                    i++;
24                }
25                star = st[i - 1].ToString();
26
29            }
30
31
32char[] resultTemp = grammar.ToCharArray();
33for (int j = 0; j < resultTemp.Length; j++)
34            {
35if (resultTemp[j] <= 'Z' && resultTemp[j] >= 'A')
36                {
37                    nonterminal += resultTemp[j].ToString() + ' ';
38                    k++;
39if (k % 19 == 0)
40                    {
41                        nonterminal += "\r\n";
42                    }
43
44                }
45else if (resultTemp[j] <= 'z' && resultTemp[j] >= 'a')
46                {
47                    terminal += resultTemp[j].ToString() + " ";
48                    l++;
49if (l % 19 == 0)
50                    {
51                        terminal += "\r\n";
52                    }
53                }
54            }
55if (start == "")
56            {
57string star1 = nonterminal.Substring(0,1);
60            }
65
66        }
67
就是这样了。⼤部分的代码就是这样了。其中还有⼀个问题就是:⾮终结符在右边出现,⽽没有在左边出现的情况。