好的,我正在尝试使用 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/