LemonJS/examples/calculator-js.y

75 lines
1.5 KiB
Plaintext

%name Parser
%token_prefix TOKEN_
%left PLUS MINUS.
%left DIVIDE TIMES.
%include {
// include something
}
%code {
var Lexer = require('../lexer/lexer');
var parser = new Parser();
parser.setTraceCallback(function (value) {
process.stdout.write(value);
}, '> ');
var lexer = new Lexer();
lexer.addRule(/\d+/, function (value) {
return { major: parser.TOKEN_INTEGER, minor: parseInt(value, 10) };
});
lexer.addRule('+', function (value) {
return { major: parser.TOKEN_PLUS, minor: null };
});
lexer.addRule('-', function (value) {
return { major: parser.TOKEN_MINUS, minor: null };
});
lexer.addRule('/', function (value) {
return { major: parser.TOKEN_DIVIDE, minor: null };
});
lexer.addRule('*', function (value) {
return { major: parser.TOKEN_TIMES, minor: null };
});
lexer.addRule(/\s+/, function () {});
var data = '';
process.stdin.on('data', function (chunk) {
data += chunk;
});
process.stdin.on('end', function () {
var token;
lexer.setInput(data);
while (token = lexer.lex()) {
parser.parse(token.major, token.minor);
}
parser.parse();
});
}
%syntax_error {
console.log("Syntax error");
}
program ::= expr(A). { console.log("Result=" + A); }
expr(A) ::= expr(B) MINUS expr(C). { A = B - C; }
expr(A) ::= expr(B) PLUS expr(C). { A = B + C; }
expr(A) ::= expr(B) TIMES expr(C). { A = B * C; }
expr(A) ::= expr(B) DIVIDE expr(C). {
if (C != 0) {
A = B / C;
} else {
throw new Error("Divide by zero");
}
}
expr(A) ::= INTEGER(B). { A = B; }