2016-09-04 97 views
-2

我一直在嘗試編寫一種語言翻譯器,使用flex和yacc與C.通常我以某種方式完成它,但我發現自己不理解一些重要的事情以完成它。yacc語法規則的語義

所有我似乎無法理解下面的語法規則是如何工作的

聲明列表→申報表聲明

本地報關→本地報關申報的第一

我在這裏看到一個例子How do i implement If statement in Flex/bison在「陳述語句」,引用:

struct AstElement* makeStatement(struct AstElement* result, struct AstElement* toAppend) 
{ 
if(!result) 
{ 
    result = checkAlloc(sizeof(*result)); 
    result->kind = ekStatements; 
    result->data.statements.count = 0; 
    result->data.statements.statements = 0; 
} 
assert(ekStatements == result->kind); 
result->data.statements.count++; 
result->data.statements.statements = realloc(result->data.statements.statements, result->data.statements.count*sizeof(*result->data.statements.statements)); 
result->data.statements.statements[result->data.statements.count-1] = toAppend; 
return result; 
} 

但我不知道它是否與其他規則一樣,另外,我想了解我在做什麼,而不僅僅是複製。

我的第二個問題是在下面的語法規則

聲明→型規格標識; | type-spec id [num];

類型說明符→INT

我在這裏獲得了整點,它是什麼,它應該做什麼等等,但我無法將認識轉化爲代碼和C

+1

您應該編寫代碼,以便在您的程序符合規則時執行任​​何操作。 – immibis

+0

嗯,我知道這很多。我覺得我需要的代碼是特定的,但是。 – codeNewbie

+0

當程序符合規則時,您希望程序執行什麼操作? – immibis

回答

2

在Yacc中,您可以爲解析器遇到的任何規則提供代碼,並且該代碼(通常)爲派生的父規則提供一個值,最後該值爲已轉換的程序。對於第二個示例:

聲明→type-spec id; | type-spec id [num];

類型說明符→INT

第二條規則或許應該返回的東西來識別遇到int類型;這可能是字符串本身或某種類型的內部標識符。因此,它應該是這樣的:

type-specifier → int { $$ = $1 }; 

它說的type-specifier值是什麼詞法分析器發送令牌int

然後,假設它已經從其它規則導出的,即一個是清楚的東西,用於宣佈一個簡單的變量或數組,則YACC規則可以是這樣的:

declaration → type-spec id   { addSymbol($1,$2); } ; 
      | type-spec id [ num ] { addSymbolForArray($1,$2,$3); }; 

其中兩個函數分別爲符號表的內部表示添加一個新符號,類型(如果您需要在符號表中的某個位置編碼該類型),標識符以及數組中的大小。

同樣適用於任何規則,但有時候規則使得大部分任何東西,因爲(可能)你:

聲明列表→申報表聲明

的聲明被攻克內部declaration派生規則。

請記住,這是一個簡單的建議,讓事情變得更加清晰,有很多事情需要關注。但是原則就在那裏:問問自己,當規則被解析時你需要做什麼,它對你的語義意味着什麼?

+0

非常感謝您的回答。它確實爲我提供了一些更清晰的東西。如果您有一些時間,請查看我對我的問題的最新評論。我試圖弄清楚是否應該將類似於代碼,因爲這些項目非常相似。 – codeNewbie