Reputation: 11
I am working on a project where I have to create a parser. The idea of the project is for a method lex() to act as a lexical analyzer and scan an input file which I will include below. the file includes a line in the input file stating which statement is being parsed and then each token of this statement below the statement. I created an enum
of tokens to be compared to in my lex()
method. What my lex method should do is use a scanner to find the next line of the file, compare it to the enum, and if it matches, store it in nextToken
and then return it. My issue is that I cannot figure out how to deal with when the nextLine()
and tokens.toString()
do not match which would indicate that either the file is empty, it is the end of file, or the line it is comparing is "Parsing the Statement: statement". How could I update my lex()
method of
public static tokens lex()
{
String str = scanner.nextLine();
while(str != null)
{
for(tokens token : tokens.values())
{
if(str.equals(token.toString()))
{
tokens nextToken = token;
return nextToken;
}
}
}
return nextToken;
to be able to handle the parsing the statement lines and only compare the tokens.
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Scanner;
public class Parse
{
//Scanner to read for each line of the input file
static Scanner scanner = new Scanner("statements.txt");
private static tokens nextToken = null;
public static String str = null;
public static PrintStream outputPrint;
public static void main(String[] args) throws FileNotFoundException, IOException
{
outputPrint = new PrintStream("lexOutput.txt");
outputPrint.println("********************************************************************************");
outputPrint.println("Shane Hampton, CSCI4200, Fall 2019, Parser");
outputPrint.println("********************************************************************************");
/*lex();
if(nextToken != null)
{
if(nextToken == tokens.IDENT)
{
outputPrint.println
outputPrint.println
}
}
else
{
outputPrint.println(str);
}*/
}
/** Lex Method to return the token from each line when called **/
public static tokens lex()
{
String str = scanner.nextLine();
while(str != null)
{
for(tokens token : tokens.values())
{
if(str.equals(token.toString()))
{
tokens nextToken = token;
return nextToken;
}
}
}
return nextToken;
/*while(str != null)
{
for(tokens token : tokens.values())
{
if(str.equals(token.toString()))
{
tokens nextToken = token;
return nextToken;
}
}
}
return nextToken;*/
}/** END OF LEX METHOD **/
enum tokens
{
END_OF_FILE, LEFT_PAREN, RIGHT_PAREN, ASSIGN_OP, ADD_OP,
SUB_OP, MULT_OP, DIV_OP, IDENT, INT_LIT
}
/**********************************************************/
/* assign
Parses strings in the language generated by the rule:
<assign> -> id = <expr>
*/
public void assign() throws IOException
{
System.out.printf("Enter <assign>\n");
/* Parse the first expression */
expr();
System.out.printf("Exit <assign>\n");
}/* End of function assign */
/**********************************************************/
/* expr
Parses strings in the language generated by the rule:
<expr> -> <term> {(+ | -) <term>}
*/
public void expr() throws IOException
{
System.out.printf("Enter <expr>\n");
/* Parse the first term */
term();
/* As long as the next token is + or -, get
the next token and parse the next term */
while (nextToken == tokens.ADD_OP || nextToken == tokens.SUB_OP)
{
lex();
term();
}
System.out.printf("Exit <expr>\n");
} /* End of function expr */
/**********************************************************/
/* term
Parses strings in the language generated by the rule:
<term> -> <factor> {(* | /) <factor>)
*/
public void term() throws IOException
{
System.out.printf("Enter <term>\n");
/* Parse the first factor */
factor();
/* As long as the next token is * or /, get the
next token and parse the next factor */
while (nextToken == tokens.MULT_OP || nextToken == tokens.DIV_OP)
{
lex();
factor();
}
System.out.printf("Exit <term>\n");
} /* End of function term */
/**********************************************************/
/* factor
Parses strings in the language generated by the rule:
<factor> -> id | int_constant | ( <expr )
*/
public void factor() throws IOException
{
System.out.printf("Enter <factor>\n");
/* Determine which RHS */
if (nextToken == tokens.IDENT || nextToken == tokens.INT_LIT)
{
/* Get the next token */
lex();
}
else
{
if (nextToken == tokens.LEFT_PAREN)
{
lex();
expr();
if (nextToken == tokens.RIGHT_PAREN)
{
lex();
}
else
{
Error(null);
}
} /* End of if (nextToken == ... */
else
{
Error(null);
} /* End of else */
}
System.out.printf("Exit <factor>\n");
} /* End of function factor */
/*********************************************************/
/* Method to show an that an error exists when the method is called*/
private void Error(String s)
{
System.out.printf("There is an Error");
}
/*********************************************************/
}
Parsing the statement: sumTotal = (sum + 47 ) / total
IDENT
ASSIGN_OP
LEFT_PAREN
IDENT
ADD_OP
INT_LIT
RIGHT_PAREN
DIV_OP
IDENT
Parsing the statement: Total = (sum + 47 ) /
IDENT
ASSIGN_OP
LEFT_PAREN
IDENT
ADD_OP
INT_LIT
RIGHT_PAREN
DIV_OP
Parsing the statement: area = (length + width) / 2
IDENT
ASSIGN_OP
LEFT_PAREN
IDENT
ADD_OP
IDENT
RIGHT_PAREN
DIV_OP
INT_LIT
Parsing the statement: ageNumbers = age + 3 - 5 * (D / C)
IDENT
ASSIGN_OP
IDENT
ADD_OP
INT_LIT
SUB_OP
INT_LIT
MULT_OP
LEFT_PAREN
IDENT
DIV_OP
IDENT
RIGHT_PAREN
END_OF_FILE
Upvotes: 1
Views: 191
Reputation: 2176
In your while loop, there is no break condition. So if you have input str = "any random value except those tokens"
, you fall inside an infinite loop. Since you are using str = scanner.nextLine()
, it reads the entire line, not the tokens( ie, including tailing spaces, etc) so you get str = "DIV_OP "
, not str="DIV_OP"
. There are some of the problems.
Anyways, I have just written a sample code:
import java.util.*;
public class Start{
static Scanner sc;
public static void main(String[] args) {
sc = new Scanner(System.in);
while(sc.hasNext()){
try{
tokens t = lex();
if(t != null){
System.out.println("Found token: "+t.toString());
}
}catch(Exception x){ x.printStackTrace(); }
}
}
public static tokens lex(){
tokens ret = null;
String s = sc.nextLine();
if(s.contains("Parsing the statement:")){
System.out.println("Found parsing statement line!!!");
return null;
}else{
//System.out.print(s);
for(tokens token : tokens.values()){
if(s.contains(token.toString())){
System.out.println("Found a token!!!");
ret = token;
return ret;
}
}
}
System.out.println("Default case!!!");
return ret;
}
enum tokens
{
END_OF_FILE, LEFT_PAREN, RIGHT_PAREN, ASSIGN_OP, ADD_OP,
SUB_OP, MULT_OP, DIV_OP, IDENT, INT_LIT
}
}
Here, I used str.contains("Parsing ...")
to detect those lines. Please have a look, and if you have any questions, feel free to ask.
Upvotes: 1