UNPKG

consys

Version:

consys is a flexible tool to evaluate models using generic and readable constraints.

270 lines (269 loc) 8.11 kB
import Token from './Token'; import { Expression } from './Expression'; /** * This class transforms a given list of tokens into an abstract syntax tree mirroring the dsl grammar. * Syntax definition for constraints: * * constraint -> activation ( ":" | "THEN" ) assertion ; * activation -> "ALWAYS" | "WHEN" | "IF" expression | functionExpr ; * assertion -> expression ; * * expression -> disjunction ; * disjunction -> conjunction ( ( "||" | "OR" ) conjunction )* ; * conjunction -> equality ( ( "&&" | "AND" ) equality )* ; * equality -> comparison ( ( "==" | "!=" ) comparison )? ; * comparison -> term ( ( "<" | "<=" | ">=" | ">" ) term )? ; * term -> factor ( ( "+" | "-" ) factor )* ; * factor -> unary ( ( "*" | "/" | "%" ) unary )* ; * unary -> ( "!" | "-" | "NOT" ) unary | primary ; * primary -> number | string | variable | function | "(" expression ")" ; * * variable -> model | state ; * model -> "$" ( nested )? ; * state -> "#" ( nested )? ; * nested -> identifier ( "." identifier )* ; * * function -> functionExpr | identifier "(" ( arguments )? ")" ; * arguments -> expression ( "," expression )* ; * functionExpr -> identifier ; * * number -> natural ( digit )* ( "." ( digit )+ )? ; * string -> "'" ( character )* "'" ; * identifier -> alpha ( alpha | digit | "_" )* ; * * digit -> zero | natural ; * character -> digit | alpha ; * zero -> "0" ; * natural -> "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; * alpha -> "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | * "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | * "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | * "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | * "t" | "u" | "v" | "w" | "x" | "y" | "z" ; */ export default class Parser { private readonly source; private readonly tokens; private current; private statistics; /** * Creates a new parser instance from a given string of source code and a list of tokens. * * @param source source code * @param tokens list of tokens */ constructor(source: string, tokens: Token[]); /** * Returns the ast for the given token list for a constraint. */ parse(): Expression.AST; /** * Returns the ast for the given token list for a model. */ parseModel(): Expression.AST; /** * Returns the ast for the given token list for a state. */ parseState(): Expression.AST; /** * Returns the ast for the given token list for a function. */ parseFunction(): Expression.AST; /** * Returns the ast for the given token list for a function expression. */ parseFunctionExpr(): Expression.AST; /** * Starts the parsing algorithm with a given starting rule. * * @param start starting rule * @param emptyMessage error message if an empty list is given (single eof token) * @private */ private run; /** * Matches this rule: * constraint -> activation ( ":" | "THEN" ) assertion ; * @private */ private constraint; /** * Matches this rule: * activation -> "ALWAYS" | "WHEN" | "IF" expression | functionExpr ; * @private */ private activation; /** * Matches this rule: * assertion -> expression ; * @private */ private assertion; /** * Matches this rule: * expression -> disjunction ; * @private */ private expression; /** * Matches this rule: * disjunction -> conjunction ( ( "||" | "OR" ) conjunction )* ; * @private */ private disjunction; /** * Matches this rule: * conjunction -> equality ( ( "&&" | "AND" ) equality )* ; * @private */ private conjunction; /** * Matches this rule: * equality -> comparison ( ( "==" | "!=" ) comparison )? ; * @private */ private equality; /** * Matches this rule: * comparison -> term ( ( "<" | "<=" | ">=" | ">" ) term )? ; * @private */ private comparison; /** * Matches this rule: * term -> factor ( ( "+" | "-" ) factor )* ; * @private */ private term; /** * Matches this rule: * factor -> unary ( ( "*" | "/" | "%" ) unary )* ; * @private */ private factor; /** * Matches this rule: * unary -> ( "!" | "-" | "NOT" ) unary | primary ; * @private */ private unary; /** * Matches this rule: * primary -> number | string | variable | function | "(" expression ")" ; * @private */ private primary; /** * Matches this rule: * variable -> model | state ; * model -> "$" ( nested )? ; * state -> "#" ( nested )? ; * nested -> identifier ( "." identifier )* ; * @private */ private variable; /** * Matches this rule: * function -> functionExpr | identifier "(" ( arguments )? ")" ; * @private */ private functionCall; /** * Matches this rule: * arguments -> expression ( "," expression )* ; * @private */ private args; /** * Matches this rule: * functionExpr -> identifier ; * @private */ private functionExpr; /** * Parses a rule with the following format: * rule -> production ( ( operators[0] | operators[1] | ... ) production )* ; * * @param logical true if currently parsing a logical expression * @param production production function pointer * @param operators binary operators of this rule * @private */ private parseLeftAssociativeBinaryOperator; /** * Parses a rule with the following format: * rule -> production ( ( operators[0] | operators[1] | ... ) production )? ; * * @param production production function pointer * @param operators binary operators of this rule * @private */ private parseLeftAssociativeOptionalBinaryOperator; /** * Adds a variable of given type (model or state) to the statistics counts. * * @param type variable type * @param name variable name * @private */ private addStatisticsVariable; /** * Consumes the current token if any of the given token types matches the current token. * * @param types token types to match * @private */ private matchAny; /** * Consumes the current token. * * @param type token type * @param message error message if current token is not of given type * @private */ private consume; /** * Consumes the current token if it matches any of the given token types. * * @param message error message if current token is not of any given type * @param types token types * @private */ private consumeAny; /** * Check if the current token is of the given type. * * @param type token type to check * @private */ private check; /** * Consumes the current token. * @private */ private advance; /** * Checks if the parser is done. * @private */ private isAtEnd; /** * Returns the current token. * @private */ private peek; /** * Returns the previous token. * @private */ private previous; /** * Prints an error message and then throws an error. * * @param token token where the error occurred * @param message error message * @private */ private syntaxErrorOnToken; }