2017-10-23 22 views
1

Java에서 어휘 분석기를 작성 중입니다. 이것은 내가 지금 가지고있는 것입니다 : 내가 좋아하는 '9'와 운영자에 '0'에서 숫자를 읽을 수있는 코드로Java로 파일에서 산술 표현식의 자연수 읽기.

import java.io.*; 

enum TokenType{ NUM,SOMA, MULT,APar,FPar, EOF} 

class Token{ 
    char lexema; 
    TokenType token; 

    Token (char l, TokenType t) 
    { lexema=l;token = t;}  

} 

class AnaliseLexica { 

BufferedReader arquivo; 

AnaliseLexica(String a) throws Exception 
{ 

    this.arquivo = new BufferedReader(new FileReader(a)); 

} 

Token getNextToken() throws Exception 
{ 
    Token token; 
    int eof = -1; 
    char currchar; 
    int currchar1; 

     do{ 
      currchar1 = arquivo.read(); 
      currchar = (char) currchar1; 
     } while (currchar == '\n' || currchar == ' ' || currchar =='\t' || currchar == '\r'); 

     if(currchar1 != eof && currchar1 !=10) 
     { 


      if (currchar >= '0' && currchar <= '9') 
       return (new Token (currchar, TokenType.NUM)); 
      else 
       switch (currchar){ 
        case '(': 
         return (new Token (currchar,TokenType.APar)); 
        case ')': 
         return (new Token (currchar,TokenType.FPar)); 
        case '+': 
         return (new Token (currchar,TokenType.SOMA)); 
        case '*': 
         return (new Token (currchar,TokenType.MULT)); 

        default: throw (new Exception("Caractere inválido: " + ((int) currchar))); 
       } 
     } 

     arquivo.close(); 

    return (new Token(currchar,TokenType.EOF)); 

} 

'*', '+'코드의이 부분 사용 :

do{ 
     currchar1 = arquivo.read(); 
     currchar = (char) currchar1; 
    } while (currchar == '\n' || currchar == ' ' || currchar =='\t' || currchar == '\r'); 

파일에서 자연수를 읽고 산술 연산자를 계속 읽는 방법은 무엇입니까?

+0

가를 추적 당신이 클래스 스캐너를 사용할 수없는 경우

import java.io.FileReader; import java.io.IOException; import java.util.Scanner; public class AnalisadorLexico { public enum TokenType { NUM, SOMA, MULT, APar, FPar, EOF } public class Token { String lexema; TokenType token; Token(String l, TokenType t) { lexema = l; token = t; } Token(char l, TokenType t) { lexema = String.valueOf(l); token = t; } @Override public String toString() { return lexema + " (" + token + ")"; } } private Scanner fileReader; private boolean scannerClosed; public AnalisadorLexico(String filePath) throws IOException { fileReader = new Scanner(new FileReader(filePath)); } public Token getNextToken() throws IOException { if (!scannerClosed && fileReader.hasNext()) { String currentData = fileReader.next(); try { Integer.parseInt(currentData); return new Token(currentData, TokenType.NUM); } catch (NumberFormatException exc) { } switch (currentData) { case "(": return new Token(currentData,TokenType.APar); case ")": return new Token(currentData,TokenType.FPar); case "+": return new Token(currentData,TokenType.SOMA); case "*": return new Token(currentData,TokenType.MULT); } } else { scannerClosed = true; fileReader.close(); return new Token("", TokenType.EOF); } return null; } public static void main(String[] args) throws IOException { AnalisadorLexico al = new AnalisadorLexico("testAL.txt"); Token t = null; while ((t = al.getNextToken()).token != TokenType.EOF) { System.out.println(t); } System.out.println(al.getNextToken()); System.out.println(al.getNextToken()); System.out.println(al.getNextToken()); System.out.println(al.getNextToken()); } } 

, 당신은 데이터를 토큰 화,을, BufferedReader를 계속 사용할 수 있습니다 현재 char로 처리 할 작업을 알 수 있거나 처리중인 토큰 유형을 추적 할 수있는 이전 char. – davidbuzatto

답변

0

공백은 토큰의 유효한 분리 기호이므로 코드를 더 간단하게 만들 수 있습니다. Scanner 클래스는 기본적으로 읽기 값을 공백으로 구분합니다. 당신은 하나씩 읽을 필요가 있습니다. 스캐너에 더 이상 읽을 데이터가 없으면이를 닫고 EOF 토큰을 반환합니다. 내 testAL.txt 파일의 내용이

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 

public class AnalisadorLexico2 { 

    public enum TokenType { 
     NUM, 
     SOMA, 
     MULT, 
     APar, 
     FPar, 
     EOF 
    } 

    public class Token { 

     String lexema; 
     TokenType token; 

     Token(String l, TokenType t) { 
      lexema = l; 
      token = t; 
     } 

     Token(char l, TokenType t) { 
      lexema = String.valueOf(l); 
      token = t; 
     } 

     @Override 
     public String toString() { 
      return lexema + " (" + token + ")"; 
     } 

    } 

    private BufferedReader fileReader; 
    private boolean fileReaderClosed; 

    public AnalisadorLexico2(String filePath) throws IOException { 
     fileReader = new BufferedReader(new FileReader(filePath)); 
    } 

    public Token getNextToken() throws IOException { 

     String currentData = nextBufferedReaderToken(); 

     if (currentData != null) { 

      try { 
       Integer.parseInt(currentData); 
       return new Token(currentData, TokenType.NUM); 
      } catch (NumberFormatException exc) { 
      } 

      switch (currentData) { 
       case "(": 
        return new Token(currentData,TokenType.APar); 
       case ")": 
        return new Token(currentData,TokenType.FPar); 
       case "+": 
        return new Token(currentData,TokenType.SOMA); 
       case "*": 
        return new Token(currentData,TokenType.MULT); 
      } 

     } else { 
      if (!fileReaderClosed) { 
       fileReaderClosed = true; 
       fileReader.close(); 
      } 
      return new Token("", TokenType.EOF); 
     } 

     return null; 

    } 

    public String nextBufferedReaderToken() throws IOException { 

     boolean started = false; 
     String data = null; 

     while (!fileReaderClosed) { 

      int d = fileReader.read(); 
      char c = (char) d; 

      if (d != -1) { 

       if (c == '\n' || c == ' ' || c == '\t' || c == '\r') { 
        if (!started) { 
         // discard... 
        } else { 
         break; 
        } 
       } else { 
        if (!started) { 
         data = ""; 
         started = true; 
        } 
        data += c; 
       } 

      } else { 
       break; 
      } 

     } 

     return data; 

    } 

    public static void main(String[] args) throws IOException { 

     AnalisadorLexico2 al = new AnalisadorLexico2("testAL.txt"); 
     Token t = null; 

     while ((t = al.getNextToken()).token != TokenType.EOF) { 
      System.out.println(t); 
     } 

     System.out.println(al.getNextToken()); 
     System.out.println(al.getNextToken()); 
     System.out.println(al.getNextToken()); 
     System.out.println(al.getNextToken()); 

    } 

} 

:

1234 + 5 * 65 + (44 * 55555) * 444 + (2354 * (34 + 44)) 
1234 + 5 * 65 + (44 * 55555) * 444 + (2354 * (34 + 44)) 
    1234 + 5 * 65 + (44 * 55555) * 444 + (2354 * (34 + 44)) 
1234 + 5 * 65 + (44 * 55555) * 444 + (2354 * (34 + 44))