1

Antlr greedy-optionで説明したように、文字列リテラル内に文字列リテラルを含めることができる言語には、次のような問題があります。

開始: "img src="test.jpg""

Bart Kiers 氏は私のスレッドで、私の問題を解決できる文法を作成することはできないと述べました。したがって、言語を次のように変更することにしました。

開始: "img src='test.jpg'"

レクサー(およびパーサー)を開始する前に。

ファイル入力は次のようになります。

START: 「あああ」
 「あああああああ」
:END_START

START: 「あああ」
 「あああ」
 a
 あぁ」
:END_START

START: 「あああああ」
:END_START

だから私は解決策を持っていますが、それは正しくありません。私の問題(コードの下)に関して2つの質問があります。私のコードは次のようになります。

public static void main(String[] args) {

    try{
        FileInputStream fis = new FileInputStream("src/file.txt");
        String preparedCode = preparingCode(fis);

        ANTLRStringStream in = new ANTLRStringStream(preparedCode);

        TestLexer lex = new TestLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lex);
        TestParser parser = new TestParser(tokens);

        parser.rule();
    }catch(IOException ex){
        ex.printStackTrace();
    } catch (RecognitionException e) {
        System.out.println(e.getMessage());
        System.exit(0);
    }
}

static String preparingCode(FileInputStream input){
    DataInputStream data = new DataInputStream(input);
    StringBuilder oldCode = new StringBuilder();
    StringBuffer newCode = new StringBuffer(oldCode.length());

    Pattern pattern = Pattern.compile("(START:\\s\")(.+)(\"\\n:END_START)");
    String strLine;
    try{
      while ((strLine = data.readLine()) != null)   
          oldCode.append(strLine + "\n");
    }
    catch(IOException ex){
      ex.printStackTrace();
    }

    Matcher matcher = pattern.matcher(oldCode);

    while (matcher.find()) {
      //eliminate quotes inside a string literal
      String stringLiteral = matcher.group(2).replaceAll("\"", "'");

      String replace = matcher.group(1) + stringLiteral + matcher.group(3);
      matcher.appendReplacement(newCode, Matcher.quoteReplacement(replace));
    }
    matcher.appendTail(newCode);

    System.out.println(newCode);

    return newCode.toString();
}


私の質問は次のとおりです。

  • どのパターンが正しいでしょうか?文字列リテラルは、"aaaa"\n"bbb" のように複数の行にわたって定義できることが重要ですが、常に"\n:END_START" 行で終了します。私の願いは次の結果になります:
開始: 「ああああああ」
 「あああああああ」
:END_START

開始: 「ああああああ」
 ああああ
 a
 あぁ」
:END_START

START: 「あああああああああ」
:END_START

パターンフラグPattern.DOTALLで遊んでみた

Pattern pattern = Pattern.compile("(START:\s\")(.+)(\"\n:END_START)", Pattern.DOTALL);
しかし、これは解決策ではありません。この場合、すべてに一致するためです...




-正しいパターンを使用する場合、他の効率的な修正方法はありますか?




パターン フラグ Pattern.DOTALL を使用して貪欲でないアプローチを使用する必要がある最初の質問を修正します。

Pattern pattern = Pattern.compile("(START:\\s\")(.+?)(\"\\n:END_START)", Pattern.DOTALL);
4

1 に答える 1

0


パターン フラグ Pattern.DOTALL を使用して貪欲でないアプローチを使用する必要がある最初の質問を修正します。

Pattern pattern = Pattern.compile("(START:\\s\")(.+?)(\"\\n:END_START)", Pattern.DOTALL);

コード:

 public static void main(String[] args) {

    try{
        FileInputStream fis = new FileInputStream("src/file.txt");
        String preparedCode = preparingCode(fis);

        ANTLRStringStream in = new ANTLRStringStream(preparedCode);

        TestLexer lex = new TestLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lex);
        TestParser parser = new TestParser(tokens);

        parser.rule();
    }catch(IOException ex){
        ex.printStackTrace();
    } catch (RecognitionException e) {
        System.out.println(e.getMessage());
        System.exit(0);
    }
}

static String preparingCode(FileInputStream input){
    DataInputStream data = new DataInputStream(input);
    StringBuilder oldCode = new StringBuilder();
    StringBuffer newCode = new StringBuffer(oldCode.length());

    Pattern pattern = Pattern.compile("(START:\\s\")(.+?)(\"\\n:END_START)", Pattern.DOTALL);
    String strLine;
    try{
      while ((strLine = data.readLine()) != null)   
          oldCode.append(strLine + "\n");
    }
    catch(IOException ex){
      ex.printStackTrace();
    }

    Matcher matcher = pattern.matcher(oldCode);

    while (matcher.find()) {
        System.out.println("++++"+matcher.group(2));
      //eliminate quotes inside a string literal
      String stringLiteral = matcher.group(2).replaceAll("\"", "'");

      String replace = matcher.group(1) + stringLiteral + matcher.group(3);
      matcher.appendReplacement(newCode, Matcher.quoteReplacement(replace));
    }
    matcher.appendTail(newCode);

    System.out.println(newCode);

    return newCode.toString();
}

この問題を解決する他の方法はありますか?

于 2012-04-05T13:20:58.250 に答える