我需要解析一个表达式,例如:neg(and(X,Y))
我需要它来提出抽象堆栈机器代码,例如上面的例子:
LOAD X;
LOAD Y;
EXEC and;
EXEC neg;
但是现在机器代码不是问题,我怎样才能将表达式的输入字符串解析/拆分成所有子表达式?
我试图找到第一个括号,然后从那个连接到最后一个括号,但如果你有一个内部表达式则会给出isuess?
我尝试过的代码:(请不要它仍处于开发阶段)
private boolean evaluateExpression(String expression) {
int brackets = 0;
int beginIndex = -1;
int endIndex = -1;
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) == '(') {
brackets++;
if (brackets == 0) {
endIndex = i;
System.out.println("the first expression ends at " + i);
}
}
if (expression.charAt(i) == ')') {
brackets--;
if (brackets == 0) {
endIndex = i;
System.out.println("the first expression ends at " + i);
}
}
}
// Check for 1st bracket
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) == '(') {
beginIndex = i;
break;
}
}
String subExpression = expression.substring(beginIndex, endIndex);
System.out.println("Sub expression: " + subExpression);
evaluateExpression(subExpression);
return false;
}
我只是在寻找一个基本的解决方案,它只需要:和,或者,否则
答案 0 :(得分:1)
您尝试解析的表达式实际上是Context Free Language,可以表示为Context Free Grammer。
您可以创建一个表示该表达式语言的无上下文语法,并使用CFG解析器来解析它。
一个现有的java工具(以及更多)是JavaCC,尽管这可能是一种过度杀伤力。
另一种使用CFG解析句子的算法是CYK,它很容易编程和使用。
在这里,表示可用表达式的CFG是:
S -> or(S,S)
S -> and(S,S)
S -> not(S)
S -> x | for each variable x
请注意,虽然这是相对简单的CFG - 它描述的语言是不规则的,所以如果你希望使用正则表达式 - 它可能不是那种方法。
答案 1 :(得分:0)
实际上,如果你希望你的解析器足够强大以处理大多数情况,你想使用一个tokenizer(java有一个已实现的tokenizer类)来首先标记字符串,然后尝试识别每个表达式,存储操作数和树结构中的运算符,然后递归地计算它们。
如果你只想处理一些简单的情况,记得使用递归,这是核心部分〜
答案 2 :(得分:0)
解析这样的事情通常是使用语法树完成的,使用某种类型的优先级来操作顺序。您发布的内容的示例如下:
Processing items left to right the tree would be populated like this
1arg_fcall(neg)
2arg_fcall(and)
Load Y
Load X
Now we can recursively visit this tree bottom to top to get
Load X
Load Y
EXEC and //on X and Y
EXEC neg //on result of and