HTML5技术

在.NET Core中使用Irony实现自己的查询语言语法解析器 - dax.net

字号+ 作者:H5之家 来源:H5之家 2017-06-07 18:00 我要评论( )

在之前《在ASP.NET Core中使用Apworks快速开发数据服务》一文的,.NET大神张善友为我提了个建议,可以使用Compile As a Service的Roslyn为语法解析提供支持。在此非常感激友哥给我的建议,也让我了解了一些Roslyn的知识。使用Roslyn的一个很大的好处是,框架

在之前《在ASP.NET Core中使用Apworks快速开发数据服务》一文的,.NET大神张善友为我提了个建议,可以使用Compile As a Service的Roslyn为语法解析提供支持。在此非常感激友哥给我的建议,也让我了解了一些Roslyn的知识。使用Roslyn的一个很大的好处是,框架无需依赖第三方的组件,并且Roslyn也是.NET Foundation的一个开源项目,为.NET语言提供编译服务,社区支持做的也非常出色。然而,经过一段时间的思考,我还是选择了一个折中的方案:在Apworks中使用Irony作为查询语言的语法解析器,与此同时,为查询语言语法解析提供可扩展的框架级支持。

那么问题来了:为什么我需要在Apworks中设计查询语言?Irony是什么?如何使用Irony实现自己的查询语言语法解析器?下面我就一一为大家介绍。

Apworks中的查询语言

很多体验过Apworks数据服务(Apworks Data Services)案例:TaskList的读者肯定有这样的感受:为什么每次我新建的任务项目(Task Item)都是出现在列表中不确定的位置?难道新建的任务就不应该放在最前面吗?是的,你的疑问没有错,在之前的TaskList中,的确存在这样的问题,因为那时候Apworks数据服务在返回任务列表时,还不支持查询和排序,也就是说,它只能默认以Id作为升序进行分页,返回所有的数据。当然,在最近一版的Apworks数据服务中,通过基于Irony的语法解析器,已经能够成功地支持查询和排序了。

如果你之前有仔细阅读《在ASP.NET Core中使用Apworks快速开发数据服务》一文,并按照文中的演练步骤实现过一个简单的RESTful服务的话,那么,请你重新在Visual Studio 2017中打开你的解决方案,将Apworks相关库更新到最新版本,然后不要修改任何代码,直接运行你的应用。等应用程序运行后,执行一次GET请求,URL中你就可以使用query作为查询条件输入了。比如,使用curl执行下面的命令:

curl -G ":58928/api/customers" --data-urlencode "query=name sw \"fr\""

你将得到下面的结果:

image

可以看到,数据服务返回了所有Name字段以“fr”开头的客户信息。当然,还支持排序操作。比如执行下面的命令:

curl -G ":58928/api/customers" --data-urlencode "sort=name d"

将得到下面的结果:

image

此时返回结果已经按Name字段倒序排列。

在Apworks中,查询语言支持以下操作和运算:

排序语言支持升序(用字母a表示)以及降序(用字母d表示),多个排序条件使用AND关键字连接。例如:name a AND email d,表示使用name字段做升序排序,并以email做降序排序。

以上就给大家大概介绍了一下Apworks数据服务对查询和排序的支持功能。设计这部分功能的需求是显而易见的:开发人员无需为一般的查询和排序功能自定义额外的接口。或许你会问,为何不使用已有的框架,比如OData。不错,OData的确可以提供统一的查询界面,做系统集成也会相对容易,但一方面我还是觉得OData太重,Apworks数据服务我希望能够提供更加简单便捷的功能;另一方面,看上去目前OData还不支持.NET Core(应该是不支持,我不太确定,有知道的朋友也欢迎留言指正)。

实现这套查询和排序语法,我使用的是一个.NET下开源的语法解析器生成工具集,它的名字叫做Irony。

Irony简介

Irony项目最开始是发布在微软的Codeplex代码托管服务上的,地址是:。在Codeplex上的好评数有51颗星,也已经很不错了。可惜的是,最近一次更新是在2013年12月,看起来已经停止维护了,不过之前使用了一下,感觉这个项目确实不错,不仅提供了开发库,而且还有一个图形化的语法解析器的测试工具,在写完自己的自定义语言的语法之后,还可以通过这个工具进行测试。于是,我把它迁移到了Github,成为我的一个公共repo,地址是:https://github.com/daxnet/irony。当然,我沿用了原有的MIT许可协议,并在首页的README.md中提供了原始地址(很可惜Codeplex将在年底关闭),并保留了开发者的名字。不仅如此,在一番踩坑之后,我把它迁移到了.NET Core平台。

在我的Irony Github Repo里,提供了一个非常简单的案例,就是实现四则混合运算的字符串解析,并计算最终结果。当然,这个案例也被包含在了这个项目的源代码里。大家可以自己下载查看。

Irony的一个特色就是运用了C#的运算符重载,使得语法定义借用了C#的编译功能(语法、类型检查等),简单直观,又不容易出错。比如,在如下案例中的语法定义类型中:

[Language("Expression Grammar", "1.0", "abc")] public class ExpressionGrammar : Grammar { /// <summary> /// Initializes a new instance of the <see cref="ExpressionGrammar"/> class. /// </summary> public ExpressionGrammar() : base(false) { var number = new NumberLiteral("Number"); number.DefaultIntTypes = new TypeCode[] { TypeCode.Int16, TypeCode.Int32, TypeCode.Int64 }; number.DefaultFloatType = TypeCode.Single; var identifier = new IdentifierTerminal("Identifier"); var comma = ToTerm(","); var BinOp = new NonTerminal("BinaryOperator", "operator"); var ParExpr = new NonTerminal("ParenthesisExpression"); var BinExpr = new NonTerminal("BinaryExpression", typeof(BinaryOperationNode)); var Expr = new NonTerminal("Expression"); var Term = new NonTerminal("Term"); var Program = new NonTerminal("Program", typeof(StatementListNode)); Expr.Rule = Term | ParExpr | BinExpr; Term.Rule = number | identifier; ParExpr.Rule = "(" + Expr + ")"; BinExpr.Rule = Expr + BinOp + Expr; BinOp.Rule = ToTerm("+") | "-" | "*" | "/"; RegisterOperators(10, "+", "-"); RegisterOperators(20, "*", "/"); MarkPunctuation("(", ")"); RegisterBracePair("(", ")"); MarkTransient(Expr, Term, BinOp, ParExpr); this.Root = Expr; } }

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • [asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗? - Emrys5

    [asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗? - Emr

    2017-06-02 13:00

  • 使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】 - 一线码农

    使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】 - 一线

    2017-05-29 13:01

  • Amazing ASP.NET Core 2.0 - Savorboard

    Amazing ASP.NET Core 2.0 - Savorboard

    2017-05-25 14:00

  • localstorage和sessionstorage上手使用记录 - 蓓蕾心晴

    localstorage和sessionstorage上手使用记录 - 蓓蕾心晴

    2017-05-24 09:00

网友点评
b