跳轉到內容

Irony - 語言實現工具包/語法/終結符

來自華夏公益教科書,開放書籍,開放世界

終結符是掃描器識別的標記,並傳遞給解析器。Irony 提供了一些關鍵的終結符,這些終結符幾乎存在於每一種程式語言中(註釋、識別符號、字串文字等)。

標準終結符

[編輯 | 編輯原始碼]

這些終結符已在 Grammar 基類中定義

Empty

用於識別非終結符中的可選元素

term.Rule = term1 | Empty;

Eof

標識檔案結束(在語法規則中使用 Eof 是可選的,解析器會自動將此符號作為前瞻新增到 Root 非終結符)

LineStartTerminal

用於錯誤標記

SyntaxError

用於錯誤標記

以下用於縮排敏感語言,如 Python。它們不是由掃描器生成的,而是由掃描後和解析前 CodeOutlineFilter 生成的

NewLine

Indent

表示縮排

Dedent

表示縮排的結束

Eos

語句結束終結符 - 用於縮排敏感語言,用於指示語句結束。它並不總是與 CRLF 字元同步,CodeOutlineFilter 會根據傳入內容標記中的行/列資訊仔細生成 Eos 標記(以及 Indent 和 Dedent)。


CommentTerminal

[編輯 | 編輯原始碼]

註釋終結符允許您輕鬆地宣告語言中註釋的定義。大多數語言至少提供行註釋,但許多語言允許使用塊註釋的概念。

要設定任何一種註釋終結符,只需宣告一個新的 CommentTerminal 型別並設定開始和結束字元。

行註釋示例

CommentTerminal LINE_COMMENT = new CommentTerminal("LINE_COMMENT", "--", "\n", "\r\n");

塊註釋示例

CommentTerminal BLOCK_COMMENT = new CommentTerminal("BLOCK_COMMENT", "/*", "*/");

如果您希望掃描器基本上忽略您的註釋終結符,以便它們不會出現在您的解析樹中,那麼將它們新增到非語法終結符列表中。

NonGrammarTerminals.Add(BLOCK_COMMENT);
NonGrammarTerminals.Add(LINE_COMMENT);


ConstantTerminal

[編輯 | 編輯原始碼]

此終結符允許在輸入語言中宣告一組常量。

當常量符號看起來不像普通識別符號時,應該使用它;例如,在 Scheme 中,#t、#f 是真/假常量,它們不符合 Scheme 識別符號模式。

ConstantTerminal CONSTANT = new ConstantTerminal("CONSTANT");
CONSTANT.Add("#t", true);
CONSTANT.Add("#f", false);

DateLiteral

[編輯 | 編輯原始碼]
DataLiteralBase DATETIME = new DataLiteralBase("DATETIME", TypeCode.DateTime);


IdentifierTerminal

[編輯 | 編輯原始碼]

識別符號終結符將識別原始碼中以正常標準方式表示變數的標記(即以下劃線或字母開頭,僅包含字母、數字和下劃線),但可以配置為識別其他非標準的變量表達方式。

IdentifierTerminal IDENTIFIER = new IdentifierTerminal("IDENTIFIER");


NumberLiteral

[編輯 | 編輯原始碼]

內建數字文字終結符可以識別多種型別的數字,從簡單的整數(例如 1)到小數(例如 1.0)到以科學記數法表示的數字(例如 1.1e2)。

NumberLiteral NUMBER = new NumberLiteral("NUMBER");


StringLiteral

[編輯 | 編輯原始碼]

使用此終結符識別字符串文字;只需設定開始/結束字元。

StringLiteral STRING = new StringLiteral("STRING", "\"", StringOptions.IsTemplate);

StringLiteral 終結符的一個有用屬性是它能夠將字串視為模板,並解析其中嵌入的表示式,如 Ruby 中那樣。只需設定 IsTemplate 選項,然後為它提供一個設定類,告訴它如何查詢這些表示式。您的表示式根(用於解析嵌入表示式的非終結符)也需要新增到 SnippetRoots 列表中。

在此示例中,建立了一個新的 StringTemplateSettings,其中任何用花括號({ 和 })包圍的表示式都被視為表示式(“表示式”是非終結符,充當根表示式)

StringTemplateSettings stringTemplateSettings = new StringTemplateSettings();
stringTemplateSettings.StartTag = "{";
stringTemplateSettings.EndTag = "}";
stringTemplateSettings.ExpressionRoot = expression;

this.SnippetRoots.Add(expression);

STRING.AstNodeConfig = stringTemplateSettings;


關鍵字

[編輯 | 編輯原始碼]

關鍵字終結符可以以兩種方式宣告:在變數宣告中顯式使用 ToTerm 方法,或在生產規則中隱式宣告。

在 SQL 中顯式宣告關鍵字 SELECT,然後在 SELECT 語句生產中使用它

KeyTerm SELECT = ToTerm("select");

selectStatement.Rule = SELECT + optionalSelectArgs + FROM + ... + SEMICOLON;

在 SQL 中的 SELECT 語句生產中隱式宣告

selectStatement.Rule = ToTerm("select") + optionalSelectArgs + ToTerm("from") + ... + ToTerm(";");


運算子

[編輯 | 編輯原始碼]

您以與關鍵字相同的方式定義運算子作為終結符。您可以使用 Grammar 基類中的 RegisterOperators 方法定義這些運算子的結合性和優先順序。

示例指示簡單二元運算子的結合性和優先順序

RegisterOperators(6, Associativity.Right, POW);
RegisterOperators(5, MULT, DIV);
RegisterOperators(4, PLUS, MINUS);


標點符號

[編輯 | 編輯原始碼]

您可以使用 Grammar 基類中的 MarkPunctuation 方法告訴掃描器和解析器您的語言中哪些終結符用作標點符號。通常,這些是左括號和右括號字元或花括號字元等終結符。

示例指示哪些終結符充當標點符號(假設 LPAREN、RPAREN、LBRACE 和 RBRACE 是預先定義的 KeyTerm 物件)

MarkPunctuation(LPAREN, RPAREN, LBRACE, RBRACE);


自定義終結符

[編輯 | 編輯原始碼]

如果您對內建的終結符不滿意,可以建立自己的終結符。只需擴充套件 Irony.Parsing.Terminal,然後開始使用。如果您需要對內建終結符進行一些調整以適應您的語言,但不能透過簡單地設定現有屬性來做到這一點,您也可以擴充套件內建終結符。

華夏公益教科書