0

ANTLR を使用して、現在持っている既存の (小さな) パーサーを置き換えています。解析しようとしているファイルのスニペットを次に示します。

Lurker    915236167 10  2 Bk  cc    b     b         1000   70  200 Jc Qs
Lurker    915236237 10  1 Bc  kf    -     -         1130   10    0 
Lurker    915236302 10 10 c   c     rc    b         1120  110  305 6d Kd
Lurker    915236381 10  9 c   f     -     -         1315   20    0 
Lurker    915236425 10  8 cc  f     -     -         1295   30    0 

ここにShared.gがあります:

lexer grammar Shared;


NICK
    : LETTER (LETTER | NUMBER | SPECIAL)*
    ;

fragment
LETTER 
    : 'A'..'Z'
    | 'a'..'z'
    | '_'
    ;

NUMBER
    : ('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')+
    ;

fragment
SPECIAL
    : ('-'|'^'|'{'|'}'|'|'|'['|']'|'`'|'\\')
    ;

WS  
    :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        )+
    ;

そして Pdb.g:

grammar Pdb;
import Shared;

@header{
import java.util.ArrayList;
import java.sql.Connection;
}


@members{
    private Connection conn;

    private StringBuilder currentExpr = new StringBuilder(500);

    ArrayList<String> players = new ArrayList<String>(10);

    public void setConn(Connection conn){
        this.conn = conn;
    }
}

pdb
    : line+
    ;

line
    @after{
        currentExpr.append("execute player_handplan(");
        currentExpr.append($nick.text);
        currentExpr.append(", to_timestamp(");
        currentExpr.append(Integer.parseInt($timestamp.text));
        currentExpr.append("), ");
        currentExpr.append(Integer.parseInt($n_players.text));
        currentExpr.append(", ");
        currentExpr.append(Integer.parseInt($position.text));
        currentExpr.append(", ");
        currentExpr.append($action_p.text);
        currentExpr.append(", ");
        currentExpr.append($action_f.text);
        currentExpr.append(", ");
        currentExpr.append($action_t.text);
        currentExpr.append(", ");
        currentExpr.append($action_r.text);
        currentExpr.append(", ");
        currentExpr.append(Integer.parseInt($bankroll.text));
        currentExpr.append(", ");
        currentExpr.append(Integer.parseInt($total_action.text));
        currentExpr.append(", ");
        currentExpr.append(Integer.parseInt($amount_won.text));
        currentExpr.append(", ");
        currentExpr.append("CARDS");
        currentExpr.append(");");
        System.out.println(currentExpr.toString());
        currentExpr = new StringBuilder(500);
    }
    : nick=NICK WS
      timestamp=NUMBER WS
      n_players=NUMBER WS
      position=NUMBER WS 
      action_p=action WS
      action_f=action WS
      action_t=action WS
      action_r=action WS
      bankroll=NUMBER WS
      total_action=NUMBER WS
      amount_won=NUMBER WS
      (NICK WS NICK WS)? // ignore this
     ;

action
    : '-'
    | ('B'|'f'|'k'|'b'|'c'|'r'|'A'|'Q'|'K')+
    ;

私の問題は、パーサーを実行すると、次のエラーが発生することです。

cal@lambda:~/src/DecisionTrees/grammar/output$ cat example | java Test 
line 1:26 no viable alternative at input 'Bk'
line 1:30 no viable alternative at input 'cc'
execute player_handplan(Lurker, to_timestamp(915236167), 10, 2, null, null, b, b, 1000, 70, 200, CARDS);

私の文法は「b」を受け入れますが、なぜ「Bk」を受け入れないのですか? 私が見落としている明らかな何かがあるように感じます。前もって感謝します

4

1 に答える 1

1

ルール WS で使用{$channel=HIDDEN}して、ライン ルールから外してみてはいかがでしょうか。

そうすれば、少なくともWS、誤って 1 つ入れすぎて困ることはありません。

そして、アクションが最大2文字しか持てない場合は、おそらくこれを試してみると役立ちます:

action
    : '-'
    | ('B'|'f'|'k'|'b'|'c'|'r'|'A'|'Q'|'K')('B'|'f'|'k'|'b'|'c'|'r'|'A'|'Q'|'K')?
    ;
于 2011-01-09T09:33:39.237 に答える