BNF記法の事例として書いたプログラムである。
本来の四則演算の構文規則(BNF記法)は
<addsub> ::= <addsub> + <muldiv> | <addsub> - <muldiv> | <muldiv> <muldiv> ::= <muldiv> * <factor> | <muldiv> / <factor> | <factor> <factor> ::= 数値 | ( <addsub> )であるが、これでは再帰プログラムが書けないので、次のように書き換える。
<addsub> ::= <muldiv> { + <muldiv> | - <muldiv> } <muldiv> ::= <factor> { * <factor> | / <factor> } <factor> ::= 数値 | ( <addsub> )
プログラム・ソースを以下に示す。
calc01.jsvar input = ""; var items = new Array(); var nItem = 0; var ix = 0; var num = ""; function push(c) { if (c == 'C') { input = ""; items = new Array(); nItem = 0; ix = 0; num = ""; } else if (c.match(/\d|\./)) { num += c; input += c; } else if (c == '=') { if (num.length > 0) { items[nItem++] = num; num = ""; } input += "=" + calc(items); } else if (c != '') { if (num.length > 0) { items[nItem++] = num; num = ""; } items[nItem++] = c; input += c; } document.getElementById('in').value = input; } function array(id) { var labels = [ ["0", "1", "2", "+", "("], ["3", "4", "5", "-", ")"], ["6", "7", "8", "*", ""], ["9", ".", "C", "/", "="] ]; var buttons = "<table border='0'>"; for (var i = 0; i < labels.length; i++) { buttons += "<tr>"; for (var j = 0; j < labels[i].length; j++) { buttons += "<td><input type='button' value='" + labels[i][j] + "' onclick=push('" + labels[i][j] + "')></td>"; } buttons += "</tr>"; } buttons += "</table>"; document.getElementById(id).innerHTML = buttons; input = ""; } function calc(){ return addsub(); } function addsub(){ var val = muldiv(); while (ix < items.length && items[ix].match(/[\+-]/)) { val = ("+" == items[ix++]) ? (val + muldiv()) : (val - muldiv()); } return val; } function muldiv(){ var val = factor(); while (ix < items.length && items[ix].match(/[\*/]/)) { var op = items[ix++]; val = ("*" == op) ? (val * factor()) : (val / factor()); } return val; } function factor(){ var val; if ("(" == items[ix]){ ix++; val = addsub(); if (")" != (items[ix])) alert(")がありません!"); ix++; // ポインタを ) の次へ進める } else { val = parseFloat(items[ix++]); } return val; }