75 lines
1.5 KiB
Plaintext
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; }
|