为了自己的乐趣,我正在Haskell中构建一个小型的单文件解析器组合器库.我为这个库给自己带来的一个挑战是构建工具,以便我可以为Java函数签名创建解析器,例如将boolean isPrime(int n)解析为语言不可知的表示,例如

Function {
    returnType = Type {
        typeName = "boolean",
        subTypes = []
    },
    functionName = "isPrime",
    args = ...
}

然而,当谈到解析Java类型时,我遇到了一个问题.像Tuple<Integer, List<Integer>>这样的类型可以解析,因为它的语法可以在没有左回归的情况下表示:

javatype := identifier, subtypes
identifier := regex("[a-zA-Z_][a-zA-Z0-9_]*")
subtypes := ('<', javatype, (',', javatype) zero or more times, '>') | NOTHING

(对我糟糕的语法写作技巧和简化Java标识符规则表示歉意)

然而,数组类型引入了左回归,众所周知,解析器组合器很难处理左回归.对于数组类型,我们将javatype规则更改为:javatype := (javatype, "[]") | (identifier, subtypes).这为我们提供了左回归.我们可以try 将规则重写为javatype := (identifier, subtypes) | (javatype, "[]"),但这意味着对于像int[]这样的类型,解析器只会解析"int"而不是"[]".

如何重写类型语法规则以避免左回归,同时允许数组类型?

推荐答案

您可以在此规则中消除左回归:

javatype := (javatype, "[]") | (identifier, subtypes)

通过将其转化为这两个等效规则:

javatype := (identifier, subtypes) javatype2
javatype2 := "[]" javatype2 | e

(其中e是空字符串)

Java相关问答推荐

将@ManyToOne JPA Composite Key用作Id保存实体添加额外参数

Java JAR环境(JRE)是否支持模块?

如何在Docker容器中使用wireock—Webhooks阻止请求?

如何使用jooq generator将表名和列名映射为人类可读的?

如何在访问完所有文件后加入所有线程?

从技术上讲,OPC UA客户端是否可以通过转发代理将请求通过 tunel 发送到OPC UA服务器?

Java函数式编程中的双值单值映射

如何创建一个2d自上而下的移动系统,其中移动,同时持有两个关键是可能的处理?

Java流传输一个列表并创建单个对象

如何在Application.yaml中连接字符串?

无法使用Freemarker从XML中读取重复的标记值

将stringBuilder + forloop转换为stream + map

JOLT根据值删除并保留其余的json键

在一行中检索字符分隔字符串的第n个值

具有多个分析模式的复杂分隔字符串的正则表达式

使用同步方法中的新线程调用同步方法

[jdk21][Foreign Function&;Memory API]MemoryLayout::varHandle通过可变数组进行 struct 化的问题

ResponseEntity.控制器截断响应的JSON部分

使用StringBuilder和append方法创建字符串时Java字符串内部方法的问题

在不带instanceof或switch的java中记录模式