2017-05-07 99 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'跟踪解析器的位置:解析注释或字符串或任何其他标记 –

相关问题