token - Bison:如果 token 不符合规则,如何忽略它

标签 token bison flex-lexer

我正在编写一个程序来处理评论以及其他一些事情。如果评论位于特定位置,那么我的程序会执行某些操作。

Flex 在找到评论时传递一个标记,然后 Bison 会查看该标记是否符合特定规则。如果是,则它采取与该规则相关联的操作。

事情是这样的:我收到的输入实际上可能在错误的地方有评论。在这种情况下,我只想忽略评论而不是标记错误 .

我的问题:
如果 token 符合规则,我如何使用它,但如果不符合则忽略它?我可以制作一个“可选”的 token 吗?

(注意:我现在能想到的唯一方法是在每个可能的规则中的每个可能的位置散布评论标记。必须有比这更好的解决方案。也许一些涉及根的规则?)

最佳答案

一种解决方案可能是使用野牛的错误恢复(参见 Bison manual )。

总而言之,bison 定义了终端 token error表示错误(例如,在错误位置返回的注释标记)。这样,您可以(例如)在发现任性注释后关闭括号或大括号。但是,这种方法可能会丢弃一定量的解析,因为我认为野牛不能“撤消”减少。 (“标记”错误,就像向 stderr 打印消息一样,与此无关:您可以在不打印错误的情况下出现错误——这取决于您如何定义 yyerror 。)

您可能希望将每个终端包装在一个特殊的非终端中:

term_wrap: comment TERM

这有效地完成了您害怕做的事情(在每个规则中添加注释),但它在较少的地方完成。

为了强制自己吃自己的狗粮,我为自己编造了一种愚蠢的语言。唯一的语法是 print <number> please ,但如果数字和 ## 之间(至少)有一条评论( please ) ,它以十六进制打印数字,而不是。

像这样:
print 1 please
1
## print 2 please
2
print ## 3 please
3
print 4 ## please
0x4
print 5 ## ## please
0x5
print 6 please ##
6

我的词法分析器:
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
%}

%%

print           return PRINT;
[[:digit:]]+    yylval = atoi(yytext); return NUMBER;
please          return PLEASE;
##              return COMMENT;

[[:space:]]+    /* ignore */
.               /* ditto */

和解析器:
%debug
%error-verbose
%verbose
%locations

%{
#include <stdio.h>
#include <string.h>

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

int yywrap() {
        return 1;
} 

extern int yydebug;
int main(void) {
    yydebug = 0;
    yyparse();
}
%}

%token PRINT NUMBER COMMENT PLEASE

%%

commands: /* empty */
        |
        commands command
    ;

command: print number comment please {
        if ($3) {
            printf("%#x", $2);
        } else {
            printf("%d", $2);
        }
        printf("\n");
     }
     ;

print: comment PRINT
     ;

number: comment NUMBER {
        $$ = $2;
      }
      ;

please: comment PLEASE
      ;

comment: /* empty */ {
            $$ = 0;
       }
       |
        comment COMMENT {
            $$ = 1;
        }
    ;

所以,正如你所看到的,不完全是火箭科学,但它确实有效。由于空字符串匹配 comment,因此存在移位/减少冲突。在多个地方。此外,没有规则可以在最终 please 之间添加评论。和 EOF .但总的来说,我认为这是一个很好的例子。

关于token - Bison:如果 token 不符合规则,如何忽略它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6797221/

相关文章:

bison - flex bison扫描仪解析的单元测试,如何驱动测试用例

linux - 我在这个 lex 程序中遇到无法识别的规则错误

flex-lexer - 在调用 yymore() 之前修改/过滤 yytext

python - 在 Python 中使用正则表达式进行标记化

git - 如何设置我的本地 Git 存储库以使用我刚刚创建的新个人访问 token ?

javascript - form.submit() 用 '?' chop 字符串

c++ - 使用 flex/bison 的多行注释声明

c++ - 为什么 Bison 仍然使用 `int yylex(void)`而找不到 `int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param)`?

使用flex的C编译器

angular - 如何从 jwt token 获取用户角色