Java 自定义标记器、带引号的迭代器
也许有人能帮忙? 如何修改此方法next(),使下一个标记可以是带引号的“abc”文本。 现在,如果文本包含引号,则在位置处抛出ExpressionException未知运算符“”Java 自定义标记器、带引号的迭代器,java,text,iterator,token,Java,Text,Iterator,Token,也许有人能帮忙? 如何修改此方法next(),使下一个标记可以是带引号的“abc”文本。 现在,如果文本包含引号,则在位置处抛出ExpressionException未知运算符“” @Override public String next() { StringBuilder token = new StringBuilder(); if (pos >= input.length()) { return previousTok
@Override
public String next() {
StringBuilder token = new StringBuilder();
if (pos >= input.length()) {
return previousToken = null;
}
char ch = input.charAt(pos);
while (Character.isWhitespace(ch) && pos < input.length()) {
ch = input.charAt(++pos);
}
if (Character.isDigit(ch)) {
while ((Character.isDigit(ch) || ch == decimalSeparator)
&& (pos < input.length())) {
token.append(input.charAt(pos++));
ch = pos == input.length() ? 0 : input.charAt(pos);
}
} else if (ch == minusSign
&& Character.isDigit(peekNextChar())
&& ("(".equals(previousToken) || ",".equals(previousToken)
|| previousToken == null || operators
.containsKey(previousToken))) {
token.append(minusSign);
pos++;
token.append(next());
} else if (Character.isLetter(ch)) {
while ((Character.isLetter(ch) || Character.isDigit(ch) || (ch == '_')) && (pos < input.length())) {
token.append(input.charAt(pos++));
ch = pos == input.length() ? 0 : input.charAt(pos);
}
} else if (ch == '(' || ch == ')' || ch == ',') {
token.append(ch);
pos++;
//FIXME
else if (ch == '\''){
pos++;
String temp = "\'"+next()+"\'";
token.append(temp);
pos++;
}
//
} else {
while (!Character.isLetter(ch) && !Character.isDigit(ch)
&& !Character.isWhitespace(ch) && ch != '('
&& ch != ')' && ch != ',' && (pos < input.length())) {
token.append(input.charAt(pos));
pos++;
ch = pos == input.length() ? 0 : input.charAt(pos);
if (ch == minusSign) {
break;
}
}
if (!operators.containsKey(token.toString())) {
throw new ExpressionException("Unknown operator '" + token
+ "' at position " + (pos - token.length() + 1));
}
}
return previousToken = token.toString();
}
它位于eval方法objectv1=stack.pop()中代码>行
谢谢 在方法next
中,在两个位置有递归调用:
看到负号后
在认出一根绳子之后
第一种情况将构造符号,其中负号后面跟一个数字(即,后面跟一个非奇数)-OK。(虽然没有符号,但一元减号运算符值得考虑。)
第二种情况意味着麻烦。在经过初始撇号之后,会出现下一个结果,就好像字符串文字只包含一个数字、一个标识符或一个运算符一样。无论如何,next()将执行,假设它返回一个数字:然后在标记中添加一个撇号,但不需要检查是否有结束撇号,也不需要跳过它
else if (ch == '\''){
token.append( '\'' );
pos++;
while( pos < input.length() &&
(ch = input.charAt(pos++)) != '\'' ){
token.append( ch );
}
token.append( '\'' );
else if(ch='\''){
token.append('\'');
pos++;
while(pos
这不允许撇号成为字符串中的字符,也不会诊断未终止的字符串。但这可以很容易地添加。寻求调试帮助的问题(“为什么此代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现该问题所需的最短代码。没有明确问题陈述的问题对其他读者不有用。请参阅。所需的行为是上面的标记器示例可以返回varchar标记:quote+text+quote。请添加完整堆栈跟踪to你的问题与你的代码的其余部分一起。从上面的链接中提供重现问题所需的所有部分。我不知道你的代码试图做什么,但你为什么试图从一个空的堆栈中pop()
?这是你要解决的。。。
private List<String> getRPN() {
if (rpn == null) {
rpn = shuntingYard(this.expression);
}
return rpn;
}
private List<String> shuntingYard(String expression) {
List<String> outputQueue = new ArrayList<String>();
Stack<String> stack = new Stack<String>();
Tokenizer tokenizer = new Tokenizer(expression);
String lastFunction = null;
while (tokenizer.hasNext()) {
String token = tokenizer.next();
if (isNumber(token)) {
outputQueue.add(token);
} else if (variables.containsKey(token)) {
outputQueue.add(token);
} else if (functions.containsKey(token.toUpperCase())) {
stack.push(token);
lastFunction = token;
} else if (Character.isLetter(token.charAt(0))) {
if ("\'".equals(Character.toString(token.charAt(0)))){
outputQueue.add(token);
} else {
stack.push(token);
}
} else if (",".equals(token)) {
while (!stack.isEmpty() && !"(".equals(stack.peek())) {
outputQueue.add(stack.pop());
}
if (stack.isEmpty()) {
throw new ExpressionException("Parse error for function '"
+ lastFunction + "'");
}
} else if (operators.containsKey(token)) {
Operator o1 = operators.get(token);
String token2 = stack.isEmpty() ? null : stack.peek();
while (operators.containsKey(token2)
&& ((o1.isLeftAssoc() && o1.getPrecedence() <= operators
.get(token2).getPrecedence()) || (o1
.getPrecedence() < operators.get(token2)
.getPrecedence()))) {
outputQueue.add(stack.pop());
token2 = stack.isEmpty() ? null : stack.peek();
}
stack.push(token);
} else if ("(".equals(token)) {
stack.push(token);
} else if (")".equals(token)) {
while (!stack.isEmpty() && !"(".equals(stack.peek())) {
outputQueue.add(stack.pop());
}
if (stack.isEmpty()) {
throw new RuntimeException("Mismatched parentheses");
}
stack.pop();
if (!stack.isEmpty()
&& functions.containsKey(stack.peek().toUpperCase())) {
outputQueue.add(stack.pop());
}
}
}
while (!stack.isEmpty()) {
String element = stack.pop();
if ("(".equals(element) || ")".equals(element)) {
throw new RuntimeException("Mismatched parentheses");
}
if (!operators.containsKey(element)) {
throw new RuntimeException("Unknown operator or function: "
+ element);
}
outputQueue.add(element);
}
return outputQueue;
}
*java.util.EmptyStackException
at java.util.Stack.peek(Unknown Source)
at java.util.Stack.pop(Unknown Source)
at com.business.Expression.eval(Expression.java:1033)*
else if (ch == '\''){
token.append( '\'' );
pos++;
while( pos < input.length() &&
(ch = input.charAt(pos++)) != '\'' ){
token.append( ch );
}
token.append( '\'' );