C 计算';a';和';b';字符计数不正确
我正在编写一个简单的递归下降解析器,它接受标准输入并计算“a”和“b”字符的数量。其语法如下: S->A B'\n' A->A A |空 B->B B |空C 计算';a';和';b';字符计数不正确,c,recursive-descent,C,Recursive Descent,我正在编写一个简单的递归下降解析器,它接受标准输入并计算“a”和“b”字符的数量。其语法如下: S->A B'\n' A->A A |空 B->B B |空 int lookahead; int nontermA(); int nontermB(); void match (int terminal){ if (lookahead == terminal){ lookahead = getchar(); } else { printf("Synt
int lookahead;
int nontermA();
int nontermB();
void match (int terminal){
if (lookahead == terminal){
lookahead = getchar();
} else {
printf("Syntax error at %c\n", lookahead);
exit(0);
}
}
void nontermS(){
int a,b;
switch(lookahead){
default:
a = nontermA();
b = nontermB();
printf("Match! Number of A's is %d and number of B's is %d", a,b);
match('\n');
}
}
int nontermA(){
int countA = 0;
switch(lookahead){
case 'a': match('a'); countA++; nontermA(); break;
case 'A': match('A'); countA++; nontermA(); break;
default: break;
}
return countA;
}
int nontermB(){
int countB = 0;
switch(lookahead){
case 'b': match('b'); countB++; nontermB(); break;
case 'B': match('B'); countB++; nontermB(); break;
default: break;
}
return countB;
}
基本上,如果我输入“aA”、“bB”或“abAB”,它应该只输出a和b的数量,但我的程序的实际输出对于a和b只有1。当我输入“ba”以及输入“B”时,我也会遇到语法错误。
nontermA
和nontermB
函数都显示出相同的逻辑缺陷。下面只描述了nontermA
的bug,但同样的bug也出现在nontermB
中
int countA = 0;
这声明了一个新的int
变量,它是nontermA
的局部变量
case 'a': match('a'); countA++; nontermA(); break;
这会增加countA,并递归地调用自身
但是,nontermA
的每次递归调用的工作原理与对nontermA
的任何其他函数调用完全相同:它创建一个名为countA
的新局部变量,并将其初始化为0
这里的明显意图是让计数器在所有递归调用中持久化。但是递归不是这样工作的
每个递归调用仅为该递归函数调用创建一个新的countA
localint
变量,这是唯一递增的。C++就是这样工作的。
解决方案非常简单:只需返回计数器值,让nontermA
和nontermB
直接返回计数器值
case 'a': match('a'); return nontermA()+1;
否则,
return 0;
当不匹配时。两个
nontermA
和nontermB
函数都显示相同的逻辑缺陷。下面只描述了nontermA
的bug,但同样的bug也出现在nontermB
中
int countA = 0;
这声明了一个新的int
变量,它是nontermA
的局部变量
case 'a': match('a'); countA++; nontermA(); break;
这会增加countA,并递归地调用自身
但是,nontermA
的每次递归调用的工作原理与对nontermA
的任何其他函数调用完全相同:它创建一个名为countA
的新局部变量,并将其初始化为0
这里的明显意图是让计数器在所有递归调用中持久化。但是递归不是这样工作的
每个递归调用仅为该递归函数调用创建一个新的countA
localint
变量,这是唯一递增的。C++就是这样工作的。
解决方案非常简单:只需返回计数器值,让nontermA
和nontermB
直接返回计数器值
case 'a': match('a'); return nontermA()+1;
否则,
return 0;
当没有匹配发生时。请提供。其中,在第一次调用
match
?之前设置了lookahead
,等等。欢迎使用堆栈溢出。请注意,在这里说“谢谢”的首选方式是投票选出好的问题和有用的答案(一旦你有足够的声誉这么做),并接受对你提出的任何问题最有用的答案(这也会给你的声誉带来一点提升)。请参阅本页,也请提供。其中,在第一次调用match
?之前设置了lookahead
,等等。欢迎使用堆栈溢出。请注意,在这里说“谢谢”的首选方式是投票选出好的问题和有用的答案(一旦你有足够的声誉这么做),并接受对你提出的任何问题最有用的答案(这也会给你的声誉带来一点提升)。请看网页,也和它的作品!它还修复了在“B”处抛出语法错误的错误。然而,我输入“ba”时仍然遇到奇怪的语法错误。我认为这是nontermS()或match()的错误。根据定义,语法只接受零个或多个a
s,然后是零个或多个b
s。您的语法错误与语法一致。它有效!它还修复了在“B”处抛出语法错误的错误。然而,我输入“ba”时仍然遇到奇怪的语法错误。我认为这是nontermS()或match()的错误。根据定义,语法只接受零个或多个a
s,然后是零个或多个b
s。您的语法错误与语法一致。