2

我想知道語法分析和語義分析是如何工作的。語法分析和語義分析

我完成了解釋器的詞法和語法結構。

現在我要實現一個遞歸下降(自上而下)分析器這個語法

例如,我有以下的語法:

<declaration> ::= <data_type> <identifier> ASSIGN <value> 

所以我編寫它像這樣(在Java中):

public void declaration(){ 
    data_type(); 
    identifier(); 
    if(token.equals("ASSIGN")){ 
     lexer(); //calls next token 
     value(); 
    } else { 
     error(); 
    } 
} 

假設我有三個數據類型的:int,字符串和布爾。由於每種數據類型的值是不同的(例如,只有布爾值爲true或false),我怎樣才能確定它是否正確地適合數據類型?我的代碼的哪一部分可以確定?

我想知道我會把代碼:

1.) call the semantic analysis part of my program. 
2.) store my variables into the symbol table. 

做語法分析和語義分析發生在同一時間? 或者我需要先完成語法分析,然後進行語義分析?

我真的很困惑。請幫忙。

謝謝。

回答

1

可以做語法分析(解析)和語義分析(例如,檢查之間的協議)在同一時間。例如,當declaration()調用data_type()時,後者可能會返回一些內容(稱爲DT),以指示聲明的類型是Int,String還是Boolean。類似地,value()可以返回指示解析類型的東西(VT)。然後,聲明()將簡單地比較DT和VT,並且如果它們不匹配則引發錯誤。 (或者,value()可以採用一個表示聲明類型的參數,並且it可以進行檢查。)

但是,您可能會發現將兩個階段完全分開更容易。爲此,您通常會在解析階段構建一個解析樹(或抽象語法樹)。因此,您的最高層會調用(例如)program()來解析整個程序,該程序將返回一個表示程序語法的樹,並將該樹傳遞給semantic_analysis()例程,該例程將遍歷樹,提取相關信息並強制執行語義約束。

0

簡短的回答是:它取決於您的編程語言的定義。而且,由於您只指定了一個派生規則和三個本地類型,因此無法知道。例如,如果你的編程語言允許向前聲明像C++代碼的下方,然後處理的函數聲明(富)完成推導規則不知道變量序列

class Tree { 
public: 
    int foo(void) 
    { 
     return serial; 
    } 
    int serial; 
}; 

事實上,現代編譯器的類型將語法分析階段與語義分析階段分開。首先執行語法分析階段,確保輸入程序與語言的上下文無關語法一致。此外,還生產了A bstract S yntax T ree(AST)。請注意AST和分析樹之間的差異,如討論in this SO post。語義分析階段然後遍歷AST並檢查類型不匹配等等。儘管如此,玩具編程語言有時可以將語義和語法分析結合在一起。當使用遞歸下降解析器時,應該有相關的遞歸調用返回一個類型。