decimal-eval
Version:
A tiny, safe, fast JavaScript library for decimal arithmetic expressions.
261 lines (243 loc) • 6.95 kB
TypeScript
declare type BinaryCalcMethod = (left: string, right: string) => string;
/**
* 创建一个二元运算符
* @param value
* @param precedence
* @param calc
* @see 运算符优先级参考: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
*/
declare function createBinaryOperator(value: string, precedence: number, calc: BinaryCalcMethod): Operator;
/**
* 创建一个一元运算符
* @param value
* @param precedence
* @param calc
* * @see 运算符优先级参考: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
*/
declare function createUnaryOperator(value: string, precedence: number, calc: UnaryCalcMethod): Operator;
declare const DecimalEval: {
evaluate: typeof Parser.evaluate;
Parser: typeof Parser;
Operator: typeof Operator;
version: string;
};
export default DecimalEval;
export declare const evaluate: typeof Parser.evaluate;
/**
* 二元表达式计算方法适配器
*/
declare interface IAdapter {
'+': (left: string, right: string) => string;
'-': (left: string, right: string) => string;
'*': (left: string, right: string) => string;
'/': (left: string, right: string) => string;
}
declare interface ITokenTypeOptions {
readonly isBinary?: boolean;
readonly isPrefix?: boolean;
readonly precedence?: number;
}
/**
* AST 节点
*/
declare class Node {
type: NodeType;
start: number;
end: number;
[key: string]: any;
constructor(start: number);
}
declare type NodeType = '' | 'Expression' | 'BinaryExpression' | 'UnaryExpression' | 'NumericLiteral' | 'Identifier';
/**
* 运算符
*/
export declare class Operator<M extends OperatorMethod = BinaryCalcMethod> {
readonly value: string;
readonly codes: number[];
readonly type: TokenType;
readonly calc: M;
constructor(value: string, precedence: number, calc: M, isUnary?: boolean);
}
declare type OperatorMethod = BinaryCalcMethod | UnaryCalcMethod;
/**
* AST Parser
*/
export declare class Parser {
readonly input: string;
node: Node | null | undefined;
pos: number;
tokenType: TokenType;
value: string;
start: number;
end: number;
lastTokenStart: number;
lastTokenEnd: number;
allowPrefix: boolean;
static createBinaryOperator: typeof createBinaryOperator;
static createUnaryOperator: typeof createUnaryOperator;
static useOperator: typeof useOperator;
static useAdapter: typeof useAdapter;
static evaluate(expression: string, scope?: Record<string, number>): string;
static readonly Node: typeof Node;
static readonly TokenType: typeof TokenType;
static readonly tokenTypes: {
start: TokenType;
end: TokenType;
parenL: TokenType;
parenR: TokenType;
numeric: TokenType;
identifier: TokenType;
plus: TokenType;
minus: TokenType;
times: TokenType;
div: TokenType;
prefixPlus: TokenType;
prefixMinus: TokenType;
};
static readonly installedOperators: Operator[];
/**
* 解析的字符串
* @param input
*/
constructor(input: string);
/**
* 编译表达式
*/
compile(): (scope?: Record<string, number>) => string;
/**
* 开始解析,如果是空字符串返回 `null`
*/
parse(): Node | null;
/**
* 解析表达式
*/
parseExpression(): Node;
/**
* 解析一个表达式原子, 如: `1 + 2`、`(1 + 2 + 3)`、`1` 都作为一个表达式原子解析
* @param leftStartPos 左侧开始位置
* @param minPrecedence 当前上下文的优先级
*/
parseExprAtom(leftStartPos: number, minPrecedence: number): Node;
/**
* 解析二元表达式优先级
* @param left 左值
* @param leftStartPos 左值节点起始位置
* @param minPrecedence 当前上下文的优先级
*/
parseExprOp(left: Node, leftStartPos: number, minPrecedence: number): Node;
/**
* 解析可能带前缀的表达式,如: `+1`, `-(2)`, `3`, `-(3 + 4)`, `+-+5`
* @param minPrecedence 当前上下文的优先级
*/
parseMaybeUnary(minPrecedence: number): Node;
/**
* 读取并移到下一个 Token
*/
next(): void;
/**
* 读取一个 token
*/
readToken(): void;
/**
* 读取一个数字
*/
readNumeric(): void;
/**
* 根据字符 code 读取一个 Token,包括自定义注册的运算符
*/
readTokenFromCode(): void;
/**
* 读取一个 scope 变量 Token
*/
readIdentifier(): void;
/**
* 完善一个 Token
* @param type
* @param value
*/
finishToken(type: TokenType, value?: string): void;
/**
* 读取 Token 完成后更新上下文
* @param prevType
*/
updateContext(prevType: TokenType): void;
codeAt(index: number): number;
isValidPosition(): boolean;
/**
* 在当前位置创建一个新节点
*/
startNode(pos?: number): Node;
/**
* 完善一个节点
* @param node
* @param type
*/
finishNode(node: Node, type: NodeType): Node;
/**
* 跳过空白字符
*/
skipSpace(): void;
/**
* 消费当前指定类型的 token,否则抛出异常
* @param type
*/
expect(type: TokenType): void;
/**
* 消费一个 token,如果是指定的 token 类型,则移动到下一个 token ,返回 true,否则返回 false
* @param type
*/
eat(type: TokenType): boolean;
/**
* 抛出 Unexpected token 异常
* @param token
* @param pos
*/
unexpected(token?: string, pos?: number): never;
/**
* 抛出异常
* @param pos
* @param message
*/
raise(pos: number, message: string): never;
}
declare class TokenType {
/**
* Token label
*/
readonly label: string;
/**
* 是否为二元运算符
*/
readonly isBinary: boolean;
/**
* 是否可以作为前缀(一元运算符,仅支持运算符在左侧)
*/
readonly isPrefix: boolean;
/**
* 运算符优先级
* @see https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
*/
readonly precedence: number;
/**
* 读取 Token 时更新上下文
*/
updateContext?: (this: Parser, prevType: TokenType) => void;
/**
* constructor
* @param label
* @param options
*/
constructor(label: string, options?: ITokenTypeOptions);
}
declare type UnaryCalcMethod = (value: string) => string;
/**
* 使用指定的计算方法适配器用于计算值
* @param adapter
*/
declare function useAdapter(adapter: IAdapter): void;
/**
* 注册自定义运算符
* @param operator
*/
declare function useOperator(operator: Operator): void;
export { }