本專案實作一個教學級編譯器前端,包含:
// 支援輸入範例
37
19 * 19 - 18 * 18
(19 + 18) * (19 - 18)
a + (a + 1) + (a + 2)
::= ;
::= "+" | "-" | null ;
::= ;
::= "*" | "/" | null ;
::= identifier | "(" ")" | number ;
⇒ ⇒ "-" ⇒ number "*" "-" ⇒ number "*" number "-" number "*" ⇒ number "*" number "-" number "*" number
var lexer = new LexicalAnalyzerExpression();
lexer.SetSourceCode("19 * 19 - 18 * 18");
var tokens = lexer.Analyze();
Token 結構:`[值] $[類別] $[行,列] $[是否錯誤] $[描述]`
[19] $[Number] $[0,0] $[False] $[] [*] $[Multiply] $[0,3] $[False] $[] [19] $[Number] $[0,5] $[False] $[] [-] $[Minus] $[0,8] $[False] $[] [18] $[Number] $[0,10] $[False] $[] [*] $[Multiply] $[0,13] $[False] $[] [18] $[Number] $[0,15] $[False] $[]
var parser = new SyntaxParserExpression();
parser.SetTokenList(tokens);
var syntaxTree = parser.Parse();
語法樹結構 (縮排表示):
├─ │ ├─ └─number(19) │ └─ ├─* └─ └─number(19) └─ ├─- └─ ...
為各節點賦予語義動作 (遞歸自頂向下):
偽碼:
SyntaxTree SemanticAnalyze(Node root)
{
switch(root.Type)
{
case Expression: return Calc(SemanticAnalyze(root[0]), SemanticAnalyze(root[1]));
case PlusOpt: root.Parent.ReplaceChild(root, root.Children); break;
case Plus: return Calc(SemanticAnalyze(root.Parent[0]), SemanticAnalyze(root.Parent[2]));
// ...
}
}
上例最終得結果 **37**。
工具支援:
LexicalAnalyzer 與 SyntaxParser 原始碼
後續文章將逐步釋出:
作者:bitzhuwei | 出處:https://www.cnblogs.com/bitzhuwei