递归下降解析器,对“ a”和“ b”字符​​的数量计数不正确

时间:2019-09-09 02:44:12

标签: 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("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”时,也会出现语法错误。

1 个答案:

答案 0 :(得分:2)

nontermAnontermB函数都表现出相同的逻辑缺陷。以下仅描述nontermA的错误,但在nontermB中也会发生相同的错误。

 int countA = 0;

这声明了int本地的新nontermA变量。

  case 'a': match('a'); countA++; nontermA(); break; 

这使countA递增,并递归地调用自身。

但是,nontermA的每个递归调用的工作方式都与对nontermA的任何其他函数调用完全相同:它创建了一个名为countA的新局部变量并将其初始化为0。

此处的明显意图是使计数器在所有递归调用中均保持不变。但是递归不能以这种方式工作。

每个递归调用仅为该递归函数调用创建一个新的countA局部int变量 ,这是唯一递增的东西。这就是C ++的工作方式。

解决方案非常简单:只需返回计数器值,让nontermAnontermB直接返回计数器值即可。

  case 'a': match('a'); return nontermA()+1;

否则,

return 0;

没有匹配时。