我正在尝试创建一个词法分析器
cond_exp →条件 | 条件操作cond_exp
条件 → single_cond |(条件) |cond_exp
single_cond →变量 | 变量' | 常量
OP → 和 | 或 | 暗示
常数 → 真 | 假 | !真 | 假
变量 → p|q|r
对于 lex 操作中的开关大小写,我得到了一个重复的案例标签,我将不胜感激,这就是我到目前为止所拥有的:
举个例子,这是一个示例字符串:((p' 和 q) 暗示 (r 或 r'))
public class Q4Lexical {
//character classes
private static final String Letter="0";
private static final String opLetter="0";
private static final String unknown="99";
private static final String EOF="100";
//Token classes
public static final String INT_LIT="10";
public static final String IDENT="11";
public static final String pVarible="20";
public static final String qVarible="21";
public static final String rVarible="22";
public static final String andOperation="23";
public static final String orOperation="24";
public static final String impliesOperation="25";
public static final String tConstant="26";
public static final String fConstant="27";
public static final String tpConstant="28";
public static final String fpConstant="29";
public static final String LEFT_PAREN="30";
public static final String RIGHT_PAREN="31";
// Global Variables
public static int current=0;
static String StringClass;
static String lexeme="";
static String nextChar;
static int lexLen=0;
static int token;
static String nextToken;
static String expression="((p' and q) implies (r or r'))";
public static boolean isVarible (String c){
if((c.equalsIgnoreCase("p")) || (c.equalsIgnoreCase("q")) ||
(c.equalsIgnoreCase("r")) || (c.equalsIgnoreCase("p'")) ||
(c.equalsIgnoreCase("q'")) || (c.equalsIgnoreCase("r'")))
return true;
else return false;
}
public static boolean isOperation(String c){
if((c.equalsIgnoreCase("and")) || (c.equalsIgnoreCase("or")) ||
(c.equalsIgnoreCase("implies")))
return true;
else return false;
}
public static boolean isSpace(String c){
if(c.equalsIgnoreCase(" "))
return true;
else return false;
}
public static void getString(){
if(current< expression.length()){
nextChar= expression.substring(current);
current++;
if(isVarible(nextChar))
StringClass=Letter;
else if(isOperation(nextChar))
StringClass=opLetter;
else
StringClass=unknown;
}
else
StringClass = "#";
}
public static void getNonBlank(){
while(isSpace(nextChar))
getString();
}
public static String lookup(String c){
switch(c){
case "(":
addString();
nextToken= LEFT_PAREN;
break;
case ")":
addString();
nextToken= RIGHT_PAREN;
break;
case "and":
addString();
nextToken= andOperation;
break;
case "or":
addString();
nextToken=orOperation;
break;
case "implies":
addString();
nextToken=impliesOperation;
break;
default:
addString();
nextToken=unknown;
break;
}
return nextToken;
}
public static void addString(){
if (lexLen <= 98)
lexeme+=nextChar;
else
System.out.println("Error - Lexeme is too long");
}
public static String lex(){
lexeme="";
lexLen=0;
getNonBlank();
switch(StringClass){
case Letter:
addString();
getString();
while(StringClass.equals(Letter) || StringClass.equals(opLetter)){
addString();
getString();
}
switch (nextToken) {
case "q":
nextToken=qVarible;
break;
case "p":
nextToken=pVarible;
break;
case "r":
nextToken=rVarible;
break;
}
break;
case opLetter:
addString();
addString();
while (StringClass.equals(opLetter)){
addString();
getString();
}
nextToken=INT_LIT;
break;
case unknown:
lookup(nextChar);
getString();
break;
case EOF:
nextToken=EOF;
break;
}
System.out.println("Next Token is : "+nextToken+" Next Lexeme is : "+lexeme);
return nextToken;
}
public static void main(String[] args) {
getString();
do {
lex();
} while (current != expression.length());
}
}
字母和opLetter都等于同一个东西,"0",
// character classes
private static final String Letter = "0";
private static final String opLetter = "0";
并且您的编译器正在抱怨,因为您不允许两个大小写常量相同。
switch (StringClass) {
case Letter:
// ....
// not allowed
case opLetter:
另外,它只是没有意义。如果 StringClass 为"0",则应激活哪种情况?
解决方案:不要让它们等于同一件事。更好的是,考虑使用枚举。