как я должен сделать рекурсивное правило в yacc / bison и lex? - PullRequest
3 голосов
/ 23 января 2012

Я пишу простой HTML-парсер, использующий yacc (bison) и flex.Как я могу сделать это правило:

column -> <td>text</td>column | NULL

Я пробовал много форм, как это:

COLUMN : L_TAG T_OPEN R_TAG ID L_TAG T_CLOSE R_TAG COLUMN
| 
;

// токены указаны в лекс.

к сожалениюэто не работаетэто дает мне ошибку сдвига / уменьшения.положил ли я КОЛОННУ в начало правила или в конец.использую ли я значение NULL следующим образом:

{$$ = NULL}

или оставляю его пустым.Мне нужна вещь NULL, чтобы сделать правило рекурсивным и иметь возможность иметь один и тот же тег более одного раза рядом друг с другом.как то так:

<tr>name</tr><tr>age</tr>

как я могу заставить эту работу работать?

Ответы [ 2 ]

2 голосов
/ 23 января 2012
column       :/* empty */
             | column '<' TD '>' TEXT '<' '/' TD '>'

Вы можете оптимизировать свои правила настолько, насколько это возможно.для рекурсии, вы должны в грамматике lalr (1) сделать ее рекурсивной.

удачи

0 голосов
/ 23 января 2012

Обычно вы разбиваете его на несколько частей:

table : TABLE rows CLOSE_TABLE
      ;

rows: 
    | rows row
    ;

row:  TR row_header cells CLOSE_TR
   ;

row_header: TH text CLOSE_TH
          ;

cells: 
     | cells cell
     ;

cell: TD TEXT CLOSE_TD
    ;

Где TABLE равно <table>, CLOSE_TABLE равно </table> и т. Д.

О, просто чтобы прояснить: я не очень работал, чтобы убедиться, что это действительно правильно анализирует HTML.На самом деле, я уверен, что сейчас этого не происходит.Просто для одного очевидного примера я считаю, что заголовок строки действительно должен быть необязательным.

...