c - 在 Bison 中使用字 rune 字作为终端

标签 c bison yacc lex flex-lexer

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

文件“a”包含单个字符“a”。 “foo.y”有一个像这样的简单语法:

%%

file: 'a' ;

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

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

%token TOK_A;

%%

file: TOK_A;

然后在 bar.lex 中:

a       { return TOK_A; }

这个工作得很好。

我在尝试将字 rune 字直接用作 Bison 终端时做错了什么,就像在文档中一样?

我希望我的语法看起来像 "statement: selector '{' property ':' value ';' '}'”而不是“语句:选择器 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; }

foo.y

%{
#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 - 在 Bison 中使用字 rune 字作为终端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13198231/

相关文章:

c++ - g++ 编译器无法识别 lex 的内置 input() 函数

parsing - M4 "No such file or directory".Bison

c - 是否可以获取代币的值(value)?

c++ - Antlr 的优势(相对于 lex/yacc/bison)

c - 在 Linux 上编译许多源文件时出错

c - 如何在 C 中突出显示 GTKTreeView 行,就像用鼠标选择一样

c++ - 如何用msgpack-c打包多键映射

c - 语法中的左递归会导致冲突

ios - "Unknown type name"使用 YACC 和 xcode

检查 pthread 句柄是否正在休眠