2017-05-07 1 views
0

나는 컴파일러를 구축 중입니다. 이 중 일부 사양은 다음과 같습니다.사용자 지정 정규식을 사용하여 문자열 분할 Java

  • 문자열 리터럴은 달러 기호 ("$")로 묶습니다. 예 : $ string sample $
  • 주석은 "*"로 묶습니다. 예. * 샘플 의견 *
  • 설명은 작업 간에는 예외가 될 수 있습니다 - 예 : 4 + * 샘플 주석 * 5 - (허용되지 않음)

이제 토큰 화하기 위해 소스 코드 줄을 분할해야합니다. 예 케이스 : 나는 그것을 토큰 화하는 것으로

PRINT $ THE FLOAT IS $ * DISPLAY THE RESULT * 

, 그것은 생산해야한다는 :

PRINT - token is KEYWORD 
THE FLOAT IS - token is STRING_LITERAL 
DISPLAY THE RESULT - token is COMMENT 

난이 얻을 수있는 가장 효율적인 방법을 알고 싶습니다. 문자열 리터럴 및 주석의 발생을 여전히 검증해야합니다. (예 : 제대로 묶여 있는지 확인하십시오). 지금까지는 각 행을 공백으로 나눠서 어휘에 "$"또는 "*"가 포함되어 있으면 문자열 리터럴을 검증 할 것입니다. 다음은 구현 한 것입니다.

private void getLexemes(){ 
    for(String line : newSourceCode){ 
     String[] lexemesInALine = line.trim().split("[\\s]+"); 
     for(String lexemeInALine : lexemesInALine){ 
      if(!(lexemeInALine.contains("$"))){ 
       lexemes.add(lexemeInALine); 
       tempTokens.add(findToken(lexemeInALine)); 
       line = line.replaceFirst(lexemeInALine,"").trim(); 
      }else{ 
       validateStringType(line); 
       break; 
      } 
     } 

감사합니다.

+0

손으로 렉싱하는 데 관심이 있으십니까? 더 높은 수준의 파트에 집중할 수있는 여러 가지 렉서/파서 생성기가 있습니다. – 9000

+0

예. 알았어. 나는 손으로 렉싱에 관심이있다. –

+0

하지만 2 차 라이브러리는 사용할 수 없습니다. –

답변

1

당신의 언어는 결정 론적이며 컨텍스트 프리인가요? 즉, 정규식을 사용하여 올바르게 구문 분석 할 수 없습니다.

필요한 것은 토큰 스트림에서 작동하는 상태 시스템입니다. 자바에는 StreamTokenizerStringTokenizer의 두 가지 클래스가 있습니다.

하지만 실제로 원하는 것은 수십 개의 파서 생성기 중 하나를 사용하는 것입니다. 어쩌면 ANTLR과 같은 것일 수도 있습니다. 많은 여기가 설명되어 있습니다

https://en.wikipedia.org/wiki/Comparison_of_parser_generators

모든 일이 실패하면, 유한 상태 기계가있다. 그 라인에있는 무엇인가

public class Parsy { 
    enum State { string, comment, token } 
    void parse(StringTokenizer tokenizer) { 
     State state = State.token; 

     List<String> tokens = new ArrayList<>(); 
     while (tokenizer.hasMoreTokens()) { 
      String token = tokenizer.nextToken(); 
      // figure out type of token 
      if (token.length() == 1) { 
       char delim = token.charAt(0); 
       switch (delim) { 
        case '$': 
         switch (state) { 
          case token: { 
           // a string literal has started, emit what we have, start a string 
           printOut(tokens, state); 
           tokens.clear(); 
           tokens.add(token); 
           state = State.string; 
           break; 
          } 
          case string: { // parsing a string, so this ends it 
           printOut(tokens, state); 
           tokens.clear(); 
           state = State.token; 
           break; 
          } 
          case comment: { // $ is ignored since we are in a comment 
           tokens.add(token); 
           break; 
          } 
         } 
         break; 
        // ... 
       } 
      } else { 
       // not a delimiter token 
       tokens.add(token); 
      } 

     } // end of while 
    if (state != State.token) { 
     System.out.println("Oops! Syntax error. I'm still parsing" + state); 
    } 
    } 
} 
+0

결정적이지는 않습니다. 그렇습니다. 문맥이 없으므로 RE를 사용할 수 없습니다. 나는 여전히 'StreamTokenizer'와 'StringTokenizer'를 읽어야한다. 링크를 이용해 주셔서 감사합니다. –

+0

그건 그렇고, 우리는이 프로젝트에서 2 차 라이브러리를 사용할 수 없으므로 다른 파서 생성기를 사용할 수 없습니다. –

+0

구문 분석하는 동안 상태를 추적하는 방법에 대한 개요를 편집하십시오.'enum State'는 파서의 위치를 ​​추적합니다 : 주석이나 문자열 또는 다른 토큰을 구문 분석합니다. –

관련 문제