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」になるまで受理されない…… なぜだろう。