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文で関数名による処理を分岐するのかな?