日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

在C#中使用Irony实现SQL语句的解析

發(fā)布時(shí)間:2023/12/4 C# 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在C#中使用Irony实现SQL语句的解析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在上一篇博文?LogoSharp:Logo語言的C#實(shí)現(xiàn)中,我介紹了LOGO語言的C#實(shí)現(xiàn),在該項(xiàng)目中,我使用了.NET下的語法解析框架:Irony。Irony框架最開始的時(shí)候是由Roman Ivantsov發(fā)布在codeplex上的一個(gè)開源項(xiàng)目,它使用MIT協(xié)議開源。由于2017年的時(shí)候,微軟關(guān)閉了codeplex服務(wù),為了讓這個(gè)優(yōu)秀的項(xiàng)目能夠繼續(xù)為人所用,我將其復(fù)制到了我的Github賬號(hào)下,并將其移植到NET Standard 2.0,地址是:https://github.com/daxnet/irony。于是,Irony目前可以在.NET Core下使用了。事實(shí)上,Github中有很多Irony的版本,但大多數(shù)都不支持.NET Core。

不僅如此,我還在Azure DevOps上配置了持續(xù)集成,因此,你可以通過NuGet很方便地使用Irony。Irony相關(guān)的NuGet包有兩個(gè),你需要在你的項(xiàng)目中同時(shí)安裝以下兩個(gè)NuGet包:

12Install-Package Irony.NetCore -Version 1.1.11Install-Package Irony.Interpreter.NetCore -Version 1.1.11

接下來,我介紹一下如何用Irony實(shí)現(xiàn)一個(gè)語法解析器,我們以SQL語句為例進(jìn)行介紹。

所有使用Irony框架的語法定義,都必須繼承于Grammar類,并加上Language特性。以下就是我定義的一個(gè)SQL語句的語法,我稱之為“Mini SQL”,因?yàn)樗壳爸恢С諷ELECT語句,而且不支持WHERE子句。

12345678910111213141516171819[Language("Mini SQL", "1.0", "A SQL Sample")]public class MiniSqlGrammar : Grammar{????public MiniSqlGrammar()????????: base(false)????{????????var identifier = new IdentifierTerminal("Identifier");????????var table = new NonTerminal("table");????????var fields = new NonTerminal("fields");????????var sql_statement = new NonTerminal("SQL");????????table.Rule = identifier;????????fields.Rule = "*" | MakePlusRule(fields, ToTerm(","), identifier);????????sql_statement.Rule = "SELECT" + fields + "FROM" + table;????????Root = sql_statement;????}}

代碼非常簡單,也很容易理解,它可以使用人類比較容易讀懂的語法定義規(guī)則進(jìn)行語法定義。這里簡單介紹一下上面的代碼:

  • Language特性用于描述我們自定義的語法

  • 語法類需要繼承于Grammar類

  • 基類構(gòu)造函數(shù)的false參數(shù)表示我們的語言是大小寫不敏感的

  • 所有的程序語言標(biāo)識(shí)符都可以用IdentifierTerminal進(jìn)行定義,Irony已經(jīng)自帶了標(biāo)識(shí)符的識(shí)別邏輯,非常簡單

  • table是一個(gè)標(biāo)識(shí)符

  • fields可以是*,也可以是由一些標(biāo)識(shí)符通過逗號(hào)分隔的一個(gè)列表

  • SQL語句由四個(gè)部分組成:SELECT關(guān)鍵字、fields字段列表、FROM關(guān)鍵字以及table數(shù)據(jù)表名

  • Root=sql_statement表示語言的解析入口就是SQL語句

編譯通過后,我們就可以使用這個(gè)語法進(jìn)行SELECT語句的解析了。

Irony有一個(gè)非常不錯(cuò)的功能,就是它提供一個(gè)用戶界面,用來測試我們定義的語法。這個(gè)用戶界面是一個(gè)Windows Forms的應(yīng)用程序,我也將其發(fā)布到我的Github賬號(hào)下,地址是:https://github.com/daxnet/irony-explorer。下載以后編譯執(zhí)行GrammarExplorer項(xiàng)目,就可以打開這個(gè)測試界面。在測試界面中,打開包含有自定義語法的.NET DLL,就可以將其添加到Grammar Explorer中。例如,下圖展示了我用Grammar Explorer測試上面的SQL語法的界面效果:

在Grammar Explorer中,你可以看到我們自定義語法是否存在錯(cuò)誤,還可以使用一個(gè)具有代碼著色功能的編輯器進(jìn)行測試,點(diǎn)擊Parse按鈕,即可生成語法解析樹。

