在计算器中识别一元减号,java
嗨,大家好 我的代码快写完了,但我却被这个愚蠢的事情困住了。我可以识别括号前有一元减号 (-[4 + 4]) 的情况。这是我的代码:
package oop.ex2.expression;
import java.io.IOException;
import java.util.HashMap;
import oop.ex2.exception.*;
import oop.ex2.main.Tokenizer;
/**
* This class contains 3 public static methods. All 3 methods are used
* to parse text into a mathematical expression. The information is "thrown"
* back and forth from one method to another.
*/
public class ExpressionParser {
/**
* This method uses expression() method to parse the text into mathematical
* expressions, and returns an expression which is the sum of all
* expressions returned from expression() [the sum is calculated according
* to the right operator]
*
* @param st - the Tokenizer parsing the text
* @return - Expression, the sum of all expressions from expression()
* @throws InputException
* @throws IOException
*/
public static Expression sumExpressions(Tokenizer st)
throws InputException, IOException {
boolean endOfLine = false;
Expression temp = expression(st);
int token = Tokenizer.TT_NOTHING;
while (!endOfLine) {
token = st.nextToken();
if ((token == Tokenizer.TT_OPERATOR)
|| (token == Tokenizer.TT_OVERLOADED_OP))
temp = new FatherExpression(st.op, temp, expression(st));
else
endOfLine = true;
}
return temp;
}
public static Expression expression(Tokenizer st) throws InputException, IOException {
Expression result = null;
switch (st.nextToken()) {
case Tokenizer.TT_NUMBER:
result = new NumberExpression(st.nval);
break;
case Tokenizer.TT_VARIABLE:
result = new VariableExpression(st.sval);
break;
case Tokenizer.TT_FUNC:
result = createFunction(st);
break;
case '[':
result = sumExpressions(st);
if (st.ttype != ']')
throw new BracketException("BracketException: "
+ "one too many ']'");
break;
default:
throw new UnexpectedTokenException("Unexpected token on" +
"ExpressionParser.elements(st)");
}
return result;
}
private static Expression createFunction(Tokenizer st)
throws IOException, InputException {
if (InlineManager.getAllInlineFunctions().containsKey(st.sval)) {
InlineFunction temp = InlineManager.getInlineFunction(st.sval);
temp.setArguments(st);
return temp;
}
if (st.sval.equals("MAX"))
return new Max(st);
if (st.sval.equals("MIN"))
return new Min(st);
if (st.sval.equals("POW"))
return new Pow(st);
if (st.sval.equals("MOD"))
return new Mod(st);
if (st.sval.equals("ABS"))
return new Abs(st);
throw new FunctionNameException("Wrong funcion entred " + st.sval);
}
public static HashMap<String, Expression> parseArguments(Tokenizer st)
throws IOException, InputException {
HashMap<String, Expression> result = new HashMap<String, Expression>();
if (st.nextToken() != '{')
throw new UnexpectedTokenException("Missing {");
int argument = 0;
while (true) {
st.ignoreToken(',', true);
switch (st.nextToken()) {
case '}':
st.ignoreToken(',', false);
return result;
case '[':
result.put(String.valueOf(argument++), sumExpressions(st));
break;
case Tokenizer.TT_NUMBER:
result.put(String.valueOf(argument++), new NumberExpression(st.nval));
break;
case Tokenizer.TT_VARIABLE:
result.put(String.valueOf(argument++), new VariableExpression(st.sval));
break;
case Tokenizer.TT_FUNC:
result.put(String.valueOf(argument++), createFunction(st));
break;
default:
throw new UnexpectedTokenException("Unexpected token on function arguments");
}
}
}
}
我知道很久了。表达式对象可以是常量、变量或函数,例如 MAX{3,2}(即 3)。 expression() 使用我构建的分词器将文本解析为表达式,sumExpression() 使用 expression() 来创建一个新的 Expression,它是两个 Expression 对象根据右侧运算符的组合。
我希望它清楚。正如我之前所说,我不知道如何识别一元减号(-[4] 将是 -4)。我没有放置我的标记器代码,认为没有必要。
谢谢!
聚苯乙烯 计算顺序定义为从左到右,与运算符的类型无关。
Hi guys
i'm almost done writing my code and i'm stuck with this stupid thing. I can identify cases in which there's a unary minus before brackets (-[4 + 4]). here's my code:
package oop.ex2.expression;
import java.io.IOException;
import java.util.HashMap;
import oop.ex2.exception.*;
import oop.ex2.main.Tokenizer;
/**
* This class contains 3 public static methods. All 3 methods are used
* to parse text into a mathematical expression. The information is "thrown"
* back and forth from one method to another.
*/
public class ExpressionParser {
/**
* This method uses expression() method to parse the text into mathematical
* expressions, and returns an expression which is the sum of all
* expressions returned from expression() [the sum is calculated according
* to the right operator]
*
* @param st - the Tokenizer parsing the text
* @return - Expression, the sum of all expressions from expression()
* @throws InputException
* @throws IOException
*/
public static Expression sumExpressions(Tokenizer st)
throws InputException, IOException {
boolean endOfLine = false;
Expression temp = expression(st);
int token = Tokenizer.TT_NOTHING;
while (!endOfLine) {
token = st.nextToken();
if ((token == Tokenizer.TT_OPERATOR)
|| (token == Tokenizer.TT_OVERLOADED_OP))
temp = new FatherExpression(st.op, temp, expression(st));
else
endOfLine = true;
}
return temp;
}
public static Expression expression(Tokenizer st) throws InputException, IOException {
Expression result = null;
switch (st.nextToken()) {
case Tokenizer.TT_NUMBER:
result = new NumberExpression(st.nval);
break;
case Tokenizer.TT_VARIABLE:
result = new VariableExpression(st.sval);
break;
case Tokenizer.TT_FUNC:
result = createFunction(st);
break;
case '[':
result = sumExpressions(st);
if (st.ttype != ']')
throw new BracketException("BracketException: "
+ "one too many ']'");
break;
default:
throw new UnexpectedTokenException("Unexpected token on" +
"ExpressionParser.elements(st)");
}
return result;
}
private static Expression createFunction(Tokenizer st)
throws IOException, InputException {
if (InlineManager.getAllInlineFunctions().containsKey(st.sval)) {
InlineFunction temp = InlineManager.getInlineFunction(st.sval);
temp.setArguments(st);
return temp;
}
if (st.sval.equals("MAX"))
return new Max(st);
if (st.sval.equals("MIN"))
return new Min(st);
if (st.sval.equals("POW"))
return new Pow(st);
if (st.sval.equals("MOD"))
return new Mod(st);
if (st.sval.equals("ABS"))
return new Abs(st);
throw new FunctionNameException("Wrong funcion entred " + st.sval);
}
public static HashMap<String, Expression> parseArguments(Tokenizer st)
throws IOException, InputException {
HashMap<String, Expression> result = new HashMap<String, Expression>();
if (st.nextToken() != '{')
throw new UnexpectedTokenException("Missing {");
int argument = 0;
while (true) {
st.ignoreToken(',', true);
switch (st.nextToken()) {
case '}':
st.ignoreToken(',', false);
return result;
case '[':
result.put(String.valueOf(argument++), sumExpressions(st));
break;
case Tokenizer.TT_NUMBER:
result.put(String.valueOf(argument++), new NumberExpression(st.nval));
break;
case Tokenizer.TT_VARIABLE:
result.put(String.valueOf(argument++), new VariableExpression(st.sval));
break;
case Tokenizer.TT_FUNC:
result.put(String.valueOf(argument++), createFunction(st));
break;
default:
throw new UnexpectedTokenException("Unexpected token on function arguments");
}
}
}
}
it long i know. Expression object could be a constant, a variable or a function such as MAX{3,2} which is 3. expression() uses a tokenizer i have built to parse text into an expression, and sumExpression() uses expression() to create a new Expression which is a combination of two Expression object according to the right operator.
i hope its clear. as i said before i can't figure out how to identify the unary minus (-[4] would be -4) thing. i didn't put my tokenizer code, didn't think its necessary.
thanks!
P.S.
the order of calculations is defined to be left to right with no regards to type of operator.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
(前缀)一元运算符和(中缀)二元运算符之间的区别在于它们出现的上下文。二元运算符总是跟在表达式之后,而一元运算符则出现在预期表达式的位置,即在开头、运算符之后或左括号之后。
The difference between (prefix) unary and (infix) binary operators is the context in which they occur. A binary operator always follows an expression, while a unary operator occurs at a position where an expression is expected, i.e. at the start, after an operator or after an opening parenthesis.
“我可以识别其中有一元减号的情况”是拼写错误吗?
看起来,如果您在
parseArguments
中点击“+”、“-”、“*”或“/”,就会立即创建InlineFunction
类的实例并将标记生成器作为参数传递给构造函数。构造函数假设当前标记两侧的内容是该运算符的参数,并且不知道“-”何时实际上应该是一元的。这是正确的吗?你能给我们看看那个构造函数吗?我认为很容易判断“-”何时应该被解析为一元减号 - 这将是二元运算符不合法的地方:在行或括号/等的开头。 - 分隔组,紧接在另一个运算符之后,或在逗号分隔列表中的表达式的开头(即 max、min 等函数的参数的开头)。
Is "I can identify cases in which there's a unary minus" a typo?
It looks like if you hit "+", "-", "*", or "/" in
parseArguments
, you're immediately creating an instance of theInlineFunction
class and passing the tokenizer as the argument to the constructor. The constructor assumes that the things on either side of the current token are the arguments to that operator, and doesn't know when "-" is actually supposed to be unary. Is that correct? Could you show us that constructor?I would think that it would be pretty easy to tell when "-" is supposed to be parsed as a unary minus sign - it would be places where a binary operator isn't legal: at the beginning of a line or parentheses/etc.-delimited group, immediately after another operator, or at the beginning of an expression in a comma-delimited list (i.e. the beginning of an argument to your max, min, etc. functions).