簡體   English   中英

Sprache:語法中的左遞歸

[英]Sprache: left recursion in grammar

我正在為類似於SQL的語言開發解析器,我遇到了創建一些語言規則的問題,例如: expression IS NULLexpression IN (expression1, expression2, ...) ,邏輯和數學運算符之間具有優先級。

我上傳了一個GitHub測試項目https://github.com/anpv/SpracheTest/,但這個變種並不好。
我試圖使用以下規則:

private static readonly Parser<AstNode> InOperator =
    from expr in Parse.Ref(() => Expression)
    from inKeyword in Parse.IgnoreCase("in").Token()
    from values in Parse
        .Ref(() => Expression)
        .DelimitedBy(Comma)
        .Contained(OpenParenthesis, CloseParenthesis)
    select new InOperator(expr, values);

private static readonly Parser<AstNode> IsNullOperator =
    from expr in Parse.Ref(() => Expression)
    from isNullKeyword in Parse
         .IgnoreCase("is")
         .Then(_ => Parse.WhiteSpace.AtLeastOnce())
         .Then(_ => Parse.IgnoreCase("null"))
    select new IsNullOperator(expr);

private static readonly Parser<AstNode> Equality =
    Parse
        .ChainOperator(Eq, IsNullOperator.Or(InOperator).Or(Additive), MakeBinary);

它在代碼中拋出ParseException ,如ScriptParser.ParseExpression("1 is null")ScriptParser.ParseExpression("1 in (1, 2, 3)"): "Parsing failure: Left recursion in the grammar."

我怎樣才能預測Expression,或者是否存在其他變體來解決這個問題?

答案是,不幸的是,Sprache無法解析左遞歸語法。 我偶然發現源代碼中的評論,討論了在研究這個問題時我是如何刪除對左遞歸語法的錯誤支持(這也是我如何找到你的問題) - 請參閱源代碼

為了解決這個問題,您需要重新組織解析方式。 例如,如果您正在編寫一個簡單的表達式解析器,那么這是您必須處理的常見問題。 在網上搜索有很多關於如何從語法中刪除左遞歸的討論,特別是對於表達式。

在你的情況下,我希望你需要做類似的事情:

term := everything simple in an expression (like "1", "2", "3", etc.)
expression := term [ IN ( expression*) | IS NULL | "+" expression | "-" expression | etc.]

或類似 - 基本上 - 你必須自己解除遞歸。 通過這樣做,我能夠解決表達式問題。 我懷疑任何基本的編譯器書可能都有關於如何“規范化”語法的部分。

它使你從解析器返回的任何對象構建更多的痛苦,但是在select語句中而不是“選擇新的表達式(arg1,arg2)”我將其更改為函數調用,並且函數決定根據參數的內容返回特定對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM