0

これらのルールでトークンを取得すると

STRINGA :   '"' (options {greedy=false;}: ESC | .)* '"';
STRINGB :   '\'' (options {greedy=false;}: ESC | .)* '\'';

'text'ただの代わりにつかむことになりtextます。私は簡単に''自分自身を削除することができますが、ANTLRにそれを削除させる方法を考えていましたか?

4

2 に答える 2

1

1つのアプローチは、文字列の内容を別のカテゴリとして定義することです。たとえば、

STRINGA : '"' STRINGCONTENTS '"';
STRINGB : '\'' STRINGCONTENTS '\'';

次に、STRINGCONTENTS値をキャプチャします。

于 2012-07-10T03:32:06.607 に答える
1

そのためのカスタムコードが必要になります。また、ルール内で(ドット)を使用しないでください。バックスラッシュ(最初はそれであると想定)、引用符改行文字を除く.すべてに一致させることを明示的に定義する必要があります。ESQ

このような何かがそれをするでしょう:

grammar T;

parse
 : STRING EOF {System.out.println($STRING.text);}
 ;

STRING
 : '"' (ESQ | ~('"' | '\\' | '\r' | '\n'))* '"'
   {
     String matched = getText();
     StringBuilder builder = new StringBuilder();

     for(int i = 1; i < matched.length() - 1; i++) {
       char ch = matched.charAt(i);
       if(ch == '\\') {
         i++;
         ch = matched.charAt(i);
         switch(ch) {
           case 'n': builder.append('\n'); break;
           case 't': builder.append('\t'); break;
           default: builder.append(ch); break;
         }
       }
       else {
         builder.append(ch);
       }
     }

     setText(builder.toString());
   }
 ;

fragment ESQ
 : '\\' ('n' | 't' | '"' | '\\')
 ;

ここで入力を解析する"tabs:'\t\t\t'\nquote:\"\nbackslash:\\"と、以下がコンソールに出力されます。

タブ:''
引用:"
バックスラッシュ:\

文法をきれいに保つために、もちろんカスタムメソッドでコードを移動することもできます。

grammar T;

@lexer::members {
  private String fix(String str) {
    ...
  }
}

parse
 : STRING EOF {System.out.println($STRING.text);}
 ;

STRING
 : '"' (ESQ | ~('"' | '\\' | '\r' | '\n'))* '"' {setText(fix(getText()));}
 ;

fragment ESQ
 : '\\' ('n' | 't' | '"' | '\\')
 ;
于 2012-07-10T06:47:26.293 に答える