关于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()];

让我们看一下类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);}
}

我应该得到这样的东西:

<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);}
}

现在,方法NEWLINEstmt返回列表。 您可能还记得,一般而言,泛型在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中提供的模式。

我将添加一种名为PackageMetamodel的容器。 中将列出几个实体。 我们也可以将其中一个实体标记为实体。

每个实体将具有:

  • 一个名字
  • 可选的父实体(从其继承属性和关系)
  • 属性列表
  • 关系清单

每个属性将具有:

  • 一个名字
  • 从原始类型中选择的一种类型。 实际上,我希望只使用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

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

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

相关文章

创建和应用Java包文件的两种方式(转)

创建和应用Java包文件的两种方式(转) 《Java编程艺术》章节选登。作者&#xff1a;高永强 清华大学出版社 &#xff08;即将出版&#xff09; 12.1 包——package 。。。 12.1.1 包命名规范 为了确保包文件名称的唯一性&#xff0c;Java对应用软件开发者&#xff0c…

MATLAB double、str、cell间的类型转换

注&#xff1a;转换的前提是数组的格式符合目标数组的要求&#xff0c;能够转换。不然会失败str2numstr2doublesrt2matstrvcatstrcatcellstr字符数组转为元胞数组&#xff08;没有strcell&#xff09;int2str整数转换为字符串数组&#xff0c;非整数将四舍五入num2str非整数数组…

【动态规划】数字三角形2

【题目描述】 数字三角形要求走到最后mod 100最大 【输入格式】 第1行n&#xff0c;表示n行 <25第2到n1行为每个的权值 【输出格式】 mod 100最大值 【分析】 设置状态f[i][j][k]表示(i,j)各自内是否mod 100可以为k。 状态转移方程&#xff1a; f[i][j][k]f[i1][j][ka[i1][j…

面向 NLP 任务的大模型 Prompt 设计

很久之前&#xff0c;我们介绍到&#xff0c;prompt是影响下游任务的关键所在&#xff0c;当我们在应用chatgpt进行nlp任务落地时&#xff0c;如何选择合适的prompt&#xff0c;对于SFT以及推理环节尤为重要。 不过&#xff0c;硬想不是办法&#xff0c;我们可以充分参考开源的…

MATLAB安装第三方工具箱

1.1 如果是Matlab安装光盘上的工具箱&#xff0c;重新执行安装程序&#xff0c;选中即可&#xff1b;1.2 如果是单独下载的工具箱&#xff0c;一般情况下仅需要把新的工具箱解压到某个目录。2 在matlab的file下面的set path把它加上&#xff0c;或者用genpath(yourlocation/you…

Debug method

#define DEBUG(format,...) printf("Ray.he file:"__FILE__" func:%s() line:%d, print "format"", __func__, __LINE__, ##__VA_ARGS__)转载于:https://www.cnblogs.com/debruyne/p/9254619.html

soa学习路线_Web服务安全性和SOA路线图的人为维度

soa学习路线在大多数非平凡的SOA环境中&#xff0c;很难跟踪系统之间不断发展的集成&#xff0c;除非有明确的发布和查找适当信息的方法。 概述IT环境&#xff0c;定义当前或将要连接的内容&#xff0c;是维护环境的先决条件。 缺少这种方法通常会导致“面向意大利面条的环境”…

MATLAB函数参数个数控制

if nargin < 1 else if nargin < 2 else if nargin < 4 end

生产Java应用程序中的十大异常类型-基于1B事件

Pareto记录原理&#xff1a;97&#xff05;的记录错误语句是由3&#xff05;的唯一错误引起的 在最新的数据整理帖子之后&#xff0c;我们收到了很多反馈和问题&#xff0c;在该文章中&#xff0c;我们显示97&#xff05;的记录错误是由10个唯一错误引起的 。 根据普遍的需求&…

Matlab矩阵查找

find(x&#xff09;find(Aa)find(A>a)find(A>a,n);A为目标矩阵&#xff0c;a为要查找的数&#xff0c;n为查找的个数&#xff0c;返回位置

剑指Offer 斐波那契数列

时间限制&#xff1a;1秒 空间限制&#xff1a;32768K 热度指数&#xff1a;332130算法知识视频讲解 题目描述 大家都知道斐波那契数列&#xff0c;现在要求输入一个整数n&#xff0c;请你输出斐波那契数列的第n项。 n<39 给出代码&#xff1a; class Solution { public:int…

Matlab将一矩阵中等于某个值的元素全部替换成另一个值

A(Ax)X; %将A中等于x的值全部替换为XA(isnan(A))X;%将A中等于nan的值全部替换为X

教你制作QQ空间超高连通率背景音乐链接。

1.进入【搜搜音乐】http://music.soso.com/index.html 搜索你想要的歌曲名字。。。如下图&#xff1a; 2、 3.此链接地址并不能做背景链接&#xff0c;因为腾讯加密了&#xff0c;你只需将链接地址里的qq改成%71%71就可以作为背景音乐链接了。如图&#xff1a;

linux中查找文件属于那个软件包的方法

一、linux中查找文件属于那个软件包的方法 [rootsalt prod]# whereis htpasswdhtpasswd: /usr/bin/htpasswd /usr/share/man/man1/htpasswd.1.gz [rootsalt prod]# rpm -qf /usr/bin/htpasswdhttpd-tools-2.4.6-80.el7.centos.x86_64转载于:https://www.cnblogs.com/nulige/p/9…

java io顺序_Java顺序IO性能

java io顺序许多应用程序将一系列事件记录到基于文件的存储中&#xff0c;以供以后使用。 从日志记录和审核&#xff0c;直到在事件源设计或其紧密相关的CQRS中保留事务重做日志&#xff0c;这都可以是任何东西。 Java具有多种方法&#xff0c;可以通过这些方法将文件顺序写入或…

Matlab矩阵的拼接

oneyeardata.fert [(0:14),zeros(15,3);oneyeardata.fert;(50:90),zeros(41,3)];%把0补齐

sqlmap常用操作命令

一、sqlmap常用基础命令 sqlmap Common operation command 以下命令顺序即为sql注入常见步骤。 sqlmap -u [“url”] --dbs #获取数据库 sqlmap -u [“url”] --current-user #获取当前用户名称 &#xff1a; sqlmap -u [“url”] --current-db #获取当前数据库名称 sqlmap -u …

hdu 2066

一个人的旅行 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 12820 Accepted Submission(s): 4343 Problem Description虽然草儿是个路痴&#xff08;就是在杭电待了一年多&#xff0c;居然还会在校园里迷路…

Java EE 8,当前状态是什么:自2015年底以来已完成工作的案例研究

对于那些密切关注Java EE的人来说&#xff0c;在过去的六个月中已经很清楚&#xff0c;活动有所减少&#xff0c;尤其是在Oracle保持领先的JSR中。 这是怎么回事&#xff1f; 最近&#xff0c;在这方面&#xff0c;Java EE社区进行了很多讨论&#xff0c;我认为给开发人员社区一…

Matlab矩阵替换所有等于某个值的数

若非NaN&#xff1a;a[2,5;1,4;1,4;3,6;3,6;2,5];a(a1)0;%所有1替换为0%上述方法可以把数替换为NaN但不能把NaN替换为数 若为NaNa(isnan(a))0;%将NaN替换为0