2014-12-29 3 views
1

Это часть грамматики для моего языка программирования. Во время компиляции возникают конфликты смены/сокращения.получение ошибок сдвига/уменьшения в моей грамматике

Rule 1: encryption_spec: key_spec 

Rule 2: key_spec: 
    key_spec key_spec_content 
    | key_spec_content 
    ; 

Rule 3: key_spec_content: TOK_PROTECT key_keyowner 
    |TOK_PROTECT key_keyname 
    |TOK_PROTECT key_keymethod 
    |TOK_PROTECT key_pub_key 
    |TOK_COMMA key_keyowner 
    |TOK_COMMA key_keyname 
    |TOK_COMMA key_keymethod 
    |TOK_COMMA key_pub_key 
    |encoding 
    ; 

Я получаю сдвиг/свертка конфликт в правиле 1. Можете ли вы предложить мне что-то изменить?

+0

Посмотрите на файл 'y.output' с' yacc -v', чтобы узнать, что представляет собой реальный конфликт - вам нужно посмотреть, в каком состоянии находится конфликт, и как парсер попадает в это состояние для его разрешения. –

+0

Из аргумента y.output видно, что причина конфликта такова: грамматика не может решить, следует ли искать или объявлять появление блока encryption_spec в соответствии с правилом 1 после нахождения хотя бы одного из операторов по правилу 3 –

+0

. Тогда есть какое-то другое правило, которое может следовать за «encryption_spec», которое не показано в вашем фрагменте выше, это источник конфликта. –

ответ

3

Правило вашего key_spec неверно. Действительно, у вас бесконечная рекурсия.
Вы должны изменить его на что-то вроде

key_spec: /* Empty. */ 
    | key_spec key_spec_content 
; 

EDIT: Удалить зубров расширение %empty.

+1

Обратите внимание, что '% empty' является расширением бизона, чтобы сделать правила epsilon более заметными. Для нормального yacc вам нужно пустое правило (ничего не между символами ':' и '|' except whitespace) –

+0

Это была опечатка. Я знаю, что это бесконечная рекурсия. Я все еще получаю сокращение/конфликт смены в правиле 1. Любая альтернатива для грамматики? –

+0

Во-первых: вы можете отредактировать свое оригинальное сообщение, чтобы исправить опечатку, пожалуйста? Во-вторых: не видя своих других правил без терминалов, я не могу вам помочь. Написание этой программы и установка 'key_ *' и 'encoding' в качестве терминалов не предупреждают о каких-либо конфликтах. –

1

Правило от @Leo неверно, так как оно допускает нулевые значения key_spec_content, где оригиналу требуется хотя бы одно. Следующее должно сделать это:

key_spec: 
    key_spec key_spec_content 
    | key_spec_content 
; 

Однако это правило имеет ненужную рекурсию. Должно быть лучше:

key_spec: 
    key_spec_content key_spec 
    | key_spec_content 
; 

Это позволяет уменьшить, увидев каждый key_spec_content.

+0

Я соглашаюсь на пустое правило. Однако вы ошибаетесь в левой или правой рекурсии. В самом деле, левая рекурсия DO сводится к каждому key_spec_content, а не к правильному. http://www.gnu.org/software/bison/manual/html_node/Recursion.html –

+0

В оригинале требуется бесконечное количество «key_spec_content» и запрещается любое конечное число. Поэтому вам нужно изменить его, чтобы разрешить конечные входы, и выбор между разрешением 0 или более и 1 или более кажется произвольным. –

+0

Это была опечатка. Я знаю, что это бесконечная рекурсия.Я все еще получаю сокращение/конфликт смены в правиле 1. Любая альтернатива для грамматики? –

Смежные вопросы