c++ - Bison 中的错误报告和 token 别名

标签 c++ c parsing bison lex

好的,我正在尝试使用 token 别名并面临一些问题。

让我们以我的(超简化的)Bison 语法的这一部分为例:

/****************************************
 Definitions
 ****************************************/

%union 
{
    char* str;
}

/****************************************
 Tokens & Types
 ****************************************/

%token <str> ID "identifier"
%token <str> NUMBER_DEC "number" 
%token <str> NUMBER_HEX "number" 
%token <str> NUMBER_BIN "number"
%token <str> NUMBER_FLOAT "number"

%type <str> identifier number
%type <str> assignment_st
%type <str> statements statement
%type <str> program

/****************************************
 Directives
 ****************************************/

%glr-parser
%locations
%start program
%define parse.error verbose
%%


/****************************************
 Grammar Rules
 ****************************************/

identifier          :   ID
                    ;

number              :   NUMBER_DEC
                    |   NUMBER_HEX
                    |   NUMBER_BIN
                    |   NUMBER_FLOAT
                    ;

assignment_st       :   identifier '=' number ';'                   { printf("assignment : %s = %s\n",$identifier,$number); }
                    ;

statement           :   assignment_st
                    ;

statements          :   statement
                    |   statements statement
                    ;

program             :   statements
                    ;

%%

现在,如果我尝试 a = 2;,这显然符合语法。 如果我尝试 a = b; 这是一个错误,因为它需要一个数字。在这种情况下,解析器报告:

syntax error, unexpected identifier, expecting number or NUMBER_HEX or NUMBER_BIN or NUMBER_FLOAT

(嗯,“number”别名重复的,因为它在 4 个 token 中使用)。

但是,我会寻找更像意外标识符,预期数字的内容。

你会怎样做?

此外,我是否有可能将错误行也包含在消息中?


P.S. 我已经研究最新的 Bison 文档几个小时了,但我觉得我最终会 build 一个......火箭而不是修复错误消息......哈哈

最佳答案

How would you go about it?

我会使用单个 NUMBER token 。我认为没有任何理由让解析器关心它正在查看哪种类型的数字文字。

当然,你的完整语法实际上可能涉及只允许某些格式的数字文字的地方,尽管我对这类事情的总体倾向是“yuk”。最有可能的可能性是存在某种规则,其中整数常量可以,但浮点常量不行。在这种情况下,除非您为 float 提供与整数不同的别名,否则您将无法获得该特定产生式的良好错误消息。但总的来说,我还是坚持使用“yuk”。

如果您有一个数字标记类型,且别名为“number”,那么错误应该可以正常解决。

关于c++ - Bison 中的错误报告和 token 别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22388218/

相关文章:

c++ - 覆盖具有不同返回类型的基类函数

c++ - 当引用位于标题中并且应该存在时 undefined reference

将一个指针的引用复制到另一个指针 C

javascript - 我如何通过ajax解析html

c++ - 使用 boost spirit 语法构建错误(boost 1.43 和 g++ 4.4.1)第二部分

xml - Go XML - 解析 HTML 中的 bool 属性导致 XML 验证错误

C++ 多维数组运算符

c++ - 链表C++实现

c++ - 在不窃取焦点的情况下使用对话框控件

c - 尝试在循环中使用 scanf 扫描值。需要辅助输入来打印第一个输入