有状态解析的替代方案

时间:2011-09-25 23:55:16

标签: algorithm language-agnostic state

我不喜欢有状态解析。在我看来应该有一个更好的方法。 有吗?

让我举例说明。假设我正在解析一个文本文件(在这种情况下是YAML,但它可以是纯文本或XML。我正在做一个简单的琐事游戏;我的游戏将包含set的{​​{1}} s,每个都有两个或多个question s。在YAML中,我可能会将我的文件结构如下:

answer

(我有一段时间没有使用过YAML,如果它是伪YAML就道歉。)当我解析时,如果我读了当前行并看到“回答:......”,我必须知道我在一个问题的答案中。

这往往是非常有状态的代码,例如:

set:
  name: math questions
  question:
    text: 1 + 1 = ?
      answer: 3
      answer: 4
      best-answer: 2
  question:
    text: 2 * 3 = ?
      answer: 5
      best-answer: 6
set:
  name: chemistry questions
  question:
    text: the valence of a Chlorine free radical is?
      answer: 1
      answer: 0
      best-answer: -1
  question:
    text: Xeon is a noble gas
      best-answer: true
      answer: false

在解析的任何一点,我们都需要一个对当前对象的引用,它可以嵌套在其他几个对象中。

部分问题可能是我的主循环逐行迭代在每一行上。另一种方法可能是只读取该行,并根据它是什么,再读几个必要的线条。

再次,我的问题:是否有一种无状态的方式来解析数据?我感觉可能存在一种比我平时更清晰,更容易阅读/理解/编码的方法所有文本行的有状态for循环。

4 个答案:

答案 0 :(得分:1)

您所描述的是一种或多或少的状态机驱动的解析方法:您遍历文件的行,并且状态变量跟踪您在解析树中的位置。您可能会发现以程序堆栈的形式使用recursive descent parsing更容易,更清晰,其中大部分状态是隐含的。正如其他人指出的那样,解析本质上是有状态的,但递归下降可以让你明确地保持较少的状态。

答案 1 :(得分:1)

你显然不是在寻找“无状态”解析,而是寻求非命令性的纯函数解析。当然总有一种状态,但是通过功能方法,你的状态是完全隐含的。

查看"Functional pearls: monadic parsing in Haskell"文章,查看各种类似Parsec的解析组合库,这些库甚至包括Java和C ++等非常强制性的语言。

答案 2 :(得分:0)

  

另一种方法可能是只读取该行,并根据它的含义,根据需要读取更多行。

你刚刚描述了“给定某种状态,做某事”。这是一种有状态的方法。

  

再次,我的问题是:是否存在无状态解析数据的方法?

解析本质上是有状态的。数据的含义取决于上下文。背景是国家。

有一个原因是编译器的入门课程从有限状态机开始。

答案 3 :(得分:0)

解析的概念意味着某些部分是一种类型的令牌,其他部分是另一种,而其他部分根本无效。你怎么会知道如果没有保持某种状态说“好吧,我现在正在解析foo ......这就是我应该拥有的”?