java - 正则表达式循环依赖性

标签 java regex dependencies

我在设计脚本语言时遇到了问题。

我们有表达式:

1 + 2

x

a := b + c

... etc

函数调用可以包含表达式:

myfunc(1 + 2 + 3, b)

表达式可以包含函数调用:

a := myfunc(1, 2) * x

并且函数调用可以包含函数调用(作为参数):

myfunc(f(x), g(x))

它们可以全部组合在一起:

a := calc(f(x) + g(x), 1) + y

我的问题是如何使用java.util.regex.Pattern表示这些关系。如果我首先声明Pattern EXPRESSION,那么它会在尚未声明时使用Pattern FUNC_CALL。首先声明 FUNC_CALL 时也会发生同样的情况,因为它也使用 EXPRESSION。

代码片段:

/**
* Expression is any positive number of either (number, spaces, operator, function call, or identifier).
*/
public static final Pattern EXPRESSION = Pattern.compile("(\\s*(\\s+|" + NUMBER.pattern()
        + "|" + OPERATOR.pattern() + "|" + FUNC_CALL.pattern() + "|" // Error : FUNC_CALL is not initialized
        + IDENTIFIER.pattern() + ")+)");
/**
* Function call is an identifier, followed by "(",
* followed by arguments which are any non-negative number of 
* either (identifier, comma, or spaces), followed by ")"
*/
public static final Pattern FUNC_CALL = Pattern.compile(IDENTIFIER.pattern()
        + "\\s*\\(" + "(" + EXPRESSION.pattern() + "|\\s+|\\,)*\\)");

最佳答案

您对正则表达式的要求太多了。你想要的东西是不可能的。通常,在解析表达式时,正则表达式的使用量要小得多,例如识别合法的函数名称、运算符和值。为了解析完整的表达式,您可能需要尝试 recursive descent parser因为这是最简单的技术。

如果您必须包含中缀运算符,那么这将大大增加解析器的复杂性。您将想了解operator-precedence parsers 。一旦了解了解析器的工作原理,编写一个漂亮的解析器并不难。您甚至可以用几行代码编写一个运算符优先级解析器,但弄清楚算法可能很棘手。如果您打算自己动手,最好的方法是在网络上查找可以帮助您的资源,例如:Parsing expressions by precedence climbing ,和Parsing Expressions by Recursive Descent 。我无法比这些教程做得更好。

您自己做的自然替代方案是使用解析器生成器来为您完成所有操作。以下是许多选项的列表:Comparison of parser generators .

关于java - 正则表达式循环依赖性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20028063/

相关文章:

python - 如何从大多数网站获取 Twitter 链接 - Python

c# - 将具有依赖项 v1 的项目添加到具有依赖项 v1.1 的项目

c# - ISEXP : warning : -6248: Could not find dependent file libc. dll,或其组件的依赖项之一

Java - 带有列表的泛型

java - Spring:从文件中读取属性为什么执行 Condition::match

正则表达式在 R 中的逗号之前或之后提取数据

go - 相同依赖的两个版本 - 较低版本被忽略

java - 无法创建 sessionFactory 对象.java.lang.NullPointerException

java - 启用 SSL 的主机

java - 为 tomcat 重写 URL