设计词法分析器/解析器组合的最大问题之一是设计分析器时过于热心。 (f)lex不具有解析器逻辑,有时会干扰迷你解析器的设计(通过yy_push_state()
,yy_pop_state()
和yy_top_state()
。
我的目标是解析表单文档:
CODE1 this is the text that might appear for a 'CODE' entry
SUBCODE1 the CODE group will have several subcodes, which
may extend onto subsequent lines.
SUBCODE2 however, not all SUBCODEs span multiple lines
SUBCODE3 still, however, there are some SUBCODES that span
not only one or two lines, but any number of lines.
this makes it a challenge to use something like \r\n
as a record delimiter.
CODE2 Moreover, it's not guaranteed that a SUBCODE is the
only way to exit another SUBCODE's scope. There may
be CODE blocks that accomplish this.
最后,我已经确定项目的这一部分最好留给词法分析器,因为我不想创建匹配每一行的模式(并标识连续记录)。部分原因是我希望词法解析器知道每一行的内容,而不需要结合自己的标记化逻辑。也就是说,如果我匹配^SUBCODE[ ][ ].{71}\r\n
(所有记录都被阻止在80个字符的记录中),我将无法利用flex的强大功能来标记.{71}
中驻留的结构化数据。
考虑到这些限制,我正在考虑做以下事情:
CODE1
开始条件结果中输入<INITIAL>
州
在致电:
yy_push_state(CODE_STATE)
yy_push_state(CODE_CODE1_STATE)
CODE1
状态标识符的内容执行某些操作,如果存在此类内容)yy_push_state(SUBCODE_STATE)
(告诉分析人员期望属于CODE_CODE1_STATE的SUBCODE
个状态。这是分析器开始伪装成解析器的地方。 <SUBCODE1_STATE>
开始条件嵌套如下:<CODE_STATE>{ <CODE_CODE1_STATE> { <SUBCODE_STATE>{ <SUBCODE1_STATE> { (perform actions based on the matching patterns) } } }
。它还将全局previous_state
变量设置为yy_top_state()
,即SUBCODE1_STATE
。<SUBCODE1_STATE>
范围内,\r\n
会致电yy_pop_state()
。如果存在延续记录(这是与所有文本匹配的最高范围的模式),则调用yy_push_state(continuation_record_states[previous_state])
,将我们带回 2 中的范围。 continuation_record_states[]
将每个状态映射到其解析器使用的连续记录状态。正如你所看到的,这是非常复杂的,这使我得出结论,我正在大大过度复杂化任务。
我遇到的最大问题是每条记录(以(SUB)CODE
前缀开头)是唯一的,但(SUB)CODE
前缀后面出现的信息不是。因此,似乎必须具有这样的多个状态,并且抽象CODE_STATE
和SUBCODE_STATE
状态将充当每个具体SUBCODE[0-9]+_STATE
和CODE[0-9]+_STATE
状态的分组。
答案 0 :(得分:1)
我会看看OMeta解析器如何处理这些事情。