Flex 和 Bison 接受仅包含注释的行

Flex and Bison accept a line that contains only a comment

flex 和 bison 中的练习 1.1 要求我接受仅包含注释的行。 这是我的 .l 文件的一部分:

%{   
   #include"fb1-5.tab.h"
%}

%%

...
"//".* {  return COMMENT;}
\n     {  return EOL;}

%%

然后是我的.y文件:

%{ 
    #include <stdio.h> 
%}

....  // the token about the calculator

%token COMMENT
%token EOL

%%

....    // the rulse about the calculator

comment: COMMENT EOL { printf("%s",yytext);}

%%

当我运行项目和输入 //test

输出:

error: syntax error

很明显,如果您输入仅包含注释的行,计算器会报告语法错误。这是一个问题,特别是对于这个一旦遇到语法错误就会失败的简单实现。 (真正的计算器必须从错误中恢复过来。这在本书后面会讲到。)

但是让我们忘记评论吧。如果我们只输入一个空行呢?

$ ./fb1-5

syntax error
$

不难看出这两个问题是相关的。扫描器只是从输入流中删除注释,因此如果我们键入仅包含注释的行,解析器看到的内容与我们键入空行时看到的内容完全相同:只是 EOL 字符。

那有什么问题呢?语法指定输入的样子:

calclist: /* Nothing */
 | calclist exp EOL { /* print answer */ }

了解这些规则的含义很重要,本练习鼓励您思考这些规则的含义。您会在 John Levine 的书(以及任何其他关于解析的书)中找到更长(也许更友好)的解释,但基本思想非常简单。规则规定 calclist 要么是空的,要么是(先前确定的)calclist 后跟 exp 后跟 EOL。不存在其他可能性。

那么空行怎么匹配呢?空行就是 EOL;没有exp,所以不会匹配第二条规则。 (这很好,因为我们不想将不存在的答案打印到一个空行。)既然没有别的,我们需要添加另一个规则:

 | calclist EOL { /* Do nothing */ }

现在,如何处理仅包含评论的行?为什么?

以上完全没有涉及扫描仪,但练习 1-1 表明扫描仪中也可能有解决方案。可以吗?它有多复杂?它能恰当地处理空行吗?您可能想花点时间看看如何使用扫描仪执行此操作。这是可能的,但远没有向解析器添加一行那么简单。