使用Irony進(jìn)行語法解析的基本步驟是:

  • 基于語法(Grammar)定義,創(chuàng)建語言數(shù)據(jù)(Language Data)

  • 基于語言數(shù)據(jù),產(chǎn)生解析器(Parser)

  • 使用解析器,解析輸入的字符串,生成語法樹

  • 遍歷語法樹,執(zhí)行相應(yīng)的程序邏輯

  • 下面的代碼展示了這一過程:

    123456789101112131415161718192021222324252627282930313233343536373839404142sealed class SqlParser{????private static readonly LanguageData languageData = new LanguageData(new MiniSqlGrammar());????private static readonly Parser parser = new Parser(languageData);????private readonly List<string> parsedFields = new List<string>();????public void Execute(string command)????{????????var tree = parser.Parse(command);????????if (tree.HasErrors())????????{????????????return;????????}????????ParseTree(tree.Root);????}????private void ParseTree(ParseTreeNode node)????{????????switch (node.Term.Name)????????{????????????case "SQL":????????????????foreach (var child in node.ChildNodes)????????????????{????????????????????ParseTree(child);????????????????}????????????????break;????????????case "fields":????????????????foreach (var child in node.ChildNodes)????????????????{????????????????????parsedFields.Add(child.Token.Text);????????????????}????????????????break;????????????case "table":????????????????ParsedTable = node.ChildNodes[0].Token.Text;????????????????break;????????}????}????public IEnumerable<string> ParsedFields => parsedFields;????public string ParsedTable { get; private set; }}

    SqlParser會(huì)基于我們自定義的語法類,生成一個(gè)Irony的Parser對(duì)象,然后使用Parse方法來解析傳入的SQL語句,并產(chǎn)生語法解析樹。之后,就可以根據(jù)樹狀結(jié)構(gòu)來解析語句中的每一個(gè)部分,并執(zhí)行相應(yīng)的操作。

    最后,就是使用這個(gè)SqlParser類來解析SQL語句并得到結(jié)果。代碼如下:

    123456789101112static void Main(string[] args){????var sqlParser = new SqlParser();????sqlParser.Execute("SELECT firstName, LastName FROM tbl_students");????Console.WriteLine($"獲得的數(shù)據(jù)表: {sqlParser.ParsedTable}");????Console.WriteLine("獲得的字段:");????foreach (var field in sqlParser.ParsedFields)????{????????Console.WriteLine(field);????}}

    代碼很簡單:調(diào)用SqlParser的Execute方法來解析給定的SQL語句,解析結(jié)果會(huì)分別保存在SqlParser的ParsedTable和ParsedFields兩個(gè)屬性中,上面的控制臺(tái)程序只需要輸出這兩個(gè)結(jié)果就行了。在實(shí)際應(yīng)用中,可以通過ParsedTable來獲取某一種類型的對(duì)象列表,然后通過ParsedFields來投影列表中每個(gè)對(duì)象的屬性,從而得到基于C#的一系列對(duì)象來執(zhí)行SQL查詢的效果。

    本案例執(zhí)行結(jié)果如下:

    本文簡要介紹了.NET語法解析框架Irony的使用,并通過SQL語句解析的案例,介紹了Irony使用的一些技巧與步驟。就SQL語句而言,它的定義還是相對(duì)比較復(fù)雜的,不可能單靠一篇博客就能完全覆蓋所有內(nèi)容,也是因?yàn)檫@個(gè)原因,本文也沒有涉及WHERE子句的設(shè)計(jì),但I(xiàn)rony框架是完全可以做到這一點(diǎn)的。事實(shí)上,在Irony Explorer項(xiàng)目中,就有一個(gè)IronyExplorer.Samples的工程,其中包含了很多編程語言語法定義的案例代碼,比如Java、C#、SQL等,有興趣的可以參考。Irony框架本身已經(jīng)幫我們做了很多工作,比如大小寫敏感的特性,比如運(yùn)算符優(yōu)先級(jí)的定義,比如標(biāo)識(shí)符、整數(shù)、小數(shù)、正負(fù)數(shù)的定義,再比如塊注釋與行注釋的處理等等。在我用C#實(shí)現(xiàn)LOGO語言時(shí),基本上也是按照上面所述步驟進(jìn)行編寫和測試,因此,我就不再另起篇幅來介紹LOGO語言的語法定義了。

    原文地址:https://sunnycoding.cn/2019/07/11/sql-parser-with-irony-in-csharp/


    .NET社區(qū)新聞,深度好文,歡迎訪問公眾號(hào)文章匯總?http://www.csharpkit.com?

    總結(jié)

    以上是生活随笔為你收集整理的在C#中使用Irony实现SQL语句的解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。