如何在yacc/bison和lex中制定一个递归规则?

3
我正在使用yacc(bison)和flex编写一个简单的HTML解析器。 如何制定这条规则:
column -> <td>text</td>column | NULL

我尝试过很多类似这样的表单:

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

//这些标记在词法分析器中指定。

不幸的是,它不起作用。无论我将COLUMN放在规则开头还是结尾,都会给出shift/reduce错误。即使我像这样使用NULL:

{$$ = NULL}

或者将其留空。我需要使用NULL来使规则递归,并且可以在相邻位置多次使用同一个标签,就像这样:

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

我该如何让这个工作起来?

2个回答

2
column       :/* empty */
             | column '<' TD '>' TEXT '<' '/' TD '>'

您可以通过使规则更加具体来进行优化。对于递归问题,您应该在lalr(1)语法中将其设置为左递归。

祝好运!


1

通常你需要将它分成多个部分:

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。实际上,我相信它现在并不正确。只举一个明显的例子,我认为行标题确实应该是可选的。


不幸的是,像这样的东西:单元格: | 单元格 单元格 ;单元格:TD TEXT CLOSE_TD ;不起作用! :( 我不知道如何使空规则起作用。我甚至尝试了 {$$=NULL;} 也没有帮助。 - Milad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接