S式PEGパーサつづき

構文解析してAbstract Syntax Treeを構築するところまでは昨日までで大体できてた。そこからPEGライブラリを使ってパーサを構築するコードを書きつつも、構文を解析しやすいように細かい変更を重ねる。あーでも、構文は結局最初のでもよかったんじゃまいかと思ったり。仕様変更は仕様です。

(parse-grammars
 '((add <- < mult lval > #\+ < add rval > :return `(+ ,lval ,rval)
	/ < mult val > :return val)
   (mult <- < prim lval > #\* < mult rval > :return `(* ,lval ,rval)
	 / < prim val > :return val)
   (prim <- #\( < add val > #\) :return val / < decim val > :return val)
   (decim <- < digit nch > :return (- (char->integer nch) (char->integer #\0)))
   (digit <- #[0-9])))

=>

((:definition (:identifier add)
  (:expression
   (:sequence ((:identifier-clause (:identifier mult) :capture lval)
	       (:char #\+)
	       (:identifier-clause (:identifier add) :capture rval))
	      :callback `(+ ,lval ,rval))
   (:sequence ((:identifier-clause (:identifier mult) :capture val))
	      :callback val)))
 (:definition (:identifier mult)
  (:expression
   (:sequence ((:identifier-clause (:identifier prim) :capture lval)
	       (:char #\*)
	       (:identifier-clause (:identifier mult) :capture rval))
	      :callback `(* ,lval ,rval))
   (:sequence ((:identifier-clause (:identifier prim) :capture val))
	      :callback val)))
 (:definition (:identifier prim)
  (:expression
   (:sequence ((:char #\()
	       (:identifier-clause (:identifier add) :capture val)
	       (:char #\)))
	      :callback val)
   (:sequence ((:identifier-clause (:identifier decim) :capture val))
	      :callback val)))
 (:definition (:identifier decim)
  (:sequence ((:identifier-clause (:identifier digit) :capture nch))
	     :callback (- (char->integer nch) (char->integer #\0))))
 (:definition (:identifier digit)
  (:sequence ((:char-set #[0-9]))
	     :callback ())))