LL(1) 構文解釈できた
とりあえず解釈できた。やはり (setq change nil) が抜けていたのと iconst が抜けていたというバグがあった。それ以外は問題なし。ついでなので簡単なリードマクロを作った。リードマクロを使うと
(setq *rules* '#%END program ::= statlist statlist ::= stat statlist statlist ::= stat ::= ident = expr ; stat ::= read ident ; stat ::= print expr ; stat ::= if ( cond ) stat stat ::= { statlist } cond ::= expr relop expr relop ::= < relop ::= > expr ::= ident expr ::= iconst END )
とかける。だだし | はない。本格的に bnf を書こうと思うと bnf を解釈する bnf が必要だ。なんだかわからない。リードマクロの主要部分だけのせておこう。
(if (char= #\newline curr) (let* ((oneline-str (string-concat "(" (coerce (nreverse oneline-char) 'string) ")")) (ln (mapcan (lambda (x) (cond ((eq x '::=) nil) ((symbolp x) (list x)) ((char= x #\;) (list 'semi)) ((char= x #\() (list 'lpar)) ((char= x #\)) (list 'rpar)) (t (error "parse error")))) (read-from-string oneline-str)))) ;(format t "~a~%" oneline-str) (setf oneline-char nil) (if (not (null ln)) (setf output (cons ln output)))) (progn (if (or (eq #\( curr) (eq #\) curr) (eq #\; curr)) (progn (push #\# oneline-char) (push #\\ oneline-char))) (push curr oneline-char)))
リードマクロを作るマクロが欲しくなってきた。