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