shamp113
shamp113

Reputation: 11

How to create a method that searches an input file

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

Answers (1)

Qazi Fahim Farhan
Qazi Fahim Farhan

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

Related Questions