2013-05-22 1 views
0

У меня есть эта грамматика в Yacc:сдвиг/свёртка Конфликт в Yacc/Flex

%{ 
    #include <stdio.h> 
%} 

%token texto SEP ERRO word 

%start Ini 

%% 

Ini: Directivas SEP SEP Conceitos '$' 
      { printf("Terminou bem...\n"); return 0; }; 

Directivas: Directiva 
      | Directivas SEP Directiva 
      ; 

Conceitos: Conceito 
     | Conceitos SEP SEP Conceito 
     ; 

Conceito: word SEP Atributos; 

Atributos: Atributo 
     | Atributos SEP Atributo 
     ; 

Directiva: texto; 
Atributo: '-' texto; 

%% 

int main(){ 
    yyparse(); 
} 

int yyerror(char *s){ 
    fprintf(stderr, "%s\n", s); 
} 

И в гибком:

%{ 
    #include "y.tab.h" 
%} 

%% 

[a-zA-Z]+   return word; 

[a-zA-Z ]+   return texto; 

\-     return '-'; 

\n     return SEP; 

[ \t]    ; 

.     return ERRO; 

<<EOF>>    return '$'; 

Я хочу сделать парсер, что valids что-то вроде:

text line 
text line 
text line 

word 
-text line 
-text line 
-text line 

word 
-text line 

, где первые строки - это «Директивы», а затем одна пустая строка, а затем «Conceitos», где один Conceito - это одно слово, за которым следует af ew текстовые строки с «-» в начале. эти «Conceitos разделены одной пустой строкой

, но он находит сдвиг/свёртка conflitct .. Я новичок в этом и я не могу понять, почему

Извините за мой английский

Спасибо

ответ

2

Используйте опцию yacc (или bison's) -v, чтобы получить полный список сгенерированного анализатора и конфликты грамматики в файле y.output. Когда вы делаете это с вашей грамматики, вы получите что-то вроде (от бизона):

State 16 conflicts: 1 shift/reduce 
     : 
state 16 

    6 Conceito: word SEP Atributos . 
    8 Atributos: Atributos . SEP Atributo 

    SEP shift, and go to state 20 

    SEP  [reduce using rule 6 (Conceito)] 
    $default reduce using rule 6 (Conceito) 

Это говорит вам, где именно конфликт - после снижения в Attributos и глядя на SEP опережающего просмотра, анализатор не знайте, следует ли ему сдвинуть SEP, чтобы проанализировать еще один Atributo после него или уменьшить Conceito, что было бы действительным только в том случае, если есть SEP после SEP (требуется наличие двух токенов).

Один из способов избежать этого будут иметь ваш лексический возвращать несколько SEP с (пустыми строками) в качестве единственных маркеров:

\n  return SEP; 
\n\n return SEP_SEP; 

Вы могли бы хотеть, чтобы пропуска на пустой строке или более чем одного пустая строка:

\n([ \t]*\n)+ return SEP_SEP; 
+0

Большое спасибо, совет о -v действительно помогает мне !! –

+0

@ chris-dodd: что я могу сделать, если опция '-v' не изменяет результат, и сейчас это просто дает мне количество конфликтов сдвига/уменьшения? – skeggse

+0

@distilledchaos: Опция '-v' создает дополнительный выходной файл (с расширением' .output') с подробной информацией. –

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

  • Нет связанных вопросов^_^