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