Java简单Lexer程序
我用Java创建了一个简单的lexer程序,它提示用户输入一个字符串并显示该字符串中的词素。但是,当我输入一个值时,如果提示中包含左括号和/或右括号,则在左括号或右括号后添加一个空字符,该字符由程序标识为标识符 此外,如果在用户提示的字符串中不包含左括号和右括号,则字符串中的最后一个字符不会作为词素计算 这是我的密码:Java简单Lexer程序,java,lexical-analysis,Java,Lexical Analysis,我用Java创建了一个简单的lexer程序,它提示用户输入一个字符串并显示该字符串中的词素。但是,当我输入一个值时,如果提示中包含左括号和/或右括号,则在左括号或右括号后添加一个空字符,该字符由程序标识为标识符 此外,如果在用户提示的字符串中不包含左括号和右括号,则字符串中的最后一个字符不会作为词素计算 这是我的密码: import javax.swing.JOptionPane; public class Append { public static void main (String
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++;
}
}
}
}
}
import javax.swing.JOptionPane;
公共类附加
{
公共静态void main(字符串[]args)
{
String str=JOptionPane.showInputDialog(“输入字符串:”);
char[]arr=str.toCharArray();
JOptionPane.showMessageDialog(null,arr.length);
确定性基因(arr);
}
公共静态void determineLexemes(char[]arr)
{
int j=0;
String[]arrayString=新字符串[1000];
字符串strTwo=“”;
System.out.println(“符号表”);
System.out.println(“Lexeme\t\tToken”);
对于(int i=0;i
感谢您为解决此问题提供的任何帮助。问题在于您没有在lexer中维护状态。识别一种常规语言可以用有限自动机来完成,这是一种跟踪其状态的简单机制(并且可以为积累更长的词素保留一个缓冲区) 因此,最初您应该将状态设置为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;
}
enum状态{S0,标识符,编号}
State=State.S0;
对于(int i=0;i
这里缺少一些东西:处理输入字符串末尾的数字或标识符。这可以通过检查变量状态和使用strTwo的内容来确定。您有一些示例输入吗?这可以而且应该作为命令行应用程序进行调试。因此,我正在删除Swing标记。一个输入是(a+b)它显示所有词素,但在(和a之间)添加一个新的词素。另一个输入是a+b。它仅将+和a显示为词素(即它跳过将b作为词素)。尝试使用类似于
if(!(Character.isWhitespace(arr[i])&&!strTwo.isEmpty()的方法{
另外,让我向你介绍我的小朋友System.out.printf
,System.out.printf(“%s%20s%n”,“=”,“EQUAL_OP”);
你能再解释一下如何维护状态吗。你提供的描述对我来说很复杂,想想“有限自动机”基本上是一个有向图,图中的每个“节点”都是一个“状态”,一次只能在一个“节点”中(从技术上讲,这是“确定性有限自动机”,但嘿…)这就是它的用途,然后你有从一个状态到另一个状态的“转换”,这些转换是有效的输入字符…当你“读”字符时,你在图形中移动,如果你读的字符没有转换,这意味着输入的“句子”与你的语法不匹配(词汇量识别的语言)@user3023315我的代码被剪断现在是可以忍受的(除了i--
,我讨厌在for语句中这样做),尽管还有其他(更好的)实现技术。