UNPKG

mutants-appfx

Version:

appfx module

82 lines (73 loc) 1.95 kB
import antlr4 from 'antlr4'; import { ErrorListener } from 'antlr4/error/ErrorListener'; import { ExprLexer } from './ExprLexer'; import { ExprParser } from './ExprParser'; import ExprExecutor from './ExprExecutor'; const log = console.log; const cache = new Map(); class ExprErrorListener extends ErrorListener { error; reset() { this.error = false; } syntaxError(recognizer, offendingSymbol, line, column, msg) { // if (typeof __DEV__ !== 'undefined' && __DEV__) { // log("line " + line + ":" + column + " " + msg); // } this.error = true; } } const errorHandler = new ExprErrorListener(); export default class Expression { str; constructor(str) { this.str = str; if (typeof str === 'string' && !!str) { // constString 暂时词法冲突 const txt = str.trim(); if (txt.startsWith('=')){ this.str = txt.substr(1); return; } if (cache.has(str)) { this.tree = cache.get(str); } else { errorHandler.reset(); const chars = new antlr4.InputStream(str); const lexer = new ExprLexer(chars); lexer.removeErrorListeners(); lexer.addErrorListener(errorHandler); const tokens = new antlr4.CommonTokenStream(lexer); const parser = new ExprParser(tokens); // parser._errHandler = new ExceptionErrorStrategy(); parser.removeErrorListeners(); parser.addErrorListener(errorHandler); parser.buildParseTrees = true; let tree = parser.exec(); if (errorHandler.error) { tree = null; } this.tree = tree; cache.set(str, tree); } } } toString() { return this.str; } exec(scope) { if (this.tree) { const executor = new ExprExecutor(scope); antlr4.tree.ParseTreeWalker.DEFAULT.walk(executor, this.tree); return executor.result; } else { return this.str; } } }