@aid-framework/ir 0.0.0 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +135 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/build.d.ts +74 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +1079 -0
- package/dist/build.js.map +1 -0
- package/dist/capabilities.d.ts +65 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +176 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/catalog/index.d.ts +36 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +43 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/catalog/models.json +52 -0
- package/dist/diagnostics.d.ts +90 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +103 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/gates/agents.d.ts +34 -0
- package/dist/gates/agents.d.ts.map +1 -0
- package/dist/gates/agents.js +233 -0
- package/dist/gates/agents.js.map +1 -0
- package/dist/gates/capability.d.ts +15 -0
- package/dist/gates/capability.d.ts.map +1 -0
- package/dist/gates/capability.js +81 -0
- package/dist/gates/capability.js.map +1 -0
- package/dist/gates/contract.d.ts +35 -0
- package/dist/gates/contract.d.ts.map +1 -0
- package/dist/gates/contract.js +19 -0
- package/dist/gates/contract.js.map +1 -0
- package/dist/gates/cost.d.ts +40 -0
- package/dist/gates/cost.d.ts.map +1 -0
- package/dist/gates/cost.js +167 -0
- package/dist/gates/cost.js.map +1 -0
- package/dist/gates/deploy.d.ts +23 -0
- package/dist/gates/deploy.d.ts.map +1 -0
- package/dist/gates/deploy.js +44 -0
- package/dist/gates/deploy.js.map +1 -0
- package/dist/gates/eval-coverage.d.ts +11 -0
- package/dist/gates/eval-coverage.d.ts.map +1 -0
- package/dist/gates/eval-coverage.js +50 -0
- package/dist/gates/eval-coverage.js.map +1 -0
- package/dist/gates/guardrails.d.ts +24 -0
- package/dist/gates/guardrails.d.ts.map +1 -0
- package/dist/gates/guardrails.js +112 -0
- package/dist/gates/guardrails.js.map +1 -0
- package/dist/gates/hitl.d.ts +17 -0
- package/dist/gates/hitl.d.ts.map +1 -0
- package/dist/gates/hitl.js +40 -0
- package/dist/gates/hitl.js.map +1 -0
- package/dist/gates/index.d.ts +66 -0
- package/dist/gates/index.d.ts.map +1 -0
- package/dist/gates/index.js +77 -0
- package/dist/gates/index.js.map +1 -0
- package/dist/gates/memory.d.ts +13 -0
- package/dist/gates/memory.d.ts.map +1 -0
- package/dist/gates/memory.js +67 -0
- package/dist/gates/memory.js.map +1 -0
- package/dist/gates/normalize.d.ts +26 -0
- package/dist/gates/normalize.d.ts.map +1 -0
- package/dist/gates/normalize.js +228 -0
- package/dist/gates/normalize.js.map +1 -0
- package/dist/gates/orchestration.d.ts +17 -0
- package/dist/gates/orchestration.d.ts.map +1 -0
- package/dist/gates/orchestration.js +46 -0
- package/dist/gates/orchestration.js.map +1 -0
- package/dist/gates/referential.d.ts +12 -0
- package/dist/gates/referential.d.ts.map +1 -0
- package/dist/gates/referential.js +554 -0
- package/dist/gates/referential.js.map +1 -0
- package/dist/gates/security.d.ts +22 -0
- package/dist/gates/security.d.ts.map +1 -0
- package/dist/gates/security.js +225 -0
- package/dist/gates/security.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/policy/ast.d.ts +61 -0
- package/dist/policy/ast.d.ts.map +1 -0
- package/dist/policy/ast.js +48 -0
- package/dist/policy/ast.js.map +1 -0
- package/dist/policy/index.d.ts +7 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +4 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/lexer.d.ts +27 -0
- package/dist/policy/lexer.d.ts.map +1 -0
- package/dist/policy/lexer.js +147 -0
- package/dist/policy/lexer.js.map +1 -0
- package/dist/policy/parser.d.ts +15 -0
- package/dist/policy/parser.d.ts.map +1 -0
- package/dist/policy/parser.js +202 -0
- package/dist/policy/parser.js.map +1 -0
- package/dist/predicate/ast.d.ts +125 -0
- package/dist/predicate/ast.d.ts.map +1 -0
- package/dist/predicate/ast.js +111 -0
- package/dist/predicate/ast.js.map +1 -0
- package/dist/predicate/index.d.ts +7 -0
- package/dist/predicate/index.d.ts.map +1 -0
- package/dist/predicate/index.js +4 -0
- package/dist/predicate/index.js.map +1 -0
- package/dist/predicate/lexer.d.ts +30 -0
- package/dist/predicate/lexer.d.ts.map +1 -0
- package/dist/predicate/lexer.js +176 -0
- package/dist/predicate/lexer.js.map +1 -0
- package/dist/predicate/parser.d.ts +16 -0
- package/dist/predicate/parser.d.ts.map +1 -0
- package/dist/predicate/parser.js +317 -0
- package/dist/predicate/parser.js.map +1 -0
- package/dist/schema/ir.schema.json +1144 -0
- package/dist/serialize.d.ts +15 -0
- package/dist/serialize.d.ts.map +1 -0
- package/dist/serialize.js +53 -0
- package/dist/serialize.js.map +1 -0
- package/dist/shapes.d.ts +671 -0
- package/dist/shapes.d.ts.map +1 -0
- package/dist/shapes.js +159 -0
- package/dist/shapes.js.map +1 -0
- package/package.json +44 -14
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PredicateExpr lexer. Tracks byte offsets so every diagnostic points at the
|
|
3
|
+
* offending span. Never throws: malformed input yields tokens plus diagnostics.
|
|
4
|
+
*
|
|
5
|
+
* The only difference from the policy lexer is `.`, which is what makes
|
|
6
|
+
* `case.metadata.<name>` one path rather than three identifiers.
|
|
7
|
+
*/
|
|
8
|
+
import { IR_DIAGNOSTIC_CODES, irError, offsetPosition, withPosition, } from '../diagnostics.js';
|
|
9
|
+
const KEYWORDS = new Set(['true', 'false', 'and', 'or', 'not']);
|
|
10
|
+
export function predicateDiagnostic(source, context, offset, code, message, hint) {
|
|
11
|
+
const { line, column } = offsetPosition(source, offset);
|
|
12
|
+
return withPosition(irError({ code, message, path: context.path, hint }), {
|
|
13
|
+
file: context.file,
|
|
14
|
+
line,
|
|
15
|
+
column,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export function tokenizePredicate(source, context = {}) {
|
|
19
|
+
const tokens = [];
|
|
20
|
+
const diagnostics = [];
|
|
21
|
+
let index = 0;
|
|
22
|
+
while (index < source.length) {
|
|
23
|
+
const char = source[index];
|
|
24
|
+
if (char === ' ' || char === '\t' || char === '\n' || char === '\r') {
|
|
25
|
+
index += 1;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (char === '(' || char === ')' || char === ',' || char === '.') {
|
|
29
|
+
const type = char === '(' ? 'lparen' : char === ')' ? 'rparen' : char === ',' ? 'comma' : 'dot';
|
|
30
|
+
tokens.push({ type, value: char, start: index, end: index + 1 });
|
|
31
|
+
index += 1;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (char === '"' || char === "'") {
|
|
35
|
+
const end = scanString(source, index, char);
|
|
36
|
+
if (end === -1) {
|
|
37
|
+
diagnostics.push(predicateDiagnostic(source, context, index, IR_DIAGNOSTIC_CODES.predicateUnterminatedString, 'unterminated string literal', 'close the string with the same quote character it opened with'));
|
|
38
|
+
index = source.length;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
tokens.push({
|
|
42
|
+
type: 'string',
|
|
43
|
+
value: decodeString(source.slice(index + 1, end - 1)),
|
|
44
|
+
start: index,
|
|
45
|
+
end,
|
|
46
|
+
});
|
|
47
|
+
index = end;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (char >= '0' && char <= '9') {
|
|
51
|
+
const end = scanNumber(source, index);
|
|
52
|
+
tokens.push({ type: 'number', value: Number(source.slice(index, end)), start: index, end });
|
|
53
|
+
index = end;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (isIdentifierStart(char)) {
|
|
57
|
+
const end = scanIdentifier(source, index);
|
|
58
|
+
const text = source.slice(index, end);
|
|
59
|
+
if (text === 'true' || text === 'false') {
|
|
60
|
+
tokens.push({ type: 'boolean', value: text === 'true', start: index, end });
|
|
61
|
+
}
|
|
62
|
+
else if (KEYWORDS.has(text)) {
|
|
63
|
+
tokens.push({ type: 'operator', value: text, start: index, end });
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
tokens.push({ type: 'identifier', value: text, start: index, end });
|
|
67
|
+
}
|
|
68
|
+
index = end;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const pair = source.slice(index, index + 2);
|
|
72
|
+
if (pair === '==' || pair === '!=' || pair === '<=' || pair === '>=') {
|
|
73
|
+
tokens.push({ type: 'operator', value: pair, start: index, end: index + 2 });
|
|
74
|
+
index += 2;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (char === '<' || char === '>') {
|
|
78
|
+
tokens.push({ type: 'operator', value: char, start: index, end: index + 1 });
|
|
79
|
+
index += 1;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const unexpected = scanUnexpected(source, index);
|
|
83
|
+
diagnostics.push(predicateDiagnostic(source, context, index, IR_DIAGNOSTIC_CODES.predicateSyntax, `unexpected ${JSON.stringify(unexpected)}`, 'PredicateExpr supports prediction, case.id, case.metadata.<name>, string/number/boolean literals, comparisons, and/or/not, parentheses, and the contains/startswith/endswith/length builtins'));
|
|
84
|
+
index += unexpected.length;
|
|
85
|
+
}
|
|
86
|
+
tokens.push({ type: 'eof', value: '', start: source.length, end: source.length });
|
|
87
|
+
return { tokens, diagnostics };
|
|
88
|
+
}
|
|
89
|
+
/** The token's text as written, for messages. */
|
|
90
|
+
export function tokenText(token) {
|
|
91
|
+
if (token.type === 'string')
|
|
92
|
+
return JSON.stringify(token.value);
|
|
93
|
+
if (token.type === 'boolean')
|
|
94
|
+
return String(token.value);
|
|
95
|
+
return String(token.value);
|
|
96
|
+
}
|
|
97
|
+
function scanString(source, start, quote) {
|
|
98
|
+
let index = start + 1;
|
|
99
|
+
while (index < source.length) {
|
|
100
|
+
const char = source[index];
|
|
101
|
+
if (char === '\\') {
|
|
102
|
+
index += 2;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (char === quote)
|
|
106
|
+
return index + 1;
|
|
107
|
+
index += 1;
|
|
108
|
+
}
|
|
109
|
+
return -1;
|
|
110
|
+
}
|
|
111
|
+
function decodeString(raw) {
|
|
112
|
+
let decoded = '';
|
|
113
|
+
for (let index = 0; index < raw.length; index += 1) {
|
|
114
|
+
const char = raw[index];
|
|
115
|
+
if (char === '\\' && index + 1 < raw.length) {
|
|
116
|
+
const next = raw[index + 1];
|
|
117
|
+
decoded += next === 'n' ? '\n' : next === 't' ? '\t' : next === 'r' ? '\r' : next;
|
|
118
|
+
index += 1;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
decoded += char;
|
|
122
|
+
}
|
|
123
|
+
return decoded;
|
|
124
|
+
}
|
|
125
|
+
function scanNumber(source, start) {
|
|
126
|
+
let index = start;
|
|
127
|
+
while (index < source.length && isDigit(source[index]))
|
|
128
|
+
index += 1;
|
|
129
|
+
if (index < source.length && source[index] === '.') {
|
|
130
|
+
index += 1;
|
|
131
|
+
while (index < source.length && isDigit(source[index]))
|
|
132
|
+
index += 1;
|
|
133
|
+
}
|
|
134
|
+
return index;
|
|
135
|
+
}
|
|
136
|
+
function scanIdentifier(source, start) {
|
|
137
|
+
let index = start;
|
|
138
|
+
while (index < source.length && isIdentifierPart(source[index]))
|
|
139
|
+
index += 1;
|
|
140
|
+
return index;
|
|
141
|
+
}
|
|
142
|
+
function isDigit(char) {
|
|
143
|
+
return char >= '0' && char <= '9';
|
|
144
|
+
}
|
|
145
|
+
function isIdentifierStart(char) {
|
|
146
|
+
return (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || char === '_';
|
|
147
|
+
}
|
|
148
|
+
function isIdentifierPart(char) {
|
|
149
|
+
return isIdentifierStart(char) || isDigit(char);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The span of characters at `start` that no token can begin with.
|
|
153
|
+
*
|
|
154
|
+
* Coalesced so one unknown operator such as `=~` reports one error instead of one
|
|
155
|
+
* per character.
|
|
156
|
+
*/
|
|
157
|
+
function scanUnexpected(source, start) {
|
|
158
|
+
let index = start;
|
|
159
|
+
while (index < source.length && isUnexpected(source[index]))
|
|
160
|
+
index += 1;
|
|
161
|
+
return source.slice(start, Math.max(index, start + 1));
|
|
162
|
+
}
|
|
163
|
+
function isUnexpected(char) {
|
|
164
|
+
if (char === ' ' || char === '\t' || char === '\n' || char === '\r')
|
|
165
|
+
return false;
|
|
166
|
+
if (char === '(' || char === ')' || char === ',' || char === '.')
|
|
167
|
+
return false;
|
|
168
|
+
if (char === '"' || char === "'")
|
|
169
|
+
return false;
|
|
170
|
+
if (isDigit(char) || isIdentifierStart(char))
|
|
171
|
+
return false;
|
|
172
|
+
// `<` and `>` always lex as operators before reaching here, but they can appear
|
|
173
|
+
// later in a run, so they still end it.
|
|
174
|
+
return char !== '<' && char !== '>';
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=lexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexer.js","sourceRoot":"","sources":["../../src/predicate/lexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PredicateExpr recursive-descent parser. Total: it returns an AST plus
|
|
3
|
+
* diagnostics and never lets an exception escape. An unparseable predicate yields
|
|
4
|
+
* an `invalid` node and an error diagnostic -- never a missing condition, which a
|
|
5
|
+
* caller could mistake for "nothing to check".
|
|
6
|
+
*/
|
|
7
|
+
import { type IrDiagnostic } from '../diagnostics.js';
|
|
8
|
+
import { type PredicateNode } from './ast.js';
|
|
9
|
+
import { type PredicateContext } from './lexer.js';
|
|
10
|
+
export interface PredicateParseResult {
|
|
11
|
+
/** Always present: an unparseable source comes back as an `invalid` node. */
|
|
12
|
+
ast: PredicateNode;
|
|
13
|
+
diagnostics: IrDiagnostic[];
|
|
14
|
+
}
|
|
15
|
+
export declare function parsePredicateExpr(source: string, context?: PredicateContext): PredicateParseResult;
|
|
16
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/predicate/parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAuB,KAAK,YAAY,EAAyB,MAAM,mBAAmB,CAAC;AAClG,OAAO,EAOL,KAAK,aAAa,EAGnB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,gBAAgB,EAKtB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,GAAG,EAAE,aAAa,CAAC;IACnB,WAAW,EAAE,YAAY,EAAE,CAAC;CAC7B;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,GAC7B,oBAAoB,CA2FtB"}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PredicateExpr recursive-descent parser. Total: it returns an AST plus
|
|
3
|
+
* diagnostics and never lets an exception escape. An unparseable predicate yields
|
|
4
|
+
* an `invalid` node and an error diagnostic -- never a missing condition, which a
|
|
5
|
+
* caller could mistake for "nothing to check".
|
|
6
|
+
*/
|
|
7
|
+
import { IR_DIAGNOSTIC_CODES, irError, withPosition } from '../diagnostics.js';
|
|
8
|
+
import { formatPredicateExpr, isPredicateBuiltin, PREDICATE_BUILTIN_ARITY, PREDICATE_OPERATORS, predicateIsBoolean, } from './ast.js';
|
|
9
|
+
import { predicateDiagnostic, tokenizePredicate, tokenText, } from './lexer.js';
|
|
10
|
+
export function parsePredicateExpr(source, context = {}) {
|
|
11
|
+
const diagnostics = [];
|
|
12
|
+
if (source.trim() === '') {
|
|
13
|
+
diagnostics.push(predicateDiagnostic(source, context, 0, IR_DIAGNOSTIC_CODES.predicateEmpty, 'empty predicate expression', 'an assert must evaluate to true or false; there is no implicit "pass"'));
|
|
14
|
+
return { ast: invalidNode('empty predicate expression'), diagnostics };
|
|
15
|
+
}
|
|
16
|
+
const lexed = tokenizePredicate(source, context);
|
|
17
|
+
diagnostics.push(...lexed.diagnostics);
|
|
18
|
+
// A tokenization failure makes the token stream untrustworthy: parsing it would
|
|
19
|
+
// report cascading syntax errors for characters the lexer already rejected.
|
|
20
|
+
if (diagnostics.some((entry) => entry.severity === 'error')) {
|
|
21
|
+
const first = diagnostics.find((entry) => entry.severity === 'error');
|
|
22
|
+
return { ast: invalidNode(first?.message ?? 'predicate could not be read'), diagnostics };
|
|
23
|
+
}
|
|
24
|
+
let ast;
|
|
25
|
+
try {
|
|
26
|
+
const parser = new Parser(source, context, lexed.tokens, diagnostics);
|
|
27
|
+
ast = parser.parseExpression();
|
|
28
|
+
if (ast !== undefined && !parser.atEnd()) {
|
|
29
|
+
const token = parser.peek();
|
|
30
|
+
diagnostics.push(predicateDiagnostic(source, context, token.start, IR_DIAGNOSTIC_CODES.predicateTrailingToken, `unexpected trailing ${tokenText(token)} after a complete expression`, 'a predicate is a single expression; combine conditions with and/or'));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
diagnostics.push(withPosition(irError({
|
|
35
|
+
code: IR_DIAGNOSTIC_CODES.predicateSyntax,
|
|
36
|
+
message: `predicate expression could not be parsed: ${error instanceof Error ? error.message : String(error)}`,
|
|
37
|
+
path: context.path,
|
|
38
|
+
}), { file: context.file }));
|
|
39
|
+
}
|
|
40
|
+
const firstError = diagnostics.find((entry) => entry.severity === 'error');
|
|
41
|
+
if (firstError !== undefined || ast === undefined) {
|
|
42
|
+
return {
|
|
43
|
+
ast: invalidNode(firstError?.message ?? 'predicate could not be parsed'),
|
|
44
|
+
diagnostics,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// Every boolean position, not just the root: `length(prediction)` at the root and
|
|
48
|
+
// `not prediction` under a `not` are the same mistake, and both must be refused
|
|
49
|
+
// here rather than surfacing as "not a pass" at eval time.
|
|
50
|
+
const mistyped = booleanPositionErrors(ast);
|
|
51
|
+
if (mistyped.length > 0) {
|
|
52
|
+
for (const node of mistyped) {
|
|
53
|
+
diagnostics.push(predicateDiagnostic(source, context, 0, IR_DIAGNOSTIC_CODES.predicateNotBoolean, `${formatPredicateExpr(node)} is not true or false`, 'a predicate must evaluate to true or false; compare it, for example `prediction != ""` or `length(prediction) < 4000`'));
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
ast: invalidNode('a predicate must evaluate to true or false'),
|
|
57
|
+
diagnostics,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return { ast, diagnostics };
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Every node sitting in a boolean position that is not boolean by construction.
|
|
64
|
+
*
|
|
65
|
+
* `predicateIsBoolean` only answers for one node; `and`/`or`/`not` are boolean
|
|
66
|
+
* whatever their operands are, so the walk is what catches a string or a number
|
|
67
|
+
* smuggled into a boolean slot.
|
|
68
|
+
*/
|
|
69
|
+
function booleanPositionErrors(root) {
|
|
70
|
+
const wrong = [];
|
|
71
|
+
const visit = (node, booleanPosition) => {
|
|
72
|
+
if (booleanPosition && !predicateIsBoolean(node))
|
|
73
|
+
wrong.push(node);
|
|
74
|
+
switch (node.kind) {
|
|
75
|
+
case 'and':
|
|
76
|
+
case 'or':
|
|
77
|
+
visit(node.left, true);
|
|
78
|
+
visit(node.right, true);
|
|
79
|
+
return;
|
|
80
|
+
case 'not':
|
|
81
|
+
visit(node.operand, true);
|
|
82
|
+
return;
|
|
83
|
+
case 'comparison':
|
|
84
|
+
visit(node.left, false);
|
|
85
|
+
visit(node.right, false);
|
|
86
|
+
return;
|
|
87
|
+
case 'call':
|
|
88
|
+
for (const argument of node.args)
|
|
89
|
+
visit(argument, false);
|
|
90
|
+
return;
|
|
91
|
+
default:
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
visit(root, true);
|
|
96
|
+
return wrong;
|
|
97
|
+
}
|
|
98
|
+
function invalidNode(reason) {
|
|
99
|
+
return { kind: 'invalid', reason };
|
|
100
|
+
}
|
|
101
|
+
class Parser {
|
|
102
|
+
source;
|
|
103
|
+
context;
|
|
104
|
+
tokens;
|
|
105
|
+
diagnostics;
|
|
106
|
+
index = 0;
|
|
107
|
+
constructor(source, context, tokens, diagnostics) {
|
|
108
|
+
this.source = source;
|
|
109
|
+
this.context = context;
|
|
110
|
+
this.tokens = tokens;
|
|
111
|
+
this.diagnostics = diagnostics;
|
|
112
|
+
}
|
|
113
|
+
atEnd() {
|
|
114
|
+
return this.peek().type === 'eof';
|
|
115
|
+
}
|
|
116
|
+
peek(offset = 0) {
|
|
117
|
+
const token = this.tokens[Math.min(this.index + offset, this.tokens.length - 1)];
|
|
118
|
+
return token;
|
|
119
|
+
}
|
|
120
|
+
parseExpression() {
|
|
121
|
+
return this.parseOr();
|
|
122
|
+
}
|
|
123
|
+
parseOr() {
|
|
124
|
+
let left = this.parseAnd();
|
|
125
|
+
while (this.isOperator('or')) {
|
|
126
|
+
this.index += 1;
|
|
127
|
+
const right = this.parseAnd();
|
|
128
|
+
if (left === undefined || right === undefined)
|
|
129
|
+
return left ?? right;
|
|
130
|
+
left = { kind: 'or', left, right };
|
|
131
|
+
}
|
|
132
|
+
return left;
|
|
133
|
+
}
|
|
134
|
+
parseAnd() {
|
|
135
|
+
let left = this.parseNot();
|
|
136
|
+
while (this.isOperator('and')) {
|
|
137
|
+
this.index += 1;
|
|
138
|
+
const right = this.parseNot();
|
|
139
|
+
if (left === undefined || right === undefined)
|
|
140
|
+
return left ?? right;
|
|
141
|
+
left = { kind: 'and', left, right };
|
|
142
|
+
}
|
|
143
|
+
return left;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* `not` binds looser than a comparison, so `not prediction == "a"` negates the
|
|
147
|
+
* comparison rather than negating a string. Binding it tighter would let
|
|
148
|
+
* `not <string path>` reach the evaluator as a well-typed-looking tree.
|
|
149
|
+
*/
|
|
150
|
+
parseNot() {
|
|
151
|
+
if (!this.isOperator('not'))
|
|
152
|
+
return this.parseComparison();
|
|
153
|
+
this.index += 1;
|
|
154
|
+
const operand = this.parseNot();
|
|
155
|
+
return operand === undefined ? undefined : { kind: 'not', operand };
|
|
156
|
+
}
|
|
157
|
+
parseComparison() {
|
|
158
|
+
const left = this.parsePrimary();
|
|
159
|
+
const token = this.peek();
|
|
160
|
+
const op = token.type === 'operator' ? toOperator(String(token.value)) : undefined;
|
|
161
|
+
if (op === undefined)
|
|
162
|
+
return left;
|
|
163
|
+
this.index += 1;
|
|
164
|
+
const right = this.parsePrimary();
|
|
165
|
+
if (left === undefined || right === undefined)
|
|
166
|
+
return left ?? right;
|
|
167
|
+
return { kind: 'comparison', op, left, right };
|
|
168
|
+
}
|
|
169
|
+
parsePrimary() {
|
|
170
|
+
const token = this.peek();
|
|
171
|
+
if (token.type === 'boolean') {
|
|
172
|
+
this.index += 1;
|
|
173
|
+
return { kind: 'boolean', value: Boolean(token.value) };
|
|
174
|
+
}
|
|
175
|
+
if (token.type === 'number') {
|
|
176
|
+
this.index += 1;
|
|
177
|
+
return { kind: 'number', value: Number(token.value) };
|
|
178
|
+
}
|
|
179
|
+
if (token.type === 'string') {
|
|
180
|
+
this.index += 1;
|
|
181
|
+
return { kind: 'string', value: String(token.value) };
|
|
182
|
+
}
|
|
183
|
+
if (token.type === 'lparen') {
|
|
184
|
+
this.index += 1;
|
|
185
|
+
const inner = this.parseExpression();
|
|
186
|
+
if (this.peek().type !== 'rparen') {
|
|
187
|
+
this.report(this.peek().start, IR_DIAGNOSTIC_CODES.predicateUnclosedParen, 'unclosed parenthesis in predicate expression', 'add the matching ")"');
|
|
188
|
+
return inner;
|
|
189
|
+
}
|
|
190
|
+
this.index += 1;
|
|
191
|
+
return inner;
|
|
192
|
+
}
|
|
193
|
+
if (token.type === 'identifier') {
|
|
194
|
+
return this.parseIdentifier();
|
|
195
|
+
}
|
|
196
|
+
this.report(token.start, IR_DIAGNOSTIC_CODES.predicateExpected, token.type === 'eof'
|
|
197
|
+
? 'unexpected end of predicate expression'
|
|
198
|
+
: `unexpected ${tokenText(token)} in predicate expression`, 'expected prediction, case.id, case.metadata.<name>, a literal, or a builtin call');
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
parseIdentifier() {
|
|
202
|
+
const token = this.peek();
|
|
203
|
+
const name = String(token.value);
|
|
204
|
+
if (this.peek(1).type === 'lparen') {
|
|
205
|
+
return this.parseCall(token, name);
|
|
206
|
+
}
|
|
207
|
+
return this.parsePath(token, name);
|
|
208
|
+
}
|
|
209
|
+
parseCall(token, name) {
|
|
210
|
+
if (!isPredicateBuiltin(name)) {
|
|
211
|
+
this.report(token.start, IR_DIAGNOSTIC_CODES.predicateUnknownBuiltin, `unknown builtin "${name}"`, 'a predicate naming a builtin the runtime cannot evaluate is rejected rather than treated as true');
|
|
212
|
+
this.skipCallArguments();
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
this.index += 2; // identifier and '('
|
|
216
|
+
const args = [];
|
|
217
|
+
if (this.peek().type !== 'rparen') {
|
|
218
|
+
for (;;) {
|
|
219
|
+
const argument = this.parsePrimary();
|
|
220
|
+
if (argument === undefined)
|
|
221
|
+
break;
|
|
222
|
+
args.push(argument);
|
|
223
|
+
if (this.peek().type !== 'comma')
|
|
224
|
+
break;
|
|
225
|
+
this.index += 1;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (this.peek().type !== 'rparen') {
|
|
229
|
+
this.report(this.peek().start, IR_DIAGNOSTIC_CODES.predicateUnclosedParen, `unclosed argument list for ${name}(...)`, 'add the matching ")"');
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
this.index += 1;
|
|
233
|
+
const builtin = name;
|
|
234
|
+
const arity = PREDICATE_BUILTIN_ARITY[builtin];
|
|
235
|
+
if (args.length !== arity) {
|
|
236
|
+
this.report(token.start, IR_DIAGNOSTIC_CODES.predicateArity, `${name}() takes ${arity} argument${arity === 1 ? '' : 's'}, received ${args.length}`);
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
const call = { kind: 'call', name: builtin, args };
|
|
240
|
+
return call;
|
|
241
|
+
}
|
|
242
|
+
parsePath(token, name) {
|
|
243
|
+
if (name === 'prediction') {
|
|
244
|
+
this.index += 1;
|
|
245
|
+
return { kind: 'path', path: 'prediction' };
|
|
246
|
+
}
|
|
247
|
+
if (name !== 'case') {
|
|
248
|
+
this.reportUnknownPath(token, name);
|
|
249
|
+
this.index += 1;
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
this.index += 1; // 'case'
|
|
253
|
+
if (this.peek().type !== 'dot') {
|
|
254
|
+
this.reportUnknownPath(token, name);
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
this.index += 1; // '.'
|
|
258
|
+
const field = this.peek();
|
|
259
|
+
if (field.type !== 'identifier') {
|
|
260
|
+
this.reportUnknownPath(token, name);
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
const fieldName = String(field.value);
|
|
264
|
+
this.index += 1;
|
|
265
|
+
if (fieldName === 'id') {
|
|
266
|
+
return { kind: 'path', path: 'case.id' };
|
|
267
|
+
}
|
|
268
|
+
if (fieldName !== 'metadata') {
|
|
269
|
+
this.reportUnknownPath(token, `case.${fieldName}`);
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
if (this.peek().type !== 'dot') {
|
|
273
|
+
this.report(field.start, IR_DIAGNOSTIC_CODES.predicateUnknownPath, 'case.metadata is not a value on its own; name one of its keys', 'write case.metadata.<name>, for example case.metadata.locale');
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
this.index += 1; // '.'
|
|
277
|
+
const key = this.peek();
|
|
278
|
+
if (key.type !== 'identifier') {
|
|
279
|
+
this.report(key.start, IR_DIAGNOSTIC_CODES.predicateUnknownPath, 'case.metadata requires a key name after the final "."', 'write case.metadata.<name>, for example case.metadata.locale');
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
this.index += 1;
|
|
283
|
+
return { kind: 'path', path: 'case.metadata', name: String(key.value) };
|
|
284
|
+
}
|
|
285
|
+
reportUnknownPath(token, name) {
|
|
286
|
+
this.report(token.start, IR_DIAGNOSTIC_CODES.predicateUnknownPath, `unknown path "${name}"`, 'the only paths are prediction, case.id, and case.metadata.<name>');
|
|
287
|
+
}
|
|
288
|
+
/** Consumes a rejected call's arguments so one bad builtin yields one error. */
|
|
289
|
+
skipCallArguments() {
|
|
290
|
+
let depth = 0;
|
|
291
|
+
while (!this.atEnd()) {
|
|
292
|
+
const token = this.peek();
|
|
293
|
+
this.index += 1;
|
|
294
|
+
if (token.type === 'lparen') {
|
|
295
|
+
depth += 1;
|
|
296
|
+
}
|
|
297
|
+
else if (token.type === 'rparen') {
|
|
298
|
+
depth -= 1;
|
|
299
|
+
if (depth <= 0)
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
isOperator(value) {
|
|
305
|
+
const token = this.peek();
|
|
306
|
+
return token.type === 'operator' && token.value === value;
|
|
307
|
+
}
|
|
308
|
+
report(offset, code, message, hint) {
|
|
309
|
+
this.diagnostics.push(predicateDiagnostic(this.source, this.context, offset, code, message, hint));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
function toOperator(value) {
|
|
313
|
+
return PREDICATE_OPERATORS.includes(value)
|
|
314
|
+
? value
|
|
315
|
+
: undefined;
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/predicate/parser.ts"],"names":[],"mappings":"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"}
|