将前一个状态存储为全局变量是否可以接受?

时间:2012-01-05 01:23:37

标签: flex-lexer lex lexical-analysis

设计词法分析器/解析器组合的最大问题之一是设计分析器时过于热心。 (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}中驻留的结构化数据。

考虑到这些限制,我正在考虑做以下事情:

  1. CODE1开始条件结果中输入<INITIAL>州 在致电:
    • yy_push_state(CODE_STATE)
    • yy_push_state(CODE_CODE1_STATE)
    • (对CODE1状态标识符的内容执行某些操作,如果存在此类内容)
    • yy_push_state(SUBCODE_STATE)(告诉分析人员期望属于CODE_CODE1_STATE的SUBCODE个状态。这是分析器开始伪装成解析器的地方。
  2. <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
  3. <SUBCODE1_STATE>范围内,\r\n会致电yy_pop_state()。如果存在延续记录(这是与所有文本匹配的最高范围的模式),则调用yy_push_state(continuation_record_states[previous_state]),将我们带回 2 中的范围。 continuation_record_states[]将每个状态映射到其解析器使用的连续记录状态。
  4. 正如你所看到的,这是非常复杂的,这使我得出结论,我正在大大过度复杂化任务。

    问题

    1. 对于缺乏极其清晰标记的国家来说,我的建议解决方案是否可以接受?
    2. 鉴于我想使用flex标记输入,有没有办法在没有启动条件的情况下这样做?
    3. 我遇到的最大问题是每条记录(以(SUB)CODE前缀开头)是唯一的,但(SUB)CODE前缀后面出现的信息不是。因此,似乎必须具有这样的多个状态,并且抽象CODE_STATESUBCODE_STATE状态将充当每个具体SUBCODE[0-9]+_STATECODE[0-9]+_STATE状态的分组。

1 个答案:

答案 0 :(得分:1)

我会看看OMeta解析器如何处理这些事情。