为什么我的解析器显示有效程序的错误?

Why is my parser showing errors for valid programs?

我不知道我的解析器出了什么问题。以下是相关文件:

parse.y

    declarations:     INTEGER_SIZE IDENTIFIER TERMINATOR {declare(,);}

    void yyerror(char *err){
        printf("\n\nYYError on line %d: Error = %s\n", yylineno, err);
    }

scan.l

[Xx]+                       {yylval.size = strlen(yytext);

当运行针对下面的有效程序使用它时,它在第 3 行显示错误;当 运行 单独处理任何一行时,它通过 yyerror() 函数在第 1 行显示错误。

BEGINING.
XXX XY-1.
XXXX Y.
XXXX Z.

BODY.
PRINT “Please enter a number? ”.
INPUT Y.

MOVE 15 TO Z.
ADD Y TO Z.
PRINT XY-1;” + “;Y;”=”;Z.

END.

到 运行 文件 运行 以下命令:

  1. yacc -d parser.y
  2. lex lexer.l
  3. gcc -o 解析器 lex.yy.c y.tab.c -ll

这个non-terminal被称为declarations,从中可能会认为它匹配一个或多个声明,或者可能是零个或多个声明:

declarations:       INTEGER_SIZE IDENTIFIER TERMINATOR {declare(,);}

但是规则恰好匹配三个标记,也就是说一个声明。所以当你给它一个包含两个声明的输入时,它在第二个声明上失败。

同样,您的 non-terminal 称为 statements 仅匹配一个语句,而不是从其名称中预期的多个语句。

语法需要明确。如果要匹配多个声明,则必须这样写:

declarations: declaration
            | declarations declaration

顺便说一下,我之前看到过一些语法,认为你必须在产生式的末尾写 {;}。我很好奇这个想法从何而来。 Yacc 和 bison 不要求产生式有动作,反正一个空动作就是{},就像在 C 中一样