为什么ANTLR不会像我期望的那样认识到这条规则?

时间:2010-11-10 22:27:30

标签: java parsing antlr antlr3

我正在使用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);

为什么我的语法不会接受“Bk”,即使它会接受“b”?我觉得我有一些明显的东西可以忽略。提前致谢

1 个答案:

答案 0 :(得分:1)

为什么不在规则WS中使用{$channel=HIDDEN}并将它们排除在行规则之外。

这样至少你不会因为意外放置太多WS而遇到麻烦。

如果动作最多只能有2个字符,那么尝试这会有所帮助:

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