2011-09-25 43 views
1

我不喜欢有状态解析。在我看来,应该有更好的方法。 有吗?状态解析的替代方案

让我来举例说明。假设我正在解析一个文本文件(在这种情况下是YAML,但它可以是纯文本或XML,我正在制作一个简单的琐事游戏;我的游戏将包含set s的question s,每个包含两个或多个answer 。■在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 

(我没有用YAML一段时间,道歉,如果这是假YAML)。当我解析,如果我读当前行看“的回答:......,”我知道,我在一组问题的回答

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

if (currentLine starts with "answer") 
    currentQuestion.addAnswer(...) 
else if (currentLine starts with "question") 
    currentQuestion = new question 
... 

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

部分可能是我的主循环迭代在每一行,一行行。另一种方法可能是阅读该行,并根据其内容,根据需要再阅读更多行。

如此反复,我的问题:有解析数据的无状态的方法是什么?我有一种感觉,可能存在的方法比我在所有文本行上通常的有状态循环更清晰,更易于阅读/理解/编码。

+0

使用“Parser”monad可以被认为是无状态的。他们可以是令人心动的东西,但肯定值得一看。 – Enigmativity

+0

@Enigmativity我不熟悉那些。你能分享一个链接吗? – ashes999

+0

这是一对[MSDN路径](http://blogs.msdn.com/b/lukeh/archive/2007/08/19/monadic-parser-combinators-using-c-3-0.aspx)&[devhawk ](http://devhawk.net/2008/08/01/monadic-philosophy-part-4-the-parser-monad-in-f/) – Enigmativity

回答

0

另一种方法可能是只读行,并根据其内容,根据需要再读几行。

你刚才所描述的“给予一定的状态,做一些事情。”那就是有状态的方法。

再次,我的问题:是否有无状态的方式来解析数据?

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

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

0

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

1

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

+0

这个答案基本上是“建立一个上下文无关语法并解析它吗?” – ashes999

+0

@ ashes999我想 - 但我认为他已经有一个语法(上下文无关或其他),并使用状态机解析它。您也可以对没有上下文的语法进行递归下降分析。 –

1

你显然不是为了“无状态”解析,而是为了一个非强制性的纯函数解析。当然,总是有一种状态,但是一种功能性的方法,你的状态是完全隐含的。

看看"Functional pearls: monadic parsing in Haskell"文章,并查看各种类似Parsec的解析组合器库,这些库甚至包含非常紧迫的语言,如Java和C++。