Итак, я экспериментирую с псевдонимами токена и сталкиваюсь с некоторыми проблемами.
Давайте возьмем эту часть моей (очень упрощенной) грамматики зубров в качестве примера:
/****************************************
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
(Ну, «номер» псевдоним является дубликат, так как он используется в 4 жетонах).
Тем не менее, я бы искал что-то более похожее unexpected identifier, expected number
,
Как бы вы пошли об этом?
Кроме того, есть ли шанс, что я мог бы также включить строку ошибки в сообщение?
Постскриптум Я часами изучал последнюю документацию по Bison, но мне кажется, что я собираюсь построить … ракету вместо того, чтобы исправлять сообщения об ошибках … lol
Как бы вы пошли об этом?
Я бы использовал один NUMBER
маркер. Я не вижу смысла заставлять парсер заботиться о том, на какой тип числового литерала он смотрит.
Конечно, вполне возможно, что ваша полная грамматика действительно включает места, где разрешены только определенные форматы числовых литералов, хотя мое общее склонение к такого рода вещам — «юк». Наиболее вероятная возможность состоит в том, что есть какое-то правило, в котором целочисленная константа в порядке, а константа с плавающей точкой — нет. В этом случае вы не получите хорошие сообщения об ошибках для этого конкретного производства если вы не предоставите другой псевдоним для чисел с плавающей запятой, чем для целых чисел. В целом, однако, я придерживаюсь «юк».
Если у вас один числовой тип токена с псевдонимом «число», то ошибки должны работать нормально.
Других решений пока нет …