在 .NET 应用中使用 ANTLR

什么是 ANTLR ?

ANTLR 是功能强大的解析器生成器,用于读取,处理,执行或翻译结构化文本或二进制文件。它被广泛用于构建语言,工具和框架。ANTLR从语法中生成一个解析器,该解析器可以构建和遍历解析树。

ANTLR 语法库

ANTLR 为常见的语言构建了语法文件, 可以直接下载使用 https://github.com/antlr/grammars-v4 。如果需要在程序中处理常用的语言, 可以先来这里找一下。

如何在 .NET 中使用 ANTLR ?

ANTLR 被广泛应用与大数据分析、 人工智能等领域的语法分析, 网上的相关资料确实非常多, 但是 .NET 相关的资料却很少, 有的也是年代久远, 几乎没有什么参考价值。

经过一番摸索, 终于找到了在 .NET 中使用 ANTLR 的正确方法, 于是记录下来。

新建 .NET 命令行项目

  1. 首先, 当然是新建一个 .NET 项目, 命令如下:

    dotnet new console AntlrDemo
    
  2. 添加 NuGet 包 Antlr4.Runtime.Standard , 目前的版本是 4.9.2 , 这是一个 .NET Standard 2.0 标准类库, 可以在大多数 .NET 环境中使用:

    dotnet add package Antlr4.Runtime.Standard --version 4.9.2
    

生成 C# 代码

  1. 下载 ANTLR 工具包

    访问 ANTLR 的 下载 页面, 下载完整的 ANTLR jar 包, 需要用这个来生成 C# 源代码。

    由于要运行 jar 文件, 所以还得装一个 jre , 不过运行时不需要 jre 。

  2. 根据语法文件生成对应的 C# 代码

    以 ANTLR 提供的 SQLite 语法文件为例, 生成代码的命令为:

    java -jar .tools/antlr-4.9.2-complete.jar \-Dlanguage=CSharp \ # 指定生成的语言为 C#-package AntlrDemo.Generated \ # 指定输出代码的命名空间-o ./src/AntlrDemo/Generated \ # 指定输出的目录SQLiteParser.g4 SQLiteLexer.g4 # 提供语法文件
    
  3. 编译一下, 确认没有错误

    dotnet build
    

使用生成的 C# 代码

要使用生成的 C# 代码, 根据 ANTLR 针对的 C# 说明 , 对应的代码如下:

var sql = "select * from t where id < 10";
ICharStream charStream = CharStreams.fromString(sql);
ITokenSource lexer = new SQLiteLexer(charStream);
ITokenStream stream = new CommonTokenStream(lexer);
SQLiteParser parser = new SQLiteParser(stream);
parser.BuildParseTree = true;
IParseTree tree = parser.parse();

上面的代码创建了解释器 (parser) 和 对应的语法树 (tree) 两个对象, 有了它们之后, 可以做类似下面的操作:

  • 判断是否存在语法错误

    如果要简单判断 sql 的内容有没有语法错误的话, 可以读取 parser 的 NumberOfSyntaxErrors 属性进行判断

    if (parser.NumberOfSyntaxErrors > 0) {throw new Exception("Invalid SQL!");
    }
    
  • 检查语法树的每一个节点

    比如 where 后面的每一个表达式是否合法, 不能出现 1=1 之类的表达式, 则需要使用 ParseTreeWalker 来循环整个语法树。

    先创建一个自定义的监听器, 代码如下:

    public class SqliteParserListener : SQLiteParserBaseListener {// 只监听退出表达式的方法, 根据提供的语法文件, 还会有很多其它的方法可以重写。public override void ExitExpr([NotNull] SQLiteParser.ExprContext context) {var text = context.GetText();Console.WriteLine(text);}
    }
    

    调用监听器 SqliteParserListener 并循环整个语法树的代码为:

    var listener = new SqliteParserListener();
    ParseTreeWalker.Default.Walk(listener, tree);
    

ANTLR 使用小结

