1

以下代码应该生成输入表达式的解析树,但问题是输出 E,T,F,S(代码中使用的函数)。我希望它是这样的:

a+b*c => E*c => E+b*c => a+b*c

     #include <stdio.h>
     #include <stdlib.h>
     #include <ctype.h>
     char next;
     void E(void);void T(void);
     void S(void);void F(void);
     void error(int);void scan(void);
     void enter(char);
     void leave(char);
     void spaces(int);
     int level = 0;



    //The main should always be very simple
    //First scan the string
    //second check for end of string reached , if yes success and if not error.

    //P ---> E '#'
    int main(void){
       printf("Input:");
       scan();  E();
       if (next != '#') error(1);
       else printf("***** Successful parse *****\n");
    }

    //E ---> T {('+'|'-') T}
    void E(void){
       enter('E');
       T();
       while (next == '+' || next == '-') {
          scan();
          T();
       }
       leave('E');
    }


    //T ---> S {('*'|'/') S}
    void T(void)
    {
       enter('T');  S();
       while (next == '*' || next == '/') {
          scan(); S();
       }
       leave('T');
    }

    //S ---> F '^' S | F
    void S(void)
    {
       enter('S'); F();
       if (next == '^') {
          scan();  S();
       }
       leave('S');
    }

    //F ---> char | '(' E ')'
    void F(void)
    {
       enter('F');
       if (isalpha(next)) 
       { 
           scan();
       }
       else if (next == '(') {
          scan(); E();
          if (next == ')')
              scan();
          else
              error(2);
       }
       else { 
          error(3);
       }
       leave('F');
    }
    //Scan the entire input
    void scan(void){
       while (isspace(next = getchar()));
    }

    void error(int n)
    {
       printf("\n*** ERROR: %i\n", n);
       exit(1);
    }

    void enter(char name)
    {
       spaces(level++);
       printf("+-%c\n", name);
    }

    void leave(char name)
    {
      spaces(--level);
      printf("+-%c\n", name);

    }
    //TO display the parse tree
    void spaces(int local_level)
    {
       while (local_level-- > 0)
       printf("| ");
    }
4

2 回答 2

1

看起来像一个递归下降解析器。首先,手工计算你的语法。你所期待的不是你的语法所说的。你有,从你的评论,

E ---> T {('+'|'-') T}   expression
T ---> S {('*'|'/') S}   term
S ---> F '^' S | F       subexpression?
F ---> char | '(' E ')'  factor

E 和 T 的定义将 * 置于比 + 更高的优先级,因此您无法获得 E*c。如果你想要那样,你必须将语法切换到

E ---> T {('*'|'/') T}   expression
T ---> S {('+'|'-') S}   term

如果您只希望输出包含表达式的其余部分,

  1. 把整条线放进去
  2. 更改您的扫描仪或词法分析器以从该扫描行中获取下一个字符。将此标记为扫描点。
  3. 更改您的 Enter 例程以打印助记符以及从扫描点开始的行。
于 2013-06-28T04:02:51.640 回答
0

您无法选择解析树。我猜你不理解输出,但是(再次)我猜你会喜欢

a+b*c => F+b*c => S+b*c => T+b*c => T+F*c => T+S*c => T+S*F => T+S*S => T+T => E

所以这里有几个问题可以提供帮助。

  1. 那里正在进行什么样的解析?自下而上还是自上而下?
  2. 解析器在打印 enter/leave 时处于什么状态E,或者T

如果您自下而上回答第一个问题,E、T、S、F、F 表示什么(输入 E,输入 T,输入 S,输入 F,离开 F)?当您离开 F 时,这意味着解析器成功识别了非终端。尝试输入字符串1+b*c。你得到了什么?为什么在 E、T、S、F 之后会出现错误?

如果您了解当前生成的内容,则可以轻松生成您似乎需要的输出。希望这可以帮助。

于 2013-06-28T03:00:03.727 回答