我正在用Java编写一个记号赋予器,它必须处理操作符,并且记号之间的空格字符不是必需的。
我需要将"<=“之类的东西识别为标记,同时还需要识别"<”和"=“。
现在我有:
if (token == '<')
if (nextToken == '=')
this.tokenList.add(27); // <=
else
// add 2 tokens separately有没有办法让StreamTokenizer自己来做这件事?我已经通读了API,但我什么也没看到。
我可以指定可以算作一个的令牌组合吗?理想情况下,getNextToken会一次删除两个令牌。
谢谢!
发布于 2011-04-19 07:29:48
StreamTokenizer为您提供的是基本词法分析器的功能。你必须使用这些来制作你的高端版本。
您必须非常明智地使用nextToken()和pushBack()。例如,在下面的示例中,我负责处理<、<<和<=。如果您看到操作符<,则向前查看流中的线索,如果没有找到后面的<或=,则将look ahead标记推回到流中。
>>示例代码
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
public class LexerTest
{
private StringReader r;
public LexerTest(StringReader stringReader) {
r = stringReader;
}
public static void main(String[] args) throws IOException
{
String s = "test = test1 + (test2 * test3 * (test4 - 2);";
new LexerTest(new StringReader(s)).printTokens();
System.out.println("\n### Test 2 ###\n");
s = "test = if(test1 < test2){ test3 = (test4 - 2);}";
new LexerTest(new StringReader(s)).printTokens();
System.out.println("\n### Test 3 ###\n");
s = "test = if(test1 <= test2){ test3 = (test4 - 2);}";
new LexerTest(new StringReader(s)).printTokens();
System.out.println("\n### Test 4 ###\n");
s = "test = if(test1 < test2){ test3 = (test4 << 2);}";
new LexerTest(new StringReader(s)).printTokens();
}
private void printTokens() throws IOException
{
StreamTokenizer st = new StreamTokenizer(r);
st.eolIsSignificant(true);
int token = st.nextToken();
while (token != StreamTokenizer.TT_EOF)
{
token = st.nextToken();
switch (token)
{
case StreamTokenizer.TT_NUMBER:
double num = st.nval;
System.out.println("Number found: " + num);
break;
case StreamTokenizer.TT_WORD:
String word = st.sval;
System.out.println("Word found: " + word);
break;
case '+':
break;
case '-':
break;
case '/':
break;
case '*':
break;
case '<':
{
int t = st.nextToken();
switch(t)
{
case '=':
System.out.println("<=");
break;
case '<':
System.out.println("<<");
break;
default:
st.pushBack();
System.out.println("<");
break;
}
}
}
}
}
}希望这能有所帮助。
发布于 2011-04-19 06:59:54
对于所提供的记号赋予器类,这不是一个典型的场景。更像是一个成熟的解析器必须处理的东西。即使您需要手动构建这样的记号生成器,您也会发现研究由解析器生成器(如javacc或antlr )生成的代码是很有教育意义的。专注于他们如何处理“前瞻”,这就是你在这里问的。
除非这是一个作业问题,不允许使用解析器生成器,否则使用解析器生成器会得到更好的结果。
发布于 2011-04-19 07:00:27
看起来StreamTokenizer有点太基础了。
我建议你在StreamTokenizer之上构建一个词法分析器。这个词法分析器所做的就是在通常意义上给你一个实际的令牌流。也就是说,<=将作为单个令牌给出,而不是两个单独的令牌。
更好的方法是,将StreamTokenizer绑定并编写一个只直接查看字符的lexer。StreamTokenizer所做的工作太少,对解析高级语法没有用处。
https://stackoverflow.com/questions/5709393
复制相似问题