I'm trying to create a lexical analyzer for
cond_exp → condition | condition op cond_exp
condition → single_cond | (condition) | cond_exp
single_cond → variable | variable' | constant
op → and | or | implies
constant → true | false | !true | !false
variable → p|q|r
for the switch case in lex operation i'm getting a duplicate case label, I would appreciate your help, This is what I have so far :
and as for an example this is a sample string : ((p' and q) implies (r or 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());
}
}
Letter and opLetter both equal the same thing, "0",
and your compiler is complaining since you're not allowed to have two case constants be the same.
Plus it just doesn't make sense. Which case should be activated if StringClass is "0"?
Solution: don't have them equal the same thing. Better still, consider using enums.