print文専用の構文解析ではなく、汎用的な関数呼び出しの構文解析にする
関数呼び出しのfunccallを作り、どれにも該当しない場合、そのままの値を返す
### parser.js
module.exports = parser; var {expect, accept, show, error} = require("./utils.js"); var tokens; function parser(t){ tokens = t; var ast = semi(); if(tokens.length>0){ show("ast=", ast); show("処理後tokens =", tokens); error("tokensが余っています。"); } return ast; } function value(){ if(tokens.length == 0) return; return tokens.shift(); } function funccall(){ var left = value(); var op; while(op = accept(tokens, "(")){ var right = semi(); op += expect(tokens, ")"); left = {left, op, right}; } return left; } function semi(){ var left = funccall(); var op; while(op = accept(tokens, ";")){ var right = funccall(); left = {left, op, right}; } return left; }
関数valueで、tokens.shift();で値を取ってleftに入れて、()をop、中をrightにして、セミコロンがあった場合は全体をleft、opをセミコロン、セミコロン後をrightにしている。
これは、この言語が必ず 関数名、()、; の順番で書かれていることを前提に立っている。
言語設計者側に立つと、命名規則ってのはちゃんと意味があるんだなぁ
function valueのtokens.shiftのところで、case文で関数名による処理を分岐するのかな?