在Java中使用自顶向下的解析器?

  • 本文关键字:自顶向下 Java java
  • 更新时间 :
  • 英文 :


我试图通过使用解析器验证输入字符串:(10+30i)或者我应该说(10+30i)n,但我无法实现StreamTokenizer。TT_EOL,这样我的程序完成时,它看到);检查它是否匹配')'(它确实)并看到下一个令牌是行尾EOL(或者应该是EOF?);并打印出"到达终点"。这是我的代码,我曾试图实现EOL,但没有成功:

import java.io.*;
import static java.util.Objects.requireNonNull;
public class Test2 {
private int lookahead;
private StreamTokenizer tokenizer;
private final Reader input;
private final Writer output;
public Test2(Reader input, Writer output) throws IOException {
this.input = requireNonNull(input);
this.output = requireNonNull(output);
this.lookahead = this.input.read();
}
private void next() throws IOException {
lookahead = tokenizer.nextToken();
if (lookahead == StreamTokenizer.TT_EOL) {
System.out.println("Reached the end!");
}
if (tokenizer.sval != null) {
char ch = tokenizer.sval.charAt(0);
lookahead = (int) ch;
}
}
private void match(int expected) throws IOException {
if (lookahead != expected ) {
switch (expected) {
case '(':
System.out.println("Error, missing opening round bracket.");
break;
case ')':
System.out.println("Error, missing closing round bracket.");
break;
case 'i':
System.out.println("Error, missing i.");
break;
case '+':
System.out.println("Error, missing +");
}
}  else {
next();
}
}
private void parseExpr() throws IOException {
if (lookahead == '(') {
match('(');
if (lookahead == StreamTokenizer.TT_NUMBER) {
next();
} else {
System.out.println("Error, missing number.");
return;
}
match('+');
if (lookahead == StreamTokenizer.TT_NUMBER) {
next();
} else {
System.out.println("Error, missing number.");
return;
}
match('i');
match(')');

System.out.println("We have a complex number.");
next();
parseExpr();
if (lookahead == '+') {
next();
parseExpr();
}

}
}

public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(outputStream);
Test2 parse = new Test2(reader, writer);
parse.tokenizer = new StreamTokenizer(reader);
parse.parseExpr();
writer.close(); // Close and flush output stream writer.
String output = outputStream.toString();
System.out.println("Output generated by parser: " + output);
}
}

我试过调试它,它工作得很好,直到)被识别为一个令牌。

这是调试器的最后一步,然后它停止工作:

输入图片描述

请帮助我:(甚至关于我可以对整个代码进行哪些更改的想法也会对我有很大帮助。

问题是标记器默认情况下不能识别EOL。您需要使用tokenizer.eolIsSignificant(true);启用此功能。

parse.tokenizer = new StreamTokenizer(reader);之后加上parse.tokenizer.eolIsSignificant(true);这一行,标记器应该能识别EOLs

最新更新