2010-06-11 57 views
2

我正在寫一個C/C++/...構建系統(我明白這是瘋狂;)),並且我在設計解析器時遇到問題。解析器與範圍和條件

我的「食譜」是這樣的:

global 
{ 
    SOURCE_DIRS src 
    HEADER_DIRS include 
    SOURCES bitwise.c \ 
      framing.c 
    HEADERS \ 
      ogg/os_types.h \ 
      ogg/ogg.h 
} 
lib static ogg_static 
{   
    NAME ogg 
} 
lib shared ogg_shared 
{ 
    NAME ogg 
} 

(基於超級簡單libogg源代碼樹這之中)

#是註釋,\是「換行逃逸」,這意味着該行繼續在下一行(參見QMake syntac)。 {}是範圍,就像在C++中一樣,全局是適用於每個「目標」的設置。這是所有的背景,而不是有關...我真的不知道如何與我的範圍工作。我需要能夠有多個範圍,也有條件處理的一種形式,在該行:

win32:DEFINES NO_CRT_SECURE_DEPRECATE 

解析功能將需要知道它在什麼級別的範圍,稱自己無論何時範圍增加了。大括號的位置也有問題(global {global{或如示例中所示)。

如何使用標準C++和STL來解決這個問題?我知道這是一個很大的工作,這正是我需要一個好的起點的原因。謝謝!

我已經是整個ifstream和內部字符串/ stringstream存儲,所以我可以閱讀每個單詞的單詞。

+2

這需要使用通常的編譯器/解釋器方法,並且應該使用標準工具處理(請參閱http://stackoverflow.com/questions/1669/learning-to-write-a-compiler並搜索「解析器發電機「等)。 – dmckee 2010-06-11 18:39:04

+0

相關鏈接肯定會幫助我形成一個想法。 – rubenvb 2010-06-11 19:00:30

回答

2

我會建議(這是或多或少的編譯器教科書)你分階段接近問題。這樣做可以將事情分解,使問題在每個階段更易於管理。

首先關注詞法分析階段。你的興趣階段應該採用原始文本並給你一些令牌,比如單詞和特殊字符。詞法分析階段可以處理續行,並根據需要處理空白或註釋。通過處理的空白,詞法分析器可以簡化您的解析器的任務:你可以寫的詞法分析器,這樣global{global {,甚至

global
{

都將產生兩個標記:一個代表global,一個表示{

另請注意,如果您遇到錯誤,詞法分析器可以將行號和列號添加到令牌上以備後用。

一旦你有一個很好的令牌流,你的解析階段工作。解析器應該採用該序列的標記並構建一個抽象語法樹,該語法樹模擬文檔的語法結構。在這一點上,你不應該擔心ifstreamoperator>>,因爲詞法分析器應該已經爲你做了所有的閱讀。

您已經表示有興趣在您看到範圍後遞歸地調用解析函數。這絕對是一種方式。正如你所看到的,你必須反覆做出的設計決定是,你是否真的想遞歸地調用相同的解析函數 (允許像global { global { ... } }這樣的結構,你可能不想在語法上禁止),或者你是否想要定義一個稍微(或甚至顯着)不同的適用於範圍內的語法規則集。

一旦你發現自己不得不改變規則:關鍵是通過重構功能來重複使用儘可能多的東西,因爲你可以在不同的語法變體之間重用。如果你繼續朝這個方向前進–使用單獨的函數,它們代表你想要處理的不同語法塊,並讓它們在需要的地方互相調用(可能遞歸)–你最終會以我們所說的遞歸下降解析器。維基百科條目有一個很好的簡單例子;見http://en.wikipedia.org/wiki/Recursive_descent_parser

如果您發現自己真的想深入研究詞法分析器和解析器的理論和實踐,我建議您獲得一本很好的編譯器教科書來幫助您。在評論中提到的堆棧溢出的話題上面會幫助您瞭解:Learning to write a compiler

+0

這就是我想要在腦海中構思的東西。哎呀,維基百科的文章(爲什麼我不看那裏:s)肯定會幫助我獲得基本知識。謝謝 – rubenvb 2010-06-13 13:39:29

0

除非項目的要點是專門學習如何編寫詞法分析器和shift-reduce解析器,否則我會推薦使用Flex和Bison,它將爲您處理大部分解析工作。編寫語法和語義分析仍然是一大堆工作,不用擔心;)

+0

嗯,我認爲這是一個「學習C++的難題」學術自我導師試錯法的事情,如果你明白我的意思:)。我認爲這是一個有價值的原因,並且必將向我展示足夠的標準庫和STL,以便抓住C++恕我直言。哎呀,我甚至會在這個過程中瞭解編譯器和鏈接器。 – rubenvb 2010-06-11 19:08:31

+0

@rubenvb:然後寫一個遞歸正常的解析器。我所知道的最簡單的邊緣實踐參考是Crenshaw教程(鏈接到1669年)。 – dmckee 2010-06-11 19:25:38

+0

@dmckee遞歸下降對於OP在他的文章中建議的複雜性的語法是否合理?我會這樣認爲瘋狂的謊言...... – user168715 2010-06-11 19:46:25

1

ANTLR(使用ANTLRWorks),之後你可以看看FLEX/BISON和其他類似lemon。那裏有很多工具,但ANTLR和flex/bison應該足夠了。我個人比較喜歡ANTLRWorks來推薦別的東西。

LATER:使用ANTLR,您可以爲variety of languages生成解析器/詞法分析器代碼。

2

boost::spirit是一個很好的遞歸下降解析器生成器,它使用C++模板作爲語言擴展來描述解析器和詞法分析器。它適用於本地C++編譯器,但不能在Managed C++下編譯。

Codeproject有一個tutorial article可能有所幫助。