2012-08-09 33 views
5

私は、誤って別のトークンにマッチさせることなく、JavaCCを使用して文字列を解析する良い方法を考えようとしています。これらの文字列には、スペース、文字、および数字を含めることができます。次のようにJavaCCで文字列を解析する

マイ識別子と数トークンは次のとおりです。

<IDENTIFIER: (["a"-"z", "A"-"Z"])+> 
<NUMBER: (["0"-"9"])+> 

私の現在の文字列トークンは次のとおりです。理想的には

<STRING: "\"" (<IDENTIFIER> | <NUMBERS> | " ")+ "\""> 

、私は引用符の中だものを保存したいです。私は変数と値の実際の保存を行う別のファイルを持っています。私はそこに引用符を削除する必要がありますか?ご想像の通り、これはそのことについては、スペース、または数字を許可しませんでした、

variable=<INDENTIFIER> <ASSIGN> <QUOTE> message=<IDENTIFIER> <QUOTE> 
{File.saveVariable(variable.image, message.image);} 

しかし:

は、私はもともとこのような構文解析器ファイルのメソッドを持っていました。変数名などの識別子については、私は文字を許可したいだけです。

文字列リテラルをキャプチャする方法についてアドバイスを受けたいと思います。特に、私は以下のような文字列を作りたいと思っています:

" hello", "hello ", " hello " and "\nhello", "hello\n", "\nhello\n" 

私の構文で有効です。

+0

あなたはDerMikeの答えを受け入れるべきです - それはかなり完璧なようです。 –

答えて

10

最初に"を渡すと、パーサーはSTRING状態になり、次のままにします(ボーナス:引用符なし)"

同様:

TOKEN: 
{ 
    <QUOTE:"\""> : STRING_STATE 
} 

<STRING_STATE> MORE: 
{ 
    "\\" : ESC_STATE 
} 

<STRING_STATE> TOKEN: 
{ 
    <ENDQUOTE:<QUOTE>> : DEFAULT 
| <CHAR:~["\"","\\"]> 
} 

<ESC_STATE> TOKEN: 
{ 
    <CNTRL_ESC:["\"","\\","/","b","f","n","r","t"]> : STRING_STATE 
} 

あなたはこのように使用することができます。

/** 
* Match a quoted string. 
*/ 
String string() : 
{ 
    StringBuilder builder = new StringBuilder(); 
} 
{ 
    <QUOTE> (getChar(builder))* <ENDQUOTE> 
    { 
    return builder.toString(); 
    } 
} 

/** 
* Match char inside quoted string. 
*/ 
void getChar(StringBuilder builder): 
{ 
    Token t; 
} 
{ 
    (t = <CHAR> | t = <CNTRL_ESC>) 
    { 
    if (t.image.length() < 2) 
    { 
     // CHAR 
     builder.append(t.image.charAt(0)); 
    } 
    else if (t.image.length() < 6) 
    { 
     // ESC 
     char c = t.image.charAt(1); 
     switch (c) 
     { 
     case 'b': builder.append((char) 8); break; 
     case 'f': builder.append((char) 12); break; 
     case 'n': builder.append((char) 10); break; 
     case 'r': builder.append((char) 13); break; 
     case 't': builder.append((char) 9); break; 
     default: builder.append(c); 
     } 
    } 
    } 
} 

HTH。