我在Java中创建了一个简单的词法分析器程序,它提示用户输入一个字符串并在该字符串中显示词法。但是,当我输入一个值时,如果提示中包含左括号和/或右括号,则在左括号或右括号后面会添加一个空字符,它会被程序识别为标识符。
此外,如果我在用户提示的字符串中不包括左括号和右括号,则字符串中的最后一个字符不会被评估为词位。
这是我的代码:
import javax.swing.JOptionPane;
public class Append
{
public static void main (String [] args)
{
String str = JOptionPane.showInputDialog("Enter string : ");
char [] arr = str.toCharArray();
JOptionPane.showMessageDialog(null,arr.length);
determineLexemes(arr);
}
public static void determineLexemes(char [] arr)
{
int j = 0;
String [] arrayString = new String [1000];
String strTwo = "";
System.out.println("Symbol Table");
System.out.println("Lexeme\t\tToken");
for(int i = 0; i < arr.length; i++)
{
if(arr[i] == '+')
{
System.out.println("+ \t\t ADD_OP");
}
if(arr[i] == '-')
{
System.out.println("- \t\t SUB_OP");
}
if(arr[i] == '*')
{
System.out.println("* \t\t MULT_OP");
}
if(arr[i] == '/')
{
System.out.println("/ \t\t DIV_OP");
}
if(arr[i] == '(')
{
System.out.println("( \t\t LEFT_PAREN");
}
if(arr[i] == ')')
{
System.out.println(") \t\t RIGHT_PAREN");
}
if(arr[i] == '=')
{
System.out.println("= \t\t EQUAL_OP");
}
if(Character.isLetter(arr[i]) || Character.isDigit(arr[i]))
{
strTwo += arr[i];
}
if(!Character.isLetter(arr[i]) && !Character.isDigit(arr[i]))
{
if(!(Character.isWhitespace(arr[i])))
{
arrayString[j] = strTwo;
System.out.println(arrayString[j] + "\t\t" + "IDENTIFIER");
strTwo = "";
j++;
}
}
}
}
}
感谢您解决问题的任何帮助。
答案 0 :(得分:0)
问题是你没有在词法分析器中保持状态。识别常规语言可以使用有限自动机来完成,这是一种跟踪其状态的简单机制(并且可以保持缓冲以累积更长的词位)。
因此,首先应将状态设置为S0,并识别每个运算符和括号,并保持状态S0。对于一封信,您输入SI,并保留,同时在SI中识别更多字母和数字。运算符终止SI,并发出运算符并返回S0。 - 识别S0中的数字,输入SN,并以类似于SI的方式处理。
enum State { S0, IDENTIFIER, NUMBER }
State state = State.S0;
for(int i = 0; i < arr.length; i++) {
switch( state ){
case S0:
switch(arr[i]){
case '+':
System.out.println("+ \t\t ADD_OP");
break;
//...
default:
if(Character.isLetter(arr[i])){
strTwo = ""; strTwo += arr[i];
state = State.IDENTIFIER;
}
if(Character.isDigit(arr[i])){
strTwo = ""; strTwo += arr[i];
state = State.NUMBER;
}
break;
}
case IDENTIFIER:
if(Character.isLetter(arr[i]) || Character.isDigit(arr[i])){
strTwo += arr[i];
} else {
System.out.println(strTwo + "\t\t" + "IDENTIFIER");
i--;
state = State.S0;
}
break;
case NUMBER:
if(Character.isDigit(arr[i])){
strTwo += arr[i];
} else {
System.out.println(strTwo + "\t\t" + "NUMBER");
i--;
State = State.S0;
}
break;
}
这里缺少一些东西:处理输入字符串末尾的数字或标识符。这可以通过检查变量状态和使用strTwo的内容来确定。