2017-05-07 112 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 

我想知道最有效的方式獲得此。請注意,我仍然需要驗證字符串文字和註釋的發生。 (例如檢查它是否正確封閉)。到目前爲止,我的方法是用whitespaces分割每一行,並且當一個詞位包含「$」或「*」時,我將驗證字符串文字。這裏是我的實施:

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

但我們不允許使用輔助庫。 –

回答

1

我認爲你的語言是確定性和上下文無關的? 這意味着,您無法使用正則表達式正確解析它。

你需要的是一個工作在令牌流中的狀態機。 Java附帶了兩個可能適用於您的類: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

順便說一下,我們不允許在這個項目中使用輔助庫,因此我不能使用其他解析器生成器。 –

+0

編輯以概述如何在解析時跟蹤狀態。'enum State'跟蹤解析器的位置:解析註釋或字符串或任何其他標記 –

相關問題