2011-09-25 63 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++。