ANTLRの練習としてS式パーサをつくってみる

試行錯誤した結果grammerはこんなふうになった。

options {
    language  = "CSharp";
    namespace = "Parser";          // encapsulate code in this namespace
}

class SExprParser extends Parser;
options {
  k = 2;
}
sexpr
  :  atom
  |  list
  |  QUOTE sexpr
  ;
list
  :  OPAREN
       sexpr
       (serialSexpr)*
       (WS DOT sexpr)?
       (WS)?
     CPAREN
   ;
serialSexpr
  : (WS sexpr);
atom
  :  INT
  |  SYMBOL
  ;

class SExprLexer extends Lexer;
options {
  k = 1;
}

WS: (' ' | '\t' | '\n' | "\r\n")+;
OPAREN: '(' (WS)?;
CPAREN: ')';
DQUOTE: '"';
QUOTE: '\'';
DOT: '.' WS;
INT: ('0'..'9')+;
SYMBOL: SYMBOLALPHA (SYMBOLALPHA | '0'..'9')*;
LINECOMMENT: ';' (~('\n' | '\r'))* ('\n' | "\r\n");
protected
SYMBOLALPHA: 'a'..'z' | 'A'..'Z'| '+' | '-' | '?' | '!' | '/' | '*';
while(true) {
  SExprParser p = new SExprParser(new SExprLexer(Console.OpenStandardInput()));
  try { p.sexpr();}
  catch {Console.WriteLine("err!");}
} 

でテスト。なんか挙動がおかしい…… 「(1 2 3 (4 5 6) )」は受理するけど「(1 2 3 (4 5 6))」は途中で引っかかったまま。「(1 2 3 (4 5 6))\n\n」になるまで受理されない…… なぜだろう。