Как исправить reduce/reduce конфликт?

224
11 апреля 2017, 11:35

Я пытаюсь написать парсер функций и переменных С++.

Имею вот такую грамматику(обрезана):

declaration:
    block_declaration
    | function_definition
    ;
block_declaration: simple_declaration;
simple_declaration: decl_specifier_seq init_declarator_list';';
decl_specifier_seq:
    decl_specifier
    | decl_specifier_seq decl_specifier
    ;
decl_specifier: type_specifier
    ;
type_specifier:
    simple_type_specifier
    | cv_qualifier
    ;
simple_type_specifier: type;
function_definition:
    decl_specifier_seq declarator function_body
    ;
function_body: '{' '}';
init_declarator_list:
    init_declarator
    | init_declarator_list ',' init_declarator
    ;
init_declarator: declarator initializer_opt;
declarator:
    direct_declarator
    | ptr_operator declarator
    ;
direct_declarator:
    declarator_id
    | direct_declarator '(' ')'
    | '(' declarator ')'
    ;
declarator_id: name | COLONCOLON name;
type:scope_id_seq_opt identifier;
name:scope_id_seq_opt unqualified_id;
scope_id_seq_opt:
    | scope_id_seq
    ;
scope_id_seq: scope_id_seq_opt SCOPE_ID COLONCOLON;
unqualified_id: identifier;
identifier:ID;

Конфликт reduce/reduce возникает в direct_declarator и связан с | '(' declarator ')' то есть если закоментировать эту строчку то всё хорошо, но теряется возможность распознать код вида int (*var);, а С++ поддерживает такой синтаксис. Как мне исправить данный конфликт?

Например парсим текст вида:

T add() {}

Лексер преобразует его в

ID(T) ID(add) '(' ')' '{' '}'

Должно быть так: ID(T) должен свернуться в type, а потом свернётся в decl_specifier_seq. ID(add) '(' ')' должен свернуться в declarator через правило | direct_declarator '(' ')'.

Но из-за конфликта правила | direct_declarator '(' ')' с | '(' declarator ')' происходит вот так. В decl_specifier_seq сворачивается не ID(T), а ID(T) ID(add). А вот '(' ')' начинает сворачиваться в declarator по правилу | '(' declarator ')' и происходит syntax error, unexpected ')', expecting ID or SCOPE_ID

Использовать glr парсер я не могу по причине использования Lexical feedback

READ ALSO
QSqlQuery возвращает некоректные данные

QSqlQuery возвращает некоректные данные

ЗдравствуйтеТретий день бьюсь над проблемой

222
Генерация разных не равных чисел JS

Генерация разных не равных чисел JS

Как сгенерировать не равные друг другу рандомные числа в заданном диапазоне?

304
Как удалить часть кода из файла полностью?

Как удалить часть кода из файла полностью?

Можно ли удалить определенный <div id="q1"> программно из кода полностью? Искал в интернете, но чего-то дельного не нашел, обычно это скрытие...

205