我正在尝试为数学表达式做一个简单的词法分析器程序而不进行验证,它将读取一行数学表达式,并根据程序读取的运算符,数字或标识符的类型将其分解为标记。
一切看起来都很好,它会根据令牌的类型返回正确的输出,但我无法检测空格字符,即使我使用了方法 Character.isWhitespace(char) c)中
我想做的是简单地忽略空白并继续下一个角色......
感谢您的帮助...
package Compilers;
import java.lang.*;
import java.io.*;
import java.util.Scanner;
public class MyLexical{ // Lexical processor of symbols
public static void main(String[] args){
char temp;
int temp2,j=0;
Scanner input= new Scanner(System.in);
System.out.println("Please input your mathematical expression.");
String mathExpr= input.next();
for(int i=0; i<mathExpr.length(); i++){
temp= mathExpr.charAt(i);
switch(temp){
case '+': printLex(j,"plus"); break;
case '-': printLex(j,"minus"); break;
case '*': printLex(j,"multiply"); break;
case '/': printLex(j,"divide"); break;
case '=': printLex(j,"equal"); break;
case '(': printLex(j,"lparen"); break;
case ')': printLex(j,"rparen"); break;
case '^': printLex(j,"exponent"); break;
case '%': printLex(j,"modulus"); break;
case ',': printLex(j,"comma"); break;
case '.': printLex(j,"period"); break;
case ';': printLex(j,"semicolon"); break;
case ':': temp2= mathExpr.charAt(i+1);
if(temp2=='='){
i++;
printLex(j,"becomes");
}
else{
printLex(j,"null");;
}
break;
case '<': temp2= mathExpr.charAt(i+1);
if(temp2=='>'){
i++;
printLex(j, "not equal");
}
else if(temp2=='='){
i++;
printLex(j, "less or equal than");
}
else {
printLex(j, "less than");
}
break;
case '>': temp2= mathExpr.charAt(i+1);
if(temp2=='='){
i++;
printLex(j, "greater or equal than");
}
else {
printLex(j, "greater than");
}
break;
default :
if (Character.isDigit(temp)){
int num=0;
do{
num=10*num+Character.getNumericValue(temp);
if((i+1)!=mathExpr.length()){
if (Character.isDigit(mathExpr.charAt(i+1))){
temp=(mathExpr.charAt(i+1));
}
else
break;
}
i++;
} while(i!=mathExpr.length() && Character.isDigit(temp));
printLex(j,String.valueOf(num));
}
else if (Character.isAlphabetic(temp)){
String entry="";
do{
entry+=String.valueOf(temp);
if((i+1)!=mathExpr.length()){
if (Character.isAlphabetic(mathExpr.charAt(i+1))){
temp=(mathExpr.charAt(i+1));
}
else
break;
}
i++;
} while(i!=mathExpr.length() && Character.isAlphabetic(temp));
printLex(j,entry);
}
else if (Character.isWhitespace(temp)){
printLex(j,"space");
}
else {
System.out.println("Bad character");
}
break;
}
j++;
}
}
public static void printLex(int i, String temp){
System.out.println("Token["+i+"]: "+temp);
}
}//Lexical class
答案 0 :(得分:3)
您正在使用Scanner
课程。此类的实例会分解标记中的输入。 next()
方法将返回下一个标记,并且(默认情况下)已经忽略空格。因此,您的mathExpr
变量将永远不会包含任何空白字符。
您可能想要阅读整行用户输入。为此,您可以使用nextLine()
类的Scanner
方法。
但是既然你想做自己的标记化,那么Scanner
可能有点过分。您还可以使用BufferedReader
,如下所示:
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader r = new BufferedReader(isr);
String mathExpr = r.readLine();
答案 1 :(得分:0)
您可以使用continue
关键字来保留跳过空格:
switch (temp) {
...
case ' ': continue;
}
此外,input.next()
只能读取一个令牌,而不是一行。也许您应该使用input.nextLine()
。默认情况下,使用此空白正则表达式对标记进行分隔:\p{javaWhitespace}+