ANTLR 是一个通用的解析器生成器, 只要能够构建语法文件, 就能生成对应的解析器, 生成对应的语法树进行分析。不仅提供了大量的语法文件, 也可以根据语法创建自定义的语法文件, 各家的 IDE 工具 (JetBrains, Visual Studio, Visual Studio Code, Eclipse 等)也都对其语法文件提供了可视化支持, 如果需要在代码中动态分析解释特定的语法, ANTLR 可以说是首选工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/301003.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GDB调试程序实例演示

GDB概述————GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许&#xff0c;各位比较喜欢那种图形界面方式的&#xff0c;像VC、BCB等IDE的调试&#xff0c;但如果你是在UNIX平台下做软件&#xff0c;你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功…

ASP.NET程序中常用的三十三种代码(二)

21.读取DataGrid控件TextBox值 foreach(DataGrid dgi in yourDataGrid.Items){ TextBox tb (TextBox)dgi.FindControl("yourTextBoxId"); tb.Text....} 23.在DataGrid中有3个模板列包含Textbox分别为 DG_ShuLiang (数量) DG_DanJian(单价) DG_JinE(金额)分别在5.6…

oracle crontab e,Linux运维知识之通过crontab -e编辑生成的定时任务,写在哪个文件中...

本文主要向大家介绍了Linux运维知识之通过crontab -e编辑生成的定时任务&#xff0c;写在哪个文件中&#xff0c;通过具体的内容向大家展现&#xff0c;希望对大家学习Linux运维知识有所帮助。环境描述&#xff1a;操作系统&#xff1a;Red Hat Enterprise Linux Server releas…

video.js html5 视频播放器

1 我个人感觉很不错2 https://github.com/videojs/video.js3 <head>4 <title>Video.js | HTML5 Video Player</title>5 6 <!-- Chang URLs to wherever Video.js files will be hosted -->7 <link href"video-js.css" rel"sty…

老师“鬼话”全曝光!哈哈哈哈哈哈全国的老师都这样吗?

老师您辛苦了明天就是教师节啦今天超模君有幸采访到一位从教多年的数学老师01请问您教的科目是&#xff1f;数学收到&#xff0c;over02您从教多久了&#xff1f;唔…快10年了您当过班主任吗&#xff1f;当过&#xff0c;现在也是班主任工作日常是怎样的&#xff1f;备课、改作…

单体系统如何拆分为微服务

当单体系统越来越大&#xff0c;并难于维护时&#xff0c;很多企业开始有意把单体系统拆分为微服务风格架构。这么做很有意义&#xff0c;但不容易。要做好这件事情我们必须学习&#xff0c;我们从一个简单的服务开始&#xff0c;另一方面拉出以垂直功能为基础的服务&#xff0…

Wiki及其他

大概是2年多以前&#xff0c;我几乎是和blog一起听到wiki的概念的。当时blog正备受推崇&#xff0c;而个性色彩稍逊一筹、讲究严肃协作的wiki则没怎么受公众注意。我也一样。后来进入行业之后&#xff0c;我一直想有一套知识库(Knowledge Base)系统&#xff0c;多分类、复杂查找…

linux服务器管理公司用户,在Linux服务器Jenkins中管理用户和角色的方法

下面将教你如何在Linux服务器Jenkins中管理用户和角色&#xff0c;它需要创建角色并分配给用户&#xff0c;你需要运行Jenkins服务器才能操作接下来的工作。安装Jenkins参考文章在Jenkins中管理用户和角色默认情况下&#xff0c;当你在Jenkins中创建用户时&#xff0c;它几乎可…

还在用Excel做数据分析?两大方法5分钟完成别人一天的工作

全世界只有3.14 % 的人关注了青少年数学之旅我是个只会用Excel的数据分析工作者。有一天&#xff0c;我和同事大鹏约好晚上一起喝酒&#xff0c;离下班还有5分钟&#xff0c;老板突然Q我&#xff1a;我怀着忐忑的心情打开了一个神秘的压缩包&#xff1a;912个CSV表格&#xff0…

poj1033

模拟题&#xff0c;注意不需要移动的情况要特殊输出 #include <cstdio> #include <cstring> #include <cstdlib> using namespace std;#define MAX_CLUSTER_NUM 10005int cluster_num, file_num; int link[MAX_CLUSTER_NUM]; bool is_free[MAX_CLUSTER_NUM];…

ABP Framework V4.4 RC 新增功能介绍

新增功能概述•启动模板删除 EntityFrameworkCore.DbMigrations 项目•CMS-Kit 模块新增 动态菜单管理 功能•对象扩展管理系统新增两个扩展方法&#xff1a;MapEfCoreDbContext MapEfCoreEntity&#xff0c;分别对 数据上下文和实体 自定义映射配置。•文本模板系统新增 Razor…

《蛋白质女孩》的一句台词

《蛋白质女孩》的一句台词 有些女孩很真&#xff0c;有些很纯&#xff0c;有些很冷&#xff0c;有些很笨。有些像旋转门&#xff0c;有些像跑马灯&#xff0c;有些像聚宝盆&#xff0c;有些像地雷坑。有些可以私奔&#xff0c;有些敢爱敢恨&#xff0c;有些像多氯联苯&#xff…

linux快速切换目录命令,Linux在命令行快速切换目录 - 米扑博客

今天在微博上看到一个用命令行快速切换目录的文章&#xff0c;比之前自己的解决方案好了非常多&#xff0c;必须记录下来分享下。每天在命令行下&#xff0c;一大部分的工作都是一遍又一遍的输入 cd ~/some/very/deep/often-used/directory这样来切换目录&#xff0c;现在利用一…

论文排版怕翻车?这个排版神器赶紧用起来!

论文的重要加分点除了内容&#xff0c;还有它相信每年临近准备毕设或者毕业论文的同学会遇到这些问题&#xff1a;“我的毕业论文提交一次就被导师批评一次&#xff0c;内容不行就算了&#xff0c;格式也有问题&#xff01;改论文改到绝望”“期刊的版式要求不是统一的&#xf…

[正则表达式] 可以解析HTML/XHTML页面的所有元素和结构的Regular Expression![ZT]

ZT: http://www.cnblogs.com/Laser_Lu/archive/2005/04/21/142605.html哈哈&#xff0c;继 昨天的那个正则表达式 之后又写了一个更长的Regular Expression&#xff0c;全长527&#xff0c;是用于查找出所有的XHTML/HTML的标记外面的所有空格&#xff0c;并将之转换为 的。 希望…

linux查看mq是否启动的命令,rocketmq查看命令

1.1. 控制台使用RocketMQ 提供有控制台及一系列控制台命令&#xff0c;用于管理员对主题&#xff0c;集群&#xff0c;broker 等信息的管理&#xff1b;登录控制台首先进入RocketMQ 工程&#xff0c;进入/RocketMQ/bin在该目录下有个mqadmin 脚本查看帮助在mqadmin 下可以查看有…

我用段子讲.NET之依赖注入(一)

我用段子讲.NET之依赖注入&#xff08;一&#xff09;1&#xff09;西城的某个人工湖畔&#xff0c;湖水清澈见底&#xff0c;湖畔柳树成荫。人工湖往北&#xff0c;坐落着两幢写字楼&#xff0c;水晶大厦靠近地铁站&#xff0c;由于为了与湖面天际线保持一致&#xff0c;楼层只…

教师节,老师们最大的愿望竟然是。。 | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;视频源网络&#xff0c;侵权删&#xff09;发给最敬爱的老师们↓ ↓ ↓

计算几何题集

这段时间刷了一群计算几何题&#xff0c;呼&#xff01; 做计算几何时一定要保证自己做到以下两点&#xff1a; 1.下手之前保证自己已经考虑到每一个细节&#xff0c;每一步的作法都要非常清晰。 2.敲代码时必须非常冷静&#xff0c;必须保持头脑清醒&#xff0c;保证自己敲下来…

linux文件权限 705,Linux 文件权限 - osc_86eb7mly的个人空间 - OSCHINA - 中文开源技术交流社区...

文件权限Linux 中任何一个文件都具有 「用户、用户组与其他用户」三种权限&#xff0c;一个用户可属于多个用户组。所有用户的相关信息都记录在 /etc/passwd 文件中&#xff0c;密码记录在 /etc/shaodw 文件&#xff0c;用户组记录在 /etc/group 文件。root 用户权限最高&#…