java - 如何创建搜索输入文件的方法

标签 java

我正在开发一个项目,我必须创建一个解析器。该项目的想法是让方法 lex() 充当词法分析器并扫描我将在下面包含的输入文件。该文件在输入文件中包含一行,说明正在解析哪个语句,然后在该语句下方包含该语句的每个标记。我创建了一个标记的 enum 来与我的 lex() 方法进行比较。我的 lex 方法应该做的是使用扫描器查找文件的下一行,将其与枚举进行比较,如果匹配,则将其存储在 nextToken 中,然后返回它。我的问题是,当 nextLine()tokens.toString() 不匹配时,我无法弄清楚如何处理,这表明文件为空,它是文件末尾,或者它正在比较的行是“解析语句:语句”。我如何更新

lex() 方法
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;

能够处理语句行的解析并仅比较标记。

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

最佳答案

在 while 循环中,没有中断条件。因此,如果您输入 str = "any random value except those tokens",您就会陷入无限循环。由于您使用的是 str = Scanner.nextLine(),它会读取整行,而不是标记(即,包括尾部空格等),因此您会得到 str = "DIV_OP ",而不是str="DIV_OP"。存在一些问题。 无论如何,我刚刚编写了示例代码:

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
    }
}

在这里,我使用 str.contains("Parsing ...") 来检测这些行。请看一下,如果您有任何疑问,请随时提问。

关于java - 如何创建搜索输入文件的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58821167/

相关文章:

java - 检查时间是否在最小和最大范围内

java - Spring:如何在 Spring 配置中注入(inject) ENUM?

java - 无法让 Jersey 映射工作

java - 使用 VBO LWJGL 渲染时出现 fatal error

java - 无法解析或不是字段

java - @RequestMapping ("/main")在 netbeans spring 4 中不起作用,但在 spring 3 中起作用

java - Spring Data Jpa 查询 dsl 与 fetch join

java - 如何将 .jar 文件添加到 BlueJ 项目?

java - Java 嵌入式系统中用于存储位字符串的 boolean 数组或字符串

java.lang.ClassCastException : java. 使用 Univocity 时,util.Date 无法转换为 java.lang.String