关于ANTLR的通用库的需求:使用反射来构建元模型
我是一名语言工程师:我使用多种工具来定义和处理语言。 在其他工具中,我使用ANTLR:它简单,灵活,可以围绕它进行构建。
但是,我发现自己围绕ANTLR为不同的项目重建了类似的工具。 我看到两个问题:
- ANTLR是一个非常好的构建基块,但是仅使用ANTLR并不能做很多事情:价值在于我们可以在AST上进行的处理,而且我看不到ANTLR周围的图书馆生态系统
- ANTLR不会产生语法的元模型:没有它,就很难围绕ANTLR构建通用工具
让我解释一下:
- 对于具有EMF经验的人:我们基本上每个语法都需要一个Ecore等效项。
- 对于其他:请阅读下一段
为什么我们需要一个元模型
假设我想构建一个通用库,以通过ANTLR生成的AST生成XML文件或JSON文档。 我该怎么办?
好吧,给定一个ParseRuleContext,我可以获取规则索引并找到名称。 我为Python语法生成了解析器,并提供了一些示例,因此,让我们看一下如何使用实际的类:
Python3Parser.Single_inputContext astRoot = pythonParse(...my code...);
String ruleName = Python3Parser.ruleNames[astRoot.getRuleIndex()];
好。 现在,假设我想将所有终端添加为属性,并将所有非终端添加为XML节点为Single_inputContext生成的子节点。
让我们看一下类Single_inputContext:
public static class Single_inputContext extends ParserRuleContext {public TerminalNode NEWLINE() { return getToken(Python3Parser.NEWLINE, 0); }public Simple_stmtContext simple_stmt() {return getRuleContext(Simple_stmtContext.class,0);}public Compound_stmtContext compound_stmt() {return getRuleContext(Compound_stmtContext.class,0);}public Single_inputContext(ParserRuleContext parent, int invokingState) {super(parent, invokingState);}@Override public int getRuleIndex() { return RULE_single_input; }@Overridepublic void enterRule(ParseTreeListener listener) {if ( listener instanceof Python3Listener ) ((Python3Listener)listener).enterSingle_input(this);}@Overridepublic void exitRule(ParseTreeListener listener) {if ( listener instanceof Python3Listener ) ((Python3Listener)listener).exitSingle_input(this);}
}
在这种情况下,我想:
- 使用NEWLINE作为属性
- 将simple_stmt和compound_stmt用作子项
我应该得到这样的东西:
<Single_input NEWLINES="..."><Simple_stmt>...</Simple_stmt><Compund_stmt>...</Compunt_stmt>
</root>
好。 对我来说,看课并识别这些元素非常容易,但是我如何自动做到这一点呢?
反思,显然,您会思考。
是。 那行得通。 但是,如果我们有多个元素怎么办? 参加本课:
public static class File_inputContext extends ParserRuleContext {public TerminalNode EOF() { return getToken(Python3Parser.EOF, 0); }public List NEWLINE() { return getTokens(Python3Parser.NEWLINE); }public TerminalNode NEWLINE(int i) {return getToken(Python3Parser.NEWLINE, i);}public List stmt() {return getRuleContexts(StmtContext.class);}public StmtContext stmt(int i) {return getRuleContext(StmtContext.class,i);}public File_inputContext(ParserRuleContext parent, int invokingState) {super(parent, invokingState);}@Override public int getRuleIndex() { return RULE_file_input; }@Overridepublic void enterRule(ParseTreeListener listener) {if ( listener instanceof Python3Listener ) ((Python3Listener)listener).enterFile_input(this);}@Overridepublic void exitRule(ParseTreeListener listener) {if ( listener instanceof Python3Listener ) ((Python3Listener)listener).exitFile_input(this);}
}
现在,方法NEWLINE和stmt返回列表。 您可能还记得,一般而言,泛型在Java的反射中不能很好地工作。 在这种情况下,我们很幸运,因为有一个解决方案:
Class clazz = Python3Parser.File_inputContext.class;
Method method = clazz.getMethod("stmt");
Type listType = method.getGenericReturnType();
if (listType instanceof ParameterizedType) {Type elementType = ((ParameterizedType) listType).getActualTypeArguments()[0];System.out.println("ELEMENT TYPE "+elementType);
}
这将打印:
元素类型类me.tomassetti.antlrplus.python.Python3Parser $ StmtContext
因此,我们也可以介绍泛型。 好的,使用反射并不理想,但是我们可以从中提取一些信息。
我不是100%肯定会足够,但是我们可以开始。
元模型应该如何?
为了定义元模型,我不会尝试任何幻想。 我将使用基于EMF的经典模式,该模式类似于MPS中提供的模式。
我将添加一种名为Package或Metamodel的容器。 包中将列出几个实体。 我们也可以将其中一个实体标记为根实体。
每个实体将具有:
- 一个名字
- 可选的父实体(从其继承属性和关系)
- 属性列表
- 关系清单
每个属性将具有:
- 一个名字
- 从原始类型中选择的一种类型。 实际上,我希望只使用String和Integers。 将来可能枚举
- 多重性(1个或多个)
每个关系将具有:
- 一个名字
- 种类: 包含或引用 。 现在,AST只知道容器 ,但是稍后我们可以实现符号解析和模型转换,在那个阶段我们将需要引用
- 目标类型:另一个实体
- 多重性(1个或多个)
下一步
我将开始构建一个元模型,然后再利用该元模型来构建通用工具。
通常还需要执行其他操作:
- 转换:我通常从ANTLR获得的AST是由我如何表达语法以获取可解析内容的方式决定的。 有时我还必须进行一些重构以提高性能。 我想在解析后转换AST,以更接近语言的逻辑结构。
- 取消编组:我想从AST进行测试
- 符号解析:这绝对不是一件容易的事,因为我发现为Java构建符号求解器
是的,我知道有些人在想: 只需使用Xtext即可 。 虽然我喜欢EMF(Xtext建立在它上面),但它的学习曲线陡峭,我看到很多人对此感到困惑。 我也不喜欢OSGi在非OSGi世界中的表现。 最终,Xtext带有很多依赖项。
别误会:我认为Xtext在许多情况下都是一个了不起的解决方案。 但是,有些客户更喜欢精简的方法。 对于有意义的情况,我们需要一种替代方法。 我认为它可以建立在ANTLR之上,但是还有很多工作要做。
几年前,我为.NET构建了类似的东西,并将其称为NetModelingFramework 。
翻译自: https://www.javacodegeeks.com/2016/05/need-generic-library-around-antlr-using-reflection-build-metamodel.html
关于ANTLR的通用库的需求:使用反射来构建元模型相关推荐
- antlr 语言 库_关于ANTLR的通用库的需求:使用反射来构建元模型
antlr 语言 库 我是一名语言工程师:我使用多种工具来定义和处理语言. 在其他工具中,我使用ANTLR:它简单,灵活,可以围绕它进行构建. 但是我发现自己围绕ANTLR为不同的项目重建了类似的工具 ...
- IC验证培训——SV通用库共享
(一)摘要 你已经编程了多少次看门狗定时器,让它在事件没有在限定时间内发生时触发?你曾经是否想过当数据在计分板中不匹配的时候用一个函数来显示多一点的信息,而不仅仅是在出错地方的那一条信息?设计验证工程 ...
- Android直播开发之旅(9):OkCamera,Android 相机应用开发通用库
OkCamera,Android 相机应用开发通用库 转载请声明出处:http://blog.csdn.net/andrexpert/article/details/79302576 明天就可以回家过 ...
- 分享:Dlib 17.49 发布,跨平台 C++ 通用库
Dlib 17.49 发布,跨平台 C++ 通用库 http://www.oschina.net/news/35962/dlib-cpp-lib-17-49
- Tiny C++通用库终于基本上完成了 - 专职C++ - C++博客
牛人 Tiny C++通用库终于基本上完成了 - 专职C++ - C++博客 Tiny C++通用库终于基本上完成了 Tiny C++通用库终于基本上完成了.包括的内容有字符串XAnsiString( ...
- c语言hid,HIDAPI首页、文档和下载 - HID 设备的 C 语言通用库
HIDAPI 是一个 USB 和蓝牙的 hid 类设备在 Windows.Linux.FreeBSD 和 Mac 的 C 语言通用库,使用 HIDAPI 可以在 Windows.Linux.FreeB ...
- 开源导入导出通用库Magicodes.ExporterAndImporter发布
导入导出通用库 Magicodes.ExporterAndImporter为心莱团队封装的导入导出通用库,并且仍在跟随项目不断地打磨. GitHub地址: https://github.com/xin ...
- 04-ESP8226的WiFi通用库学习
文章目录 **04-ESP8226的WiFi通用库学习** WiFi事件类: WiFI睡眠模式: WiFi配置相关: 官方例程: 中断事件回调函数的使用: 04-ESP8226的WiFi通用库学习 E ...
- 物联网国赛LORA模块开发基础教程(通用库)—点对点通信
LORA模块开发基础教程目录 物联网国赛LORA模块开发基础教程-开发环境配置 物联网国赛LORA模块开发基础教程-输出(LED) 物联网国赛LORA模块开发基础教程-输入(按键) 物联网国赛LORA ...
最新文章
- Ubuntu 搜狗输入法不能输入中文解决
- mysql 常见错误_mysql常见的错误提示问题处理小结
- js中sort()方法的用法,参数以及排序原理
- 写不出满分作文怎么办,GPT-3 来帮你
- 谈表达式树的缓存(6):五种缓存方式的性能比较
- 【渝粤教育】电大中专计算机职业素养 (6)作业 题库
- ESLint 规则详解(二)
- 深圳荔枝公园没看到夜景(可能过节才有)
- 基于R语言的Meta分析【全流程、不确定性分析】方法与Meta机器学习
- 【操作系统习题】假定某多道程序设计系统供用户使用的主存空间为100 KB ,磁带机2台,打印机1台
- html+css+js按键定位搜索框
- vue3实现发送验证码功能
- android x86虚拟机不识别网卡,科学网-AndroidSDK-虚拟机之Intel x86虚拟机安装-几个错误解决方法-联网-马飞的博文...
- webclient是什么意思_Web 是什么意思?
- 牛客寒假训练营4-爆炸的符卡洋洋洒洒 (dp变形)
- 源中的 backports proposed security updates 什么意思?
- 滴滴出行A/B测试数据分析
- python画箭头_Python matplotlib绘制图形,包括点、曲线、注释和箭头
- 关于电脑特别卡的解决方法.(管用, 真的)
- html 转换为jade,html转jade.htm
热门文章
- Oracle入门(十四.14)之处理异常
- 高级java必须清楚的概念:原子性、可见性、有序性
- 小课堂?小视频?小商店?
- mybatis简单案例源码详细【注释全面】——前期准备
- MyBatisPlus(基于starter和Bean方式)
- 全自动安装 linux光盘,CentOS 7.1全自动安装光盘制作详解
- 19年8月 字母哥 第五章 静态资源与模板引擎的整合 用热点公司网不行
- matlab哈明窗带阻,基于matlabFIR低通,高通,带通,带阻滤波器设计.doc
- Future取消线程执行
- tms tck_在雅加达EE TCK中使用Arquillian的可能方法