我正在尝试了解flex/bison,但是文档对我来说有点困难,并且我可能严重误解了一些东西。这是一个测试用例:http://namakajiri.net/misc/bison_charlit_test/

文件“a”包含单个字符“a”。 “foo.y”的语法很简单:

%%

file: 'a' ;

生成的解析器无法解析文件“a”;它给出了语法错误。

语法“bar.y”几乎相同,只是我更改了命名 token 的字 rune 字:
%token TOK_A;

%%

file: TOK_A;

然后在bar.lex中:
a       { return TOK_A; }

这个很好用。

在像文档中那样直接将字 rune 字用作野牛终端时,我做错了什么?

我希望我的语法看起来像“声明:选择器'{'属性':'值';' '}'”而不是“语句:选择器LBRACE属性COLON值SEMIC RBRACE” ...

我在debian wheezy中运行bison 2.5和flex 2.5.35。

最佳答案

改写

该问题是运行时问题,而不是编译时问题。

问题在于您有两个截然不同的词法分析器。
bar.lex分析器识别输入中的a并将其作为TOK_A返回,并忽略其他所有内容。
foo.lex分析器回显每个字符,仅此而已。

foo.lex-书面

%{
#include "foo.tab.h"
%}

%%

foo.lex-等效
%{
#include "foo.tab.h"
%}

%%
. { ECHO; }

foo.lex-必需
%{
#include "foo.tab.h"
%}

%%
. { return *yytext; }

工作代码

这是一些诊断打印就绪的工作代码。

foo-lex.l
%%
. { printf("Flex: %d\n", *yytext); return *yytext; }

愚蠢的
%{
#include <stdio.h>
void yyerror(char *s);
%}

%%

file: 'a' { printf("Bison: got file!\n") }
    ;

%%

int main(void)
{
    yyparse();
}

void yyerror(char *s)
{
    fprintf(stderr, "%s\n", s);
}

编译与执行
$ flex foo-lex.l
$ bison foo.y
$ gcc -o foo foo.tab.c lex.yy.c -lfl
$ echo a | ./foo
Flex: 97
Bison: got file!

$

详细点:空白行是如何进入输出的?答:词法分析器将其放在此处。模式.与换行符不匹配,因此将换行符视为存在规则:
\n    { ECHO; }

这就是为什么输入被接受的原因。如果将foo-lex.l文件更改为:
%%
.       { printf("Flex-1: %d\n", *yytext); return *yytext; }
\n      { printf("Flex-2: %d\n", *yytext); return *yytext; }

然后重新编译并再次运行,输出为:
$ echo a | ./foo
Flex-1: 97
Bison: got file!
Flex-2: 10
syntax error
$

没有空白行。这是因为语法不允许换行出现在有效的"file"中。

关于c - 在野牛中使用字 rune 字作为终端,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13198231/

10-11 18:55