diff --git a/package-lock.json b/package-lock.json index 4f267c9..50dd440 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@arbiter/core", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@arbiter/core", - "version": "1.0.0", + "version": "1.0.1", "license": "ISC", "dependencies": { "@tenere/pltc-core": "^0.6.3", @@ -14,21 +14,32 @@ "uuidv7": "^1.0.2" }, "devDependencies": { + "@arbiter/evidence-dsl": "^1.0.0", "@rigor/core": "*", "@tenere/benchmark-lib": "^2.0.1", - "fast-check": "^4.5.3", - "peggy": "^5.0.6" + "fast-check": "^4.5.3" } }, - "node_modules/@peggyjs/from-mem": { - "version": "3.1.3", + "node_modules/@arbiter/core": { + "version": "1.0.1", + "resolved": "https://hub.kl1.tenere.ai/api/packages/Arbiter/npm/%40arbiter%2Fcore/-/1.0.1/core-1.0.1.tgz", + "integrity": "sha512-BfIv6vRKsuJR39WBkBGxl2PQ/LDoW/J1u4UeFrog0AbeTSTvRqhxG1+its2pAcUvcQXq99ZOccFlK3XgNRKt4Q==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "semver": "7.7.4" - }, - "engines": { - "node": ">=20.8" + "@tenere/pltc-core": "^0.6.3", + "heapify": "^1.0.2", + "uuidv7": "^1.0.2" + } + }, + "node_modules/@arbiter/evidence-dsl": { + "version": "1.0.0", + "resolved": "https://hub.kl1.tenere.ai/api/packages/Arbiter/npm/%40arbiter%2Fevidence-dsl/-/1.0.0/evidence-dsl-1.0.0.tgz", + "integrity": "sha512-v28SkNfcR60rJkDG6Btp5ieYaHQQZEiIJshsyGZYJiTt+V2bGbEj8341PUSzaSE5vRL2mVmRWKT9RoDHQXnzWg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@arbiter/core": "^1.0.1" } }, "node_modules/@rigor/analysis": { @@ -332,14 +343,6 @@ "@tenere/graph-core": "^1.0.1" } }, - "node_modules/commander": { - "version": "14.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - } - }, "node_modules/fast-check": { "version": "4.9.0", "dev": true, @@ -365,22 +368,6 @@ "version": "1.0.2", "license": "MIT" }, - "node_modules/peggy": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@peggyjs/from-mem": "3.1.3", - "commander": "^14.0.3", - "source-map-generator": "2.0.6" - }, - "bin": { - "peggy": "bin/peggy.js" - }, - "engines": { - "node": ">=20" - } - }, "node_modules/pure-rand": { "version": "8.4.2", "dev": true, @@ -396,25 +383,6 @@ ], "license": "MIT" }, - "node_modules/semver": { - "version": "7.7.4", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/source-map-generator": { - "version": "2.0.6", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=20" - } - }, "node_modules/uuidv7": { "version": "1.2.1", "license": "Apache-2.0", diff --git a/package.json b/package.json index 04ede95..a0dd19d 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,6 @@ "test:property": "node --test --test-force-exit \"tests/property-based/**/*.test.js\"", "test:integration": "node --test --test-force-exit \"tests/integration/*.js\"", "test:perf": "RUN_PERF_TESTS=1 node --test --test-force-exit tests/engine/core-performance-targets.test.js", - "generate:parser": "node scripts/generate-parser.js", - "build:ast": "npm run generate:parser", "benchmark": "node --expose-gc scripts/benchmark.js", "benchmark:core": "node benchmarks/core-performance-benchmark.js", "benchmark:batch": "node benchmarks/batch-size-analysis.js", @@ -69,6 +67,6 @@ "@rigor/core": "*", "@tenere/benchmark-lib": "^2.0.1", "fast-check": "^4.5.3", - "peggy": "^5.0.6" + "@arbiter/evidence-dsl": "^1.0.0" } } diff --git a/scripts/generate-parser.js b/scripts/generate-parser.js deleted file mode 100755 index 5eb325f..0000000 --- a/scripts/generate-parser.js +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env node - -/** - * Script to generate the DSL parser from Peggy grammar - */ - -import peggy from 'peggy'; -import fs from 'fs'; -import path from 'path'; -import { fileURLToPath } from 'url'; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -const grammarPath = path.join(__dirname, '../src/ast/grammar/dsl.peggy'); -const outputPath = path.join(__dirname, '../src/ast/parser/GeneratedParser.js'); - -console.log('Generating DSL parser from Peggy grammar...'); -console.log('Grammar:', grammarPath); -console.log('Output:', outputPath); - -try { - // Read the grammar file - const grammar = fs.readFileSync(grammarPath, 'utf8'); - - // Generate the parser - const parserSource = peggy.generate(grammar, { - format: 'es', - output: 'source', - grammarSource: 'dsl.peggy' - }); - - // Write the generated parser - fs.writeFileSync(outputPath, parserSource); - - console.log('✅ Parser generated successfully!'); - console.log('Generated file:', outputPath); - -} catch (error) { - console.error('❌ Error generating parser:'); - console.error(error.message); - - if (error.format) { - console.error('\nFormatted error:'); - console.error(error.format([ - { source: 'dsl.peggy', text: fs.readFileSync(grammarPath, 'utf8') } - ])); - } - - process.exit(1); -} diff --git a/src/ast/DSLCompiler.js b/src/ast/DSLCompiler.js deleted file mode 100644 index 8a1f796..0000000 --- a/src/ast/DSLCompiler.js +++ /dev/null @@ -1,356 +0,0 @@ -import { parse } from './parser/DSLParser.js'; -import { RuleGenerator } from './generator/RuleGenerator.js'; -import { validateDslText } from './validation/DSLValidation.js'; - -/** - * DSL Compiler - Main integration layer - * Compiles DSL text into rule configurations for the zanzibar-graph system - */ -export class DSLCompiler { - constructor(arbiter) { - this.arbiter = arbiter; - this.parser = parse; - this.generator = new RuleGenerator(arbiter); - this.compiledPrograms = new Map(); - } - - /** - * Compile DSL text into rule configurations - * @param {string} dslText - DSL text to compile - * @param {string} programName - Optional name for the program - * @returns {Object} Compilation result - */ - compile(dslText, programName = 'default') { - try { - const validation = validateDslText(dslText); - if (!validation.success) { - return { - success: false, - errors: validation.errors, - warnings: validation.warnings, - program: null, - generatedRules: new Map() - }; - } - - const program = validation.program; - - // Convert plain AST to ProgramNode structure - const programNode = { - definitions: program.body.filter(s => s.type === 'Definition'), - facts: program.body.filter(s => s.type === 'Fact'), - evidence: program.body.filter(s => s.type === 'Evidence'), - measures: program.body.filter(s => s.type === 'Measure'), - validate: () => ({ isValid: true, errors: [], warnings: [] }) - }; - - // Generate rules from AST - const generationResult = this.generator.generateRules(programNode); - - if (!generationResult.success) { - return { - success: false, - errors: generationResult.errors, - warnings: [], - program: programNode, - generatedRules: new Map() - }; - } - - // Store compiled program - this.compiledPrograms.set(programName, { - program: programNode, - generatedRules: this.generator.getGeneratedRules(), - dependencyIndex: this.generator.getDependencyIndex(), - compiledAt: new Date() - }); - - return { - success: true, - errors: validation.errors, - warnings: validation.warnings, - program: programNode, - generatedRules: this.generator.getGeneratedRules(), - dependencyIndex: this.generator.getDependencyIndex(), - generatedCount: generationResult.generatedCount - }; - } catch (error) { - return { - success: false, - errors: [`Compilation error: ${error.message}`], - warnings: [], - program: null, - generatedRules: new Map() - }; - } - } - - /** - * Compile multiple DSL programs - * @param {Object} programs - Map of program names to DSL text - * @returns {Object} Compilation result for all programs - */ - compileMultiple(programs) { - const results = {}; - let overallSuccess = true; - const allErrors = []; - const allWarnings = []; - - for (const [name, dslText] of Object.entries(programs)) { - const result = this.compile(dslText, name); - results[name] = result; - - if (!result.success) { - overallSuccess = false; - } - - allErrors.push(...result.errors.map(err => `${name}: ${err}`)); - allWarnings.push(...result.warnings.map(warn => `${name}: ${warn}`)); - } - - return { - success: overallSuccess, - errors: allErrors, - warnings: allWarnings, - results: results - }; - } - - /** - * Get compiled program by name - * @param {string} programName - Name of the program - * @returns {Object|null} Compiled program or null - */ - getCompiledProgram(programName) { - return this.compiledPrograms.get(programName) || null; - } - - /** - * Get all compiled programs - * @returns {Map} Map of all compiled programs - */ - getAllCompiledPrograms() { - return this.compiledPrograms; - } - - /** - * Remove compiled program - * @param {string} programName - Name of the program to remove - * @returns {boolean} True if removed successfully - */ - removeCompiledProgram(programName) { - return this.compiledPrograms.delete(programName); - } - - /** - * Clear all compiled programs - */ - clearCompiledPrograms() { - this.compiledPrograms.clear(); - } - - /** - * Get compilation statistics - * @returns {Object} Compilation statistics - */ - getCompilationStats() { - const stats = { - totalPrograms: this.compiledPrograms.size, - totalRules: 0, - programs: {} - }; - - this.compiledPrograms.forEach((program, name) => { - const programStats = { - name: name, - compiledAt: program.compiledAt, - ruleCount: program.generatedRules.size, - definitions: program.program.definitions.length, - facts: program.program.facts.length, - evidence: program.program.evidence.length, - measures: program.program.measures.length - }; - - stats.programs[name] = programStats; - stats.totalRules += program.generatedRules.size; - }); - - return stats; - } - - /** - * Validate DSL text without compiling - * @param {string} dslText - DSL text to validate - * @returns {Object} Validation result - */ - validate(dslText) { - const validation = validateDslText(dslText); - return { - success: validation.success, - errors: validation.errors, - warnings: validation.warnings, - program: validation.program - }; - } - - /** - * Get parser errors from last parse - * @returns {string[]} Array of parser errors - */ - getParserErrors() { - return this.parser.getErrors(); - } - - /** - * Get generator errors from last generation - * @returns {string[]} Array of generator errors - */ - getGeneratorErrors() { - return this.generator.getErrors(); - } - - /** - * Check if a relation is configured - * @param {string} relation - Relation name to check - * @returns {boolean} True if relation is configured - */ - isRelationConfigured(relation) { - return this.arbiter.relationConfigs.has(relation); - } - - /** - * Get relation configuration - * @param {string} relation - Relation name - * @returns {Object|null} Relation configuration or null - */ - getRelationConfig(relation) { - return this.arbiter.relationConfigs.get(relation) || null; - } - - /** - * Get all configured relations - * @returns {Map} Map of all relation configurations - */ - getAllRelationConfigs() { - return this.arbiter.relationConfigs; - } - - /** - * Export compiled program to JSON - * @param {string} programName - Name of the program to export - * @returns {string|null} JSON string or null if program not found - */ - exportProgram(programName) { - const program = this.getCompiledProgram(programName); - if (!program) { - return null; - } - - return JSON.stringify({ - name: programName, - compiledAt: program.compiledAt, - program: this.serializeProgram(program.program), - generatedRules: Array.from(program.generatedRules.entries()) - }, null, 2); - } - - /** - * Import compiled program from JSON - * @param {string} jsonString - JSON string to import - * @returns {boolean} True if imported successfully - */ - importProgram(jsonString) { - try { - const data = JSON.parse(jsonString); - const program = this.deserializeProgram(data.program); - - this.compiledPrograms.set(data.name, { - program: program, - generatedRules: new Map(data.generatedRules), - compiledAt: new Date(data.compiledAt) - }); - - // Apply rules to arbiter - data.generatedRules.forEach(([relation, config]) => { - this.arbiter.setRelationConfig(relation, config); - }); - - return true; - } catch (error) { - return false; - } - } - - /** - * Serialize program to plain object - * @param {ProgramNode} program - Program to serialize - * @returns {Object} Serialized program - */ - serializeProgram(program) { - // This is a simplified serialization - in a real implementation, - // you'd want to properly serialize all node types - return { - type: 'Program', - definitions: program.definitions.map(def => ({ - type: 'Definition', - name: def.name, - definitionType: def.definitionType, - fields: def.fields.map(field => ({ - type: 'Field', - name: field.name, - type: field.type, - isArray: field.isArray, - isOptional: field.isOptional - })) - })), - facts: program.facts.map(fact => ({ - type: 'Fact', - name: fact.name, - parameters: fact.parameters.map(param => ({ - type: 'Parameter', - name: param.name, - type: param.type, - isArray: param.isArray - })) - })), - evidence: program.evidence.map(ev => ({ - type: 'Evidence', - name: ev.name, - parameters: ev.parameters.map(param => ({ - type: 'Parameter', - name: param.name, - type: param.type, - isArray: param.isArray - })), - returnType: ev.returnType - })), - measures: program.measures.map(measure => ({ - type: 'Measure', - name: measure.name, - parameters: measure.parameters.map(param => ({ - type: 'Parameter', - name: param.name, - type: param.type, - isArray: param.isArray - })), - returnType: measure.returnType - })) - }; - } - - /** - * Deserialize program from plain object - * @param {Object} data - Serialized program data - * @returns {ProgramNode} Deserialized program - */ - deserializeProgram(data) { - // This is a simplified deserialization - in a real implementation, - // you'd want to properly deserialize all node types - const program = new ProgramNode(); - - // Note: This is a basic implementation. In practice, you'd need - // to properly reconstruct all the AST nodes from the serialized data - - return program; - } -} diff --git a/src/ast/generator/RuleGenerator.js b/src/ast/generator/RuleGenerator.js deleted file mode 100644 index c64b32a..0000000 --- a/src/ast/generator/RuleGenerator.js +++ /dev/null @@ -1,1039 +0,0 @@ -import { ProgramNode, DefinitionNode, FactNode, EvidenceNode, MeasureNode, DirectEvidenceNode, PatternMatchNode, DefeasibleLogicNode, FusionNode, PredicateNode, ExpressionNode } from '../nodes/index.js'; - -/** - * Rule Generator for converting AST to setRelationConfig calls - * Generates rule configurations that interface with the existing rule system - */ -export class RuleGenerator { - constructor(arbiter) { - this.arbiter = arbiter; - this.generatedRules = new Map(); - this.errors = []; - this.dependencyIndex = new Map(); - } - - /** - * Generate rules from AST program - * @param {ProgramNode} program - AST program to generate rules from - * @returns {Object} Generation result with success status and errors - */ - generateRules(program) { - this.errors = []; - this.generatedRules.clear(); - this.dependencyIndex.clear(); - - try { - // Generate rules for each evidence definition - program.evidence.forEach(evidence => { - this.generateEvidenceRules(evidence); - }); - - // Generate rules for each measure definition - program.measures.forEach(measure => { - this.generateMeasureRules(measure); - }); - - // Generate fact relation configs (requires injection at check time) - program.facts.forEach(fact => { - this.generateFactConfig(fact); - }); - - // Apply generated rules to arbiter - this.applyRulesToArbiter(); - - return { - success: this.errors.length === 0, - errors: this.errors, - generatedCount: this.generatedRules.size - }; - } catch (error) { - this.errors.push(`Generation error: ${error.message}`); - return { - success: false, - errors: this.errors, - generatedCount: 0 - }; - } - } - - /** - * Generate rules for an evidence definition - * @param {EvidenceNode} evidence - Evidence to generate rules for - */ - generateEvidenceRules(evidence) { - const relationName = evidence.name; - const ruleConfig = this.buildRuleConfig(evidence); - - if (ruleConfig) { - this._annotateDependencies(relationName, ruleConfig); - this.generatedRules.set(relationName, ruleConfig); - } - } - - /** - * Generate rules for a measure definition - * @param {MeasureNode} measure - Measure to generate rules for - */ - generateMeasureRules(measure) { - const relationName = measure.name; - const ruleConfig = this.buildMeasureRuleConfig(measure); - - if (ruleConfig) { - this._annotateDependencies(relationName, ruleConfig); - this.generatedRules.set(relationName, ruleConfig); - } - } - - /** - * Generate relation config for a fact declaration. - * Facts require injection at check time (e.g. from user DB, session store). - * Registered as type: 'direct' with requiresInjection flag so the gate-check - * pipeline can pre-fetch facts before calling graphStore.check(). - * @param {FactNode} fact - Fact to generate config for - */ - generateFactConfig(fact) { - const name = fact.name; - const params = fact.params || []; - const paramNames = params.map(p => p.name); - const paramTypes = params.map(p => p.type); - - this.generatedRules.set(name, { - type: 'direct', - relation: name, - isFactRelation: true, - requiresInjection: true, - arity: paramTypes.length, - paramTypes: paramTypes, - paramNames: paramNames, - cacheDirective: fact.cacheDirective || fact.cache || 'lazy', - properties: Object.fromEntries( - (fact.properties || []).map(p => - typeof p === 'string' ? [p, true] : Array.isArray(p) ? p : [p, true] - ) - ) - }); - } - - _annotateDependencies(relationName, ruleConfig) { - if (!ruleConfig || typeof ruleConfig !== 'object') return; - const dependsOn = new Set(); - const dependsByLevel = { - never: new Set(), - always: new Set(), - requires: new Set(), - when: new Set(), - unless: new Set(), - ordinary: new Set() - }; - - const collect = (rule, targetSet) => { - if (!rule || typeof rule !== 'object') return; - if (rule.type === 'direct' && rule.relation) { - targetSet.add(rule.relation); - } - if (rule.type === 'tuple_to_userset') { - if (rule.tuplesetRelation) targetSet.add(rule.tuplesetRelation); - if (rule.computedRelation) targetSet.add(rule.computedRelation); - } - if (rule.type === 'parent' && rule.parentRelation) { - targetSet.add(rule.parentRelation); - } - if (rule.type === 'multi_hop' && rule.relation) { - targetSet.add(rule.relation); - } - if (rule.type === 'chain' && Array.isArray(rule.steps)) { - for (const step of rule.steps) { - if (typeof step === 'string') targetSet.add(step); - else if (step && typeof step.relation === 'string') targetSet.add(step.relation); - } - } - if (rule.type === 'relational_comparator') { - if (rule.left?.valueRelation) targetSet.add(rule.left.valueRelation); - if (rule.right?.valueRelation) targetSet.add(rule.right.valueRelation); - if (rule.left?.rule) collect(rule.left.rule, targetSet); - if (rule.right?.rule) collect(rule.right.rule, targetSet); - } - - const logicalKeys = ['union', 'intersection', 'exclusion', 'never', 'always', 'requires', 'when', 'unless']; - for (const key of logicalKeys) { - const node = rule[key]; - const ruleList = node?.rules || node?.union?.rules || node?.intersection?.rules; - if (Array.isArray(ruleList)) { - for (const child of ruleList) collect(child, targetSet); - } - if (node?.rule) collect(node.rule, targetSet); - } - }; - - const collectWithKeys = (rule, keys, targetSet) => { - if (!rule || typeof rule !== 'object') return; - for (const key of keys) { - const node = rule[key]; - const ruleList = node?.rules || node?.union?.rules || node?.intersection?.rules; - if (Array.isArray(ruleList)) { - for (const child of ruleList) collect(child, targetSet); - } - if (node?.rule) collect(node.rule, targetSet); - } - }; - - if (ruleConfig.type === 'logical') { - if (ruleConfig.never) collect(ruleConfig.never, dependsByLevel.never); - if (ruleConfig.always) collect(ruleConfig.always, dependsByLevel.always); - if (ruleConfig.requires) collect(ruleConfig.requires, dependsByLevel.requires); - if (ruleConfig.when) collect(ruleConfig.when, dependsByLevel.when); - if (ruleConfig.unless) collect(ruleConfig.unless, dependsByLevel.unless); - collectWithKeys(ruleConfig, ['union', 'intersection', 'exclusion'], dependsByLevel.ordinary); - } else { - collect(ruleConfig, dependsOn); - } - - for (const level of Object.keys(dependsByLevel)) { - for (const rel of dependsByLevel[level]) { - dependsOn.add(rel); - } - } - - const orderedDependsOn = Array.from(dependsOn); - if (orderedDependsOn.length > 0) { - ruleConfig.dependsOn = orderedDependsOn; - } - - if (Object.values(dependsByLevel).some(set => set.size > 0)) { - ruleConfig.dependsByLevel = { - never: Array.from(dependsByLevel.never), - always: Array.from(dependsByLevel.always), - requires: Array.from(dependsByLevel.requires), - when: Array.from(dependsByLevel.when), - unless: Array.from(dependsByLevel.unless), - ordinary: Array.from(dependsByLevel.ordinary) - }; - } - - if (orderedDependsOn.length > 0) { - for (const rel of orderedDependsOn) { - let entry = this.dependencyIndex.get(rel); - if (!entry) { - entry = { - all: new Set(), - byLevel: { - never: new Set(), - always: new Set(), - requires: new Set(), - when: new Set(), - unless: new Set(), - ordinary: new Set() - } - }; - this.dependencyIndex.set(rel, entry); - } - entry.all.add(relationName); - if (ruleConfig.dependsByLevel) { - for (const level of Object.keys(entry.byLevel)) { - if (ruleConfig.dependsByLevel[level]?.includes(rel)) { - entry.byLevel[level].add(relationName); - } - } - } - } - } - } - - getDependencyIndex() { - return this.dependencyIndex; - } - - /** - * Build rule configuration from evidence - * @param {EvidenceNode} evidence - Evidence to build config for - * @returns {Object|null} Rule configuration or null - */ - buildRuleConfig(evidence) { - if (!evidence.body || !evidence.body.statements) { - this.errors.push(`Evidence ${evidence.name} has no body`); - return null; - } - - const statements = evidence.body.statements; - - // Handle single statement evidence - if (statements.length === 1) { - return this.buildSingleStatementRule(statements[0]); - } - - // Handle multiple statements with logical operators - return this.buildLogicalRule(statements); - } - - /** - * Build rule configuration for a single statement - * @param {BaseNode} statement - Statement to build rule for - * @returns {Object|null} Rule configuration or null - */ - buildSingleStatementRule(statement) { - switch (statement.type) { - case 'DirectEvidence': - return this.buildDirectRule(statement); - case 'PatternMatch': - return this.buildPatternMatchRule(statement); - case 'DefeasibleLogic': - return this.buildDefeasibleRule(statement); - case 'Fusion': - return this.buildFusionRule(statement); - case 'PredicateCall': - return this.buildPredicateRule(statement); - case 'UnaryExpression': - return this.buildUnaryRule(statement); - case 'BinaryExpression': - // Top-level comparator — emit a relational_comparator rule. RF-24 closure. - return this.buildRuleFromExpressionNode(statement); - case 'Expression': - // Handle expressions that might be predicate calls - if (statement.type === 'PredicateCall') { - return this.buildPredicateRule(statement); - } - return this.buildRuleFromExpressionNode(statement); - default: - this.errors.push(`Unsupported statement type: ${statement.type}`); - return null; - } - } - - /** - * Build rule for unary expression (NOT) - * @param {Object} expression - Unary expression - * @returns {Object|null} Rule configuration or null - */ - buildUnaryRule(expression) { - if (expression.operator !== 'NOT') { - this.errors.push(`Unsupported unary operator: ${expression.operator}`); - return null; - } - - const innerRule = this.buildRuleFromExpression(expression.operand); - if (!innerRule) { - return null; - } - - // NOT x: evaluation will negate the inner rule's possibility (1 - poss) - return { - type: 'logical', - intersection: { - rules: [innerRule], - aggregator: 'min', - negate: true - } - }; - } - - /** - * Build logical rule configuration for multiple statements - * @param {BaseNode[]} statements - Statements to combine - * @returns {Object|null} Rule configuration or null - */ - buildLogicalRule(statements) { - const rules = []; - - statements.forEach(statement => { - const rule = this.buildSingleStatementRule(statement); - if (rule) { - rules.push(rule); - } - }); - - if (rules.length === 0) { - this.errors.push('No valid rules found in evidence body'); - return null; - } - - if (rules.length === 1) { - return rules[0]; - } - - // Combine rules with intersection (AND) logic — REBAC default. - // Use explicit fusion max { ... } in DSL for OR semantics. - return { - type: 'logical', - intersection: { - rules: rules, - aggregator: 'min' - } - }; - } - - /** - * Build direct rule configuration - * @param {DirectEvidenceNode} directEvidence - Direct evidence statement - * @returns {Object|null} Rule configuration or null - */ - buildDirectRule(directEvidence) { - if (!directEvidence.predicate) { - this.errors.push('Direct evidence must have a predicate'); - return null; - } - - const predicate = directEvidence.predicate; - const relation = predicate.name; - - return { - type: 'direct', - relation: relation, - reverse: false - }; - } - - /** - * Build pattern match rule configuration - * @param {PatternMatchNode} patternMatch - Pattern match statement - * @returns {Object|null} Rule configuration or null - */ - buildPatternMatchRule(patternMatch) { - if (!patternMatch.predicate) { - this.errors.push('Pattern match must have a predicate'); - return null; - } - - const predicate = patternMatch.predicate; - const relation = predicate.name; - - // Membership/hierarchy predicates map to TupleToUsersetRule / ParentRule - // regardless of body shape — those have priority over chain detection. - if (this.isMembershipPredicate(predicate)) { - return this.buildTupleToUsersetRule(patternMatch); - } - if (this.isHierarchyPredicate(predicate)) { - return this.buildParentRule(patternMatch); - } - - // Chain detection: ADR-000 ChainRule shape is "works_in(p, *d) { has_access(d, r) }". - // The outer PatternMatch has a Wildcard binding, and its body contains a single - // PredicateCall (no DefeasibleLogic wrapping, no nested PatternMatch). Treat that - // as a chain: two-hop traversal through the wildcard intermediate. RF-24 closure - // (parallel to RF-22/RF-23 — DSL→engine mapping gap surfaced by rigor coverage). - if (this._isChainPattern(patternMatch)) { - return this.buildChainRule(patternMatch); - } - - return this.buildMultiHopRule(patternMatch); - } - - /** - * Detect the ChainRule shape: a PatternMatch whose body contains exactly one - * PredicateCall and uses a Wildcard arg to bind the intermediate. The predicate - * name itself is NOT in the membership/hierarchy lists (those map to TUS/Parent). - */ - _isChainPattern(patternMatch) { - if (!patternMatch.body || !Array.isArray(patternMatch.body.statements)) return false; - const stmts = patternMatch.body.statements; - if (stmts.length !== 1) return false; - if (stmts[0].type !== 'PredicateCall') return false; - const predicate = patternMatch.predicate; - if (!predicate || !Array.isArray(predicate.args)) return false; - // Must use at least one Wildcard (*var) to bind the intermediate - return predicate.args.some(arg => arg && arg.type === 'Wildcard'); - } - - /** - * Build chain rule configuration (ADR-000 ChainRule). - * Compiles "works_in(p, *d) { has_access(d, doc) }" into - * { type: 'chain', steps: ['works_in', 'has_access'] } - * The intermediate wildcard binds the two predicates' arguments. - */ - buildChainRule(patternMatch) { - const steps = []; - steps.push(patternMatch.predicate.name); - - const inner = patternMatch.body.statements[0]; - if (inner && inner.type === 'PredicateCall' && inner.name) { - steps.push(inner.name); - } - - return { - type: 'chain', - steps, - aggregator: 'max', - collectValues: true - }; - } - - /** - * Build tuple-to-userset rule configuration - * @param {PatternMatchNode} patternMatch - Pattern match statement - * @returns {Object|null} Rule configuration or null - */ - buildTupleToUsersetRule(patternMatch) { - const predicate = patternMatch.predicate; - const relation = predicate.name; - - return { - type: 'tuple_to_userset', - tuplesetRelation: 'owner', // Default, could be inferred from context - computedRelation: relation, - reverse: false, - earlyExitThreshold: 0.95, - maxIntermediates: patternMatch.limit || 10 - }; - } - - /** - * Build parent rule configuration - * @param {PatternMatchNode} patternMatch - Pattern match statement - * @returns {Object|null} Rule configuration or null - */ - buildParentRule(patternMatch) { - const predicate = patternMatch.predicate; - const relation = predicate.name; - - return { - type: 'parent', - parentRelation: 'parent', // Default, could be inferred from context - relation: relation, - reverse: false, - aggregator: 'max' - }; - } - - /** - * Build multi-hop rule configuration - * @param {PatternMatchNode} patternMatch - Pattern match statement - * @returns {Object|null} Rule configuration or null - */ - buildMultiHopRule(patternMatch) { - const predicate = patternMatch.predicate; - const relation = predicate.name; - - return { - type: 'multi_hop', - relation: relation, - maxDepth: 3, - pathAggregation: 'max', - reverse: false, - fallbackToBasicPaths: true, - collectValues: false - }; - } - - /** - * Build defeasible rule configuration - * @param {DefeasibleLogicNode} defeasibleLogic - Defeasible logic statement - * @returns {Object|null} Rule configuration or null - */ - buildDefeasibleRule(defeasibleLogic) { - const logicType = defeasibleLogic.logicType; - - if (logicType === 'NEVER') { - return this.buildNeverRule(defeasibleLogic); - } else if (logicType === 'ALWAYS') { - return this.buildStrictRule(defeasibleLogic); - } else if (logicType === 'WHEN') { - return this.buildDefeasibleRuleWithDefeater(defeasibleLogic); - } else if (logicType === 'UNLESS') { - return this.buildDefeaterRule(defeasibleLogic); - } else if (logicType === 'REQUIRES') { - return this.buildRequirementRule(defeasibleLogic); - } - - this.errors.push(`Unsupported defeasible logic type: ${logicType}`); - return null; - } - - /** - * Build NEVER rule configuration (absolute denial) - * @param {DefeasibleLogicNode} defeasibleLogic - Defeasible logic statement - * @returns {Object|null} Rule configuration or null - */ - buildNeverRule(defeasibleLogic) { - const condition = this.buildRuleFromExpression(defeasibleLogic.condition); - - return { - type: 'logical', - never: { - union: { - rules: [condition], - aggregator: 'max' - } - } - }; - } - - /** - * Build strict rule configuration - * @param {DefeasibleLogicNode} defeasibleLogic - Defeasible logic statement - * @returns {Object|null} Rule configuration or null - */ - buildStrictRule(defeasibleLogic) { - const condition = this.buildRuleFromExpression(defeasibleLogic.condition); - - return { - type: 'logical', - always: { - direct: condition, - aggregator: 'min' - } - }; - } - - /** - * Build defeasible rule with defeater - * @param {DefeasibleLogicNode} defeasibleLogic - Defeasible logic statement - * @returns {Object|null} Rule configuration or null - */ - buildDefeasibleRuleWithDefeater(defeasibleLogic) { - const condition = this.buildRuleFromExpression(defeasibleLogic.condition); - const defeater = this.buildRuleFromExpression(defeasibleLogic.defeater); - - const rule = { - type: 'logical', - when: { - intersection: { - rules: [condition], - aggregator: 'min' - } - } - }; - - if (defeater) { - rule.unless = { - union: { - rules: [defeater], - aggregator: 'max' - } - }; - } - - return rule; - } - - /** - * Build defeater rule configuration - * @param {DefeasibleLogicNode} defeasibleLogic - Defeasible logic statement - * @returns {Object|null} Rule configuration or null - */ - buildDefeaterRule(defeasibleLogic) { - const condition = this.buildRuleFromExpression(defeasibleLogic.condition); - - return { - type: 'logical', - unless: { - union: { - rules: [condition], - aggregator: 'max' - } - } - }; - } - - /** - * Build requirement rule configuration - * @param {DefeasibleLogicNode} defeasibleLogic - Defeasible logic statement - * @returns {Object|null} Rule configuration or null - */ - buildRequirementRule(defeasibleLogic) { - const condition = this.buildRuleFromExpression(defeasibleLogic.condition); - - return { - type: 'logical', - requires: { - union: { - rules: [condition], - aggregator: 'min' - } - } - }; - } - - /** - * Build fusion rule configuration - * @param {FusionNode} fusion - Fusion statement - * @returns {Object|null} Rule configuration or null - */ - buildFusionRule(fusion) { - const rules = []; - - (fusion.expressions || fusion.evidence || []).forEach(evidence => { - const rule = this.buildRuleFromExpression(evidence); - if (rule) { - rules.push(rule); - } - }); - - if (rules.length === 0) { - this.errors.push('Fusion has no valid evidence'); - return null; - } - - if (fusion.weights && fusion.strategy !== 'custom') { - this.errors.push(`Fusion weights require custom strategy, got: ${fusion.strategy}`); - return null; - } - - if (fusion.strategy === 'custom') { - if (!fusion.weights || fusion.weights.length === 0) { - this.errors.push('Custom fusion requires weights'); - return null; - } - const total = fusion.weights.reduce((sum, w) => sum + w, 0); - if (Math.abs(total - 1.0) > 1e-6) { - this.errors.push('Custom fusion weights must sum to 1.0'); - return null; - } - } - - const union = { - rules: rules, - aggregator: fusion.strategy - }; - if (fusion.weights && fusion.weights.length > 0) { - union.owaWeights = fusion.weights; - } - - return { - type: 'logical', - union - }; - } - - /** - * Build rule from expression - * @param {BaseNode} expression - Expression to build rule from - * @returns {Object|null} Rule configuration or null - */ - buildRuleFromExpression(expression) { - if (!expression) { - return null; - } - - if (expression.type === 'Predicate') { - return this.buildDirectRuleFromPredicate(expression); - } else if (expression.type === 'Expression') { - return this.buildRuleFromExpressionNode(expression); - } else if (expression.type === 'PredicateCall') { - return this.buildPredicateRule(expression); - } else if (expression.type === 'UnaryExpression') { - return this.buildUnaryRule(expression); - } - - this.errors.push(`Unsupported expression type: ${expression.type}`); - return null; - } - - /** - * Build direct rule from predicate - * @param {PredicateNode} predicate - Predicate to build rule from - * @returns {Object|null} Rule configuration or null - */ - buildDirectRuleFromPredicate(predicate) { - const expanded = this._expandPredicate(predicate.name); - if (expanded) return expanded; - - return { - type: 'direct', - relation: predicate.name, - reverse: false - }; - } - - _expandPredicate(predicateName) { - const existingConfig = this.generatedRules.get(predicateName) || this.arbiter?.relationConfigs?.get(predicateName); - if (!existingConfig) return null; - if (!existingConfig.union && !existingConfig.intersection && !existingConfig.exclusion) return null; - - const logicalKey = existingConfig.union ? 'union' : existingConfig.intersection ? 'intersection' : 'exclusion'; - const subRules = Array.isArray(existingConfig[logicalKey]?.rules) - ? existingConfig[logicalKey].rules - : Array.isArray(existingConfig[logicalKey]) ? existingConfig[logicalKey] : []; - - if (subRules.length === 0) return null; - - const expandedRules = subRules.map(r => { - if (r && r.type === 'direct') return { type: 'direct', relation: r.relation, reverse: !!r.reverse }; - if (typeof r === 'string') return { type: 'direct', relation: r, reverse: false }; - return null; - }).filter(Boolean); - - if (expandedRules.length === 0) return null; - - return { - type: 'logical', - [logicalKey]: { - rules: expandedRules, - aggregator: existingConfig[logicalKey]?.aggregator || 'min' - }, - // Flag to tell the evaluator: this expanded sub-predicate is unary — - // use the subject as the object instead of inheriting the parent's object. - _subjectAsObject: true - }; - } - - /** - * Build rule from expression node - * @param {ExpressionNode} expression - Expression to build rule from - * @returns {Object|null} Rule configuration or null - */ - buildRuleFromExpressionNode(expression) { - if (expression.type === 'AttributeAccess') { - return this.buildAttributeRule(expression); - } else if (expression.type === 'PredicateCall') { - return this.buildPredicateRule(expression); - } else if (expression.type === 'BinaryExpression' && expression.operator === 'within') { - return this.buildWithinRule(expression); - } else if (expression.type === 'BinaryExpression' && this._isComparatorOperator(expression.operator)) { - // ADR-000 RelationalComparatorRule shape: "userRisk(u) <= riskLimit(r)". - // Route BinaryExpression with comparator operators here so the - // evaluator can run a fuzzy interval comparison instead of treating - // them as logical truth values. RF-24 closure. - return this.buildRelationalComparatorRule(expression); - } - - this.errors.push(`Unsupported expression type: ${expression.type}`); - return null; - } - - /** - * Detect comparator operators per ADR-000. These are the operators that map - * to RelationalComparatorRule (vs. the boolean operators like `&&`/`||` which - * keep going through LogicalOperators). - */ - _isComparatorOperator(operator) { - return operator === '>' || operator === '>=' || operator === '<' || - operator === '<=' || operator === '==' || operator === '!='; - } - - /** - * Build relational comparator rule configuration (ADR-000 RelationalComparatorRule). - * Compiles "personAge(p) >= docMinAge(d)" into - * { - * type: 'relational_comparator', - * left: { rule: , extractValue: true }, - * right: { rule: , extractValue: true }, - * comparator: '>=', - * marginOfSafety: 1.0, - * fallbackBehavior: 'deny', - * minRulePossibility: 0 - * } - */ - buildRelationalComparatorRule(binaryExpression) { - const comparator = binaryExpression.operator; - const left = this._buildComparatorOperand(binaryExpression.left); - const right = this._buildComparatorOperand(binaryExpression.right); - if (!left || !right) { - this.errors.push(`Comparator operands must resolve to predicate calls (operator=${comparator})`); - return null; - } - - return { - type: 'relational_comparator', - left, - right, - comparator, - marginOfSafety: 1.0, - fallbackBehavior: 'deny', - minRulePossibility: 0 - }; - } - - /** - * Wrap a BinaryExpression side into a relational_comparator operand. The - * operand's `rule` field is the original predicate call (preserving reference - * semantics so the inner rule's evaluator can resolve its values). `extractValue` - * tells the evaluator to read the relation's `value` field rather than its - * `possibility`, which is what `personAge(p)` / `docMinAge(d)` semantics require. - */ - _buildComparatorOperand(side) { - if (!side) return null; - if (side.type === 'PredicateCall') { - return { - rule: side, - extractValue: true, - evaluatorFrom: 'auto' - }; - } - if (side.type === 'AttributeAccess') { - // user.age — treat the attribute path as a "measure" reference - return { - rule: side, - extractValue: true, - evaluatorFrom: 'auto', - attributePath: side.getAttributePath ? side.getAttributePath() : null - }; - } - return null; - } - - /** - * Build attribute rule configuration - * @param {ExpressionNode} expression - Attribute expression - * @returns {Object|null} Rule configuration or null - */ - buildAttributeRule(expression) { - const attributePath = expression.getAttributePath(); - - return { - type: 'direct', - relation: attributePath, - reverse: false - }; - } - - /** - * Build function rule configuration - * @param {ExpressionNode} expression - Function expression - * @returns {Object|null} Rule configuration or null - */ - buildPredicateRule(expression) { - const predicateName = expression.name; - if (expression.challenge) { - return this.buildChallengeRule(expression, null); - } - - // Expand composite (logical) predicate references into their direct - // leaf components so the optimizer can flatten to a correct direct_list. - const expanded = this._expandPredicate(predicateName); - if (expanded) return expanded; - - return { - type: 'direct', - relation: predicateName, - reverse: false - }; - } - - buildWithinRule(expression) { - const left = expression.left; - const right = expression.right; - if (left && left.type === 'PredicateCall' && left.challenge) { - this.errors.push('within must be applied to a challenge proof field, e.g. !mfa(user).issued_at within 10m'); - return null; - } - if (left && left.type === 'AttributeAccess' && left.object?.type === 'PredicateCall' && left.object?.challenge) { - if (left.attribute !== 'issued_at' && left.attribute !== 'issuedAt') { - this.errors.push('only issued_at is supported for challenge recency checks'); - return null; - } - return this.buildChallengeRule(left.object, right); - } - this.errors.push('within operator currently only supported with challenge predicates'); - return null; - } - - buildChallengeRule(expression, duration) { - const predicateName = expression.name; - const subject = this._resolveChallengeSubject(expression.args || []); - const withinMs = duration ? this._durationToMs(duration) : null; - return { - type: 'challenge', - challenge: predicateName, - subject, - ...(withinMs !== null && { withinMs }) - }; - } - - _resolveChallengeSubject(args) { - if (!args || !args.length) return 'user'; - const first = args[0]; - if (first?.type === 'Variable') { - if (first.name === 'object') return 'object'; - if (first.name === 'session') return 'session'; - return 'user'; - } - return 'user'; - } - - _durationToMs(duration) { - if (!duration || duration.value === undefined) return null; - const raw = typeof duration.value === 'string' ? duration.value : String(duration.value); - const unit = duration.unit || raw.slice(-1); - const numeric = parseFloat(raw); - if (!Number.isFinite(numeric)) return null; - switch (unit) { - case 's': - return numeric * 1000; - case 'm': - return numeric * 60 * 1000; - case 'h': - return numeric * 60 * 60 * 1000; - case 'd': - return numeric * 24 * 60 * 60 * 1000; - case 'w': - return numeric * 7 * 24 * 60 * 60 * 1000; - default: - return null; - } - } - - /** - * Build measure rule configuration - * @param {MeasureNode} measure - Measure to build rule for - * @returns {Object|null} Rule configuration or null - */ - buildMeasureRuleConfig(measure) { - if (!measure.body) { - this.errors.push(`Measure ${measure.name} has no body`); - return null; - } - - // Measures typically generate computed rules - return { - type: 'computed', - relation: measure.name - }; - } - - /** - * Check if predicate is membership-based - * @param {PredicateNode} predicate - Predicate to check - * @returns {boolean} True if membership predicate - */ - isMembershipPredicate(predicate) { - const membershipPredicates = ['member', 'member_of', 'belongs_to', 'is_member']; - return membershipPredicates.includes(predicate.name.toLowerCase()); - } - - /** - * Check if predicate is hierarchy-based - * @param {PredicateNode} predicate - Predicate to check - * @returns {boolean} True if hierarchy predicate - */ - isHierarchyPredicate(predicate) { - const hierarchyPredicates = ['parent', 'parent_of', 'child', 'child_of', 'ancestor', 'descendant']; - return hierarchyPredicates.includes(predicate.name.toLowerCase()); - } - - /** - * Apply generated rules to arbiter - */ - applyRulesToArbiter() { - if (!this.arbiter || typeof this.arbiter.setRelationConfig !== 'function') { - // Skip applying rules if arbiter is not available or doesn't support setRelationConfig - return; - } - - this.generatedRules.forEach((config, relation) => { - try { - this.arbiter.setRelationConfig(relation, config); - } catch (error) { - this.errors.push(`Failed to set relation config for ${relation}: ${error.message}`); - } - }); - - if (typeof this.arbiter.registerDependencyIndex === 'function') { - this.arbiter.registerDependencyIndex(this.dependencyIndex); - } - } - - /** - * Get generated rules - * @returns {Map} Map of generated rules - */ - getGeneratedRules() { - return this.generatedRules; - } - - /** - * Get generation errors - * @returns {string[]} Array of error messages - */ - getErrors() { - return this.errors; - } -} diff --git a/src/ast/grammar/dsl.peggy b/src/ast/grammar/dsl.peggy deleted file mode 100644 index 8bf560a..0000000 --- a/src/ast/grammar/dsl.peggy +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Peggy Parser for the Evidence DSL - * - * This grammar defines a declarative language for authorization policies. - * It parses definitions, facts, measures, and evidence rules into a structured - * Abstract Syntax Tree (AST) represented by plain JavaScript objects. - * (Version 4: Corrected infinite loop check in String literal parsing) - */ -{ - // The location() function provides line/column info for error reporting. - // The text() function returns the matched text for a rule. - - // Helper function to build a left-associative binary expression tree. - function buildLeftAssoc(head, tail) { - return tail.reduce((result, element) => { - return { - type: "BinaryExpression", - operator: element[1], - left: result, - right: element[3], - location: location() - }; - }, head); - } -} - -// -- Grammar Entry Point -- -Program - = _ statements:(Statement _)* _ { - const allStatements = statements.map(s => s[0]); - return { - type: "Program", - body: allStatements, - definitions: allStatements.filter(s => s.type === "Definition"), - facts: allStatements.filter(s => s.type === "Fact"), - evidence: allStatements.filter(s => s.type === "Evidence"), - measures: allStatements.filter(s => s.type === "Measure"), - sources: allStatements.filter(s => s.type === "Source") - }; - } - -Statement - = Definition - / Source - / Fact - / Evidence - / Measure - -// -- Top-Level Statements -- - -Definition "A type definition" - = ("definition" / "type") __ name:Identifier __ "{" _ fields:(Field _)* "}" { - return { type: "Definition", name, fields: fields.map(f => f[0]) }; - } - -Field - = name:Identifier _ ":" _ fieldType:Type _ isArray:("[]")? _ behavior:Behavior? _ cache:CacheDirective? { - return { - type: "Field", - name, - fieldType, - isArray: !!isArray, - behavior: behavior || null, - cache: cache || null - }; - } - -Fact "A statement of fact (or relation in ADR-000)" - = ("fact" / "relation") __ star:"*"? name:Identifier _ "(" _ params:ParameterList? _ ")" _ behavior:BehaviorAnnotation? _ properties:(FactProperty _)* cache:CacheDirective? _ limit:Limit? { - return { - type: "Fact", - name, - params: params || [], - behavior: behavior || null, - properties: properties.map(p => p[0]), - cache: cache || null, - limit: limit || null, - injectable: !!star - }; - } - -Source "An injectable source (proof provider)" - = "source" __ star:"*"? name:Identifier _ "(" _ params:ParameterList? _ ")" _ provides:Provides? _ within:WithinClause? { - return { - type: "Source", - name, - params: params || [], - provides: provides || null, - injectable: !!star, - within: within || null - }; - } - -WithinClause "A freshness constraint on a source" - = "within" __ duration:Duration { return duration; } - -Evidence "An evidence rule" - = "evidence" __ star:"*"? name:Identifier _ "(" _ params:ParameterList? _ ")" _ limit:Limit? _ "{" _ body:EvidenceBody _ "}" _ provides:Provides? { - return { - type: "Evidence", - name, - params: params || [], - limit: limit || null, - body, - provides: provides || null, - challenge: !!star - }; - } - -Measure "A derived measurement or value" - = "measure" __ name:Identifier _ "(" _ params:ParameterList? _ ")" _ "{" _ body:MeasureBody _ "}" _ provides:Provides? { - return { - type: "Measure", - name, - params: params || [], - body, - provides: provides || null - }; - } - -// -- Evidence & Measure Internals -- - -EvidenceBody - = statements:(EvidenceStatement _)* { - return { type: "EvidenceBody", statements: statements.map(s => s[0]) }; - } - -EvidenceStatement - = DefeasibleLogic - / Fusion - / CollectionProcessing - / PatternMatch - / Expression - -MeasureBody - = statements:(MeasureStatement _)* returnStmt:ReturnStatement? { - return { - type: "MeasureBody", - statements: statements.map(s => s[0]), - returnStatement: returnStmt || null - }; - } - -MeasureStatement - = Fusion - / Aggregation - / PatternMatch - / Expression - -ReturnStatement - = "return" __ expression:Expression { - return { type: "ReturnStatement", expression }; - } - -// -- Complex Statement Types -- - -DefeasibleLogic - = type:("NEVER" / "ALWAYS" / "REQUIRES") __ condition:Expression { - return { type: "DefeasibleLogic", logicType: type, condition }; - } - / "WHEN" __ condition:Expression __ "UNLESS" __ defeater:Expression { - return { type: "DefeasibleLogic", logicType: "WHEN", condition, defeater }; - } - / "WHEN" __ condition:Expression { - return { type: "DefeasibleLogic", logicType: "WHEN", condition }; - } - -PatternMatch - = predicate:PatternPredicate _ binding:BindingClause? _ "{" _ body:EvidenceBody _ "}" _ limit:Limit? _ withClause:WithClause? { - return { - type: "PatternMatch", - predicate, - binding: binding || null, - limit: limit || null, - body, - withClause: withClause || null - }; - } - -CollectionProcessing - = measure:Expression _ "|" _ variable:Identifier _ "|" _ fusionStrategy:("fusion" __ strategy:Identifier)? _ "{" _ body:EvidenceBody _ "}" _ limit:Limit? { - return { - type: "CollectionProcessing", - measure, - variable, - fusion: fusionStrategy ? { strategy: fusionStrategy[1] } : null, - body, - limit: limit || null - }; - } - -PatternPredicate - = name:Identifier _ "(" _ args:PatternArgumentList? _ ")" { - return { type: "Predicate", name, args: args || [] }; - } - -PatternArgumentList - = head:PatternArgument tail:(_ "," _ arg:PatternArgument)* { - return [head, ...tail.map(t => t[3])]; - } - -PatternArgument - = "*" _ name:Identifier { return { type: "Wildcard", name }; } - / Expression - -BindingClause - = "|" _ name:Identifier _ "|" { return name; } - -WithClause - = "with" __ condition:Expression { return condition; } - -Fusion - = "fusion" __ strategy:Identifier __ "{" _ expressions:ExpressionList _ "}" { - return { type: "Fusion", strategy, expressions }; - } - -Aggregation - = "aggregate" __ "{" _ expressions:ExpressionList _ "}" _ using:Using? { - return { type: "Aggregation", expressions, using: using || null }; - } - -Using - = "USING" __ method:Identifier { return method; } - -// -- Type System & Parameters -- - -Type - = Identifier - -TypeName - = name:Identifier { return { type: "TypeName", name }; } - / literal:String { return { type: "TypeName", name: literal.value }; } - -ParameterList - = head:Parameter tail:(_ "," _ param:Parameter)* { - return [head, ...tail.map(t => t[3])]; - } - -Parameter - = name:Identifier _ ":" _ paramType:Type _ isArray:("[]")? { - return { type: "Parameter", name, paramType, isArray: !!isArray }; - } - -Provides - = "PROVIDES" __ providesType:Type { return providesType; } - -BehaviorAnnotation - = "BEHAVES" __ "AS" __ behavior:("edge" / "transitive" / "hierarchical" / "symmetrical_graph") { - return { type: "BehaviorAnnotation", behavior }; - } - -FactProperty - = "transitive" { return "transitive"; } - / "symmetrical" { return "symmetrical"; } - -Limit - = "limit" __ value:Integer { return value; } - -// -- Behaviors and Caching -- - -Behavior - = "BEHAVES" __ "{" _ b:(DecayBehavior / BlurBehavior / TTLBehavior) _ "}" { return b; } - -DecayBehavior - = "decaying" __ direction:("up" / "down" / "neutral" / "stable") __ period:("hourly" / "daily" / "weekly" / "monthly") { - return { type: "Behavior", behaviorType: "decay", direction, period }; - } - -BlurBehavior - = "blurring" __ mode:("fixed" / "adaptive" / "confidence") confidence:(__ ("confidence_90" / "confidence_95" / "confidence_99"))? { - return { type: "Behavior", behaviorType: "blur", mode, confidence: confidence ? confidence[1] : null }; - } - -TTLBehavior - = "ttl" __ duration:Duration { - return { type: "Behavior", behaviorType: "ttl", duration }; - } - -CacheDirective - = "CACHE" __ directive:("eager" / "lazy") { return directive; } - -// -- Expressions (with operator precedence) -- - -Expression - = LogicalOr - -LogicalOr - = head:LogicalAnd tail:(_ "||" _ right:LogicalAnd)* { return buildLeftAssoc(head, tail); } - -LogicalAnd - = head:Comparison tail:(_ "&&" _ right:Comparison)* { return buildLeftAssoc(head, tail); } - -Comparison - = head:TemporalComparison _ "is" __ typeName:TypeName { - return { type: "BinaryExpression", operator: "is", left: head, right: typeName }; - } - / head:TemporalComparison tail:(_ operator:("==" / "!=" / ">=" / "<=" / ">" / "<") _ right:TemporalComparison)* { return buildLeftAssoc(head, tail); } - -TemporalComparison - = head:Addition _ "within" __ right:Duration { - return { type: "BinaryExpression", operator: "within", left: head, right }; - } - / Addition - -Addition - = head:Multiplication tail:(_i operator:("+" / "-") _i right:Multiplication)* { return buildLeftAssoc(head, tail); } - -Multiplication - = head:Unary tail:(_i operator:("*" / "/") _i right:Unary)* { return buildLeftAssoc(head, tail); } - -Unary - = operator:("NOT" / "!") __ operand:Unary { return { type: "UnaryExpression", operator: "NOT", operand }; } - / Postfix - -Postfix - = primary:(AttributeAccess / PrimaryTerm) binding:BindingClause? { - if (binding) { - return { type: "BindingAccess", expression: primary, binding }; - } - return primary; - } - -AttributeAccess - = head:PrimaryTerm tail:(_ "." _ attr:Identifier)+ { - return tail.reduce((obj, part) => { - return { - type: "AttributeAccess", - object: obj, - attribute: part[3], // The Identifier is the 4th element (index 3) - location: location() - }; - }, head); - } - -PrimaryTerm "The non-recursive base for an expression chain" - = ChallengePredicate - / Literal - / PredicateCall - / Variable - / "(" _ expr:Expression _ ")" { return expr; } - -ChallengePredicate - = "*" name:Identifier _ "(" _ args:ArgumentList? _ ")" { - return { type: "PredicateCall", name, args: args || [], challenge: true }; - } - -PredicateCall - = name:Identifier "(" _ args:ArgumentList? _ ")" { - return { type: "PredicateCall", name, args: args || [] }; - } - -Variable - = name:Identifier { return { type: "Variable", name }; } - -ArgumentList - = head:Expression tail:(_ "," _ expr:Expression)* { - return [head, ...tail.map(t => t[3])]; - } - -ExpressionList - = head:Expression tail:(_ "," _ expr:Expression)* { - return [head, ...tail.map(t => t[3])]; - } - -// -- Literals -- - -Literal - = String / Float / Integer / Boolean / Duration - -String "A string literal" - = '"' chars:((!("\"" / "\\")) . / "\\" .)* '"' { - return { type: "Literal", value: JSON.parse(text()) }; - } - / "'" chars:((!("'" / "\\")) . / "\\" .)* "'" { - return { type: "Literal", value: JSON.parse("\"" + chars.map(c => c[0] === '\\' ? c[1] : c[1]).join('') + "\"") }; - } - -Float "A floating-point number" - = value:([0-9]+ "." [0-9]+) { return { type: "Literal", value: parseFloat(text()) }; } - -Integer "An integer" - = value:[0-9]+ { return { type: "Literal", value: parseInt(text(), 10) }; } - -Boolean "A boolean literal" - = value:("true" / "false") { return { type: "Literal", value: value === "true" }; } - -Duration "A time duration literal" - = value:([0-9]+ ("h" / "d" / "w" / "m")) { return { type: "Literal", value: text(), unit: text().slice(-1) }; } - - -// -- Core Tokens & Whitespace -- - -Identifier - = !Keyword name:$([a-zA-Z_][a-zA-Z0-9_]*) { return name; } - -Keyword - = ("definition" / "type" / "fact" / "relation" / "evidence" / "measure" / "BEHAVES" / "AS" / "CACHE" - / "decaying" / "blurring" / "ttl" / "transitive" / "symmetrical" / "hierarchical" / "symmetrical_graph" / "edge" / "limit" - / "PROVIDES" / "fusion" / "aggregate" / "USING" / "NEVER" / "ALWAYS" / "WHEN" / "UNLESS" - / "REQUIRES" / "with" / "true" / "false" / "NOT" / "within" / "return" / "is") !([a-zA-Z0-9_]) - -// _ = optional whitespace and comments -// __ = mandatory whitespace and comments -_ - = (WhiteSpace / Comment)* - -// Inline (single-line) optional whitespace — used around arithmetic -// operators so a `*` challenge-predicate on the next line is not -// absorbed as a multiplication tail. -_i - = [ \t]* -__ - = (WhiteSpace / Comment)+ - -WhiteSpace - = [ \t\r\n] - -Comment - = "//" [^\r\n]* - / "/*" (!"*/" .)* "*/" diff --git a/src/ast/grammar/expression.peggy b/src/ast/grammar/expression.peggy deleted file mode 100644 index 816987b..0000000 --- a/src/ast/grammar/expression.peggy +++ /dev/null @@ -1,167 +0,0 @@ -// Inline Expression Grammar for Permission Checking -// -// This grammar parses inline DSL expressions used for permission checks. -// It supports predicate calls, OWA Fusion blocks (exclusive composition), -// challenge predicates (* prefix for out-of-band), and defeasible logic (UNLESS). -// AND/OR operators removed — OWA Fusion is the only composition mechanism. -// -// Usage: npx peggy -o src/ast/parser/ExpressionParser.js src/ast/grammar/expression.peggy - -{ - // Helper functions - function makeVariable(name, path) { - return { type: 'Variable', name, path: path || [] }; - } - - function makePredicate(name, args) { - return { type: 'Predicate', name, args: args || [] }; - } - - function makeChallengePredicate(name, args) { - return { type: 'Predicate', name, args: args || [], challenge: true }; - } - - function makeFusion(expressions, aggregator) { - return { type: 'Fusion', aggregator, expressions }; - } - - function makeDefeasible(primary, exception) { - return { type: 'Defeasible', primary, exception }; - } -} - -// Entry point -Expression - = _ expr:DefeasibleExpr _ { return expr; } - -// Defeasible logic: primary UNLESS exception -DefeasibleExpr - = primary:PrimaryExpr _ "UNLESS" _ exception:PredicateCall { - return makeDefeasible(primary, exception); - } - / PrimaryExpr - -// Primary expressions: Fusion blocks or predicate calls -PrimaryExpr - = FusionBlock - / ChallengePredicate - / PredicateCall - -// OWA Fusion block: FUSION { expr1 expr2 ... } -FusionBlock - = "FUSION" _ aggregator:AggregatorKeyword _ "{" _ expressions:ExpressionList _ "}" { - return makeFusion(expressions, aggregator); - } - -// Aggregator keywords (subset of ADR-000 DSL v2 aggregators) -AggregatorKeyword - = "max" / "min" / "majority" / "average" / "sum" / "sum_unbounded" - / "median" / "optimistic" / "pessimistic" / "top2" / "top3" / "priority" - -// List of expressions (whitespace-separated) -ExpressionList - = head:Expression tail:(_ Expression)* { - const exprs = [head]; - for (const t of tail) { - exprs.push(t[1]); - } - return exprs; - } - -// Challenge predicate (* prefixed): *name(arg1, arg2, ...) -ChallengePredicate - = "*" name:Identifier _ "(" _ args:ArgumentList? _ ")" { - return makeChallengePredicate(name, args || []); - } - -// Predicate call: name(arg1, arg2, ...) -PredicateCall - = name:Identifier _ "(" _ args:ArgumentList? _ ")" { - return makePredicate(name, args || []); - } - -// Comma-separated arguments -ArgumentList - = head:Argument tail:(_ "," _ Argument)* { - const args = [head]; - for (const t of tail) { - args.push(t[3]); - } - return args; - } - -// Argument types -// Order matters: try VariableBinding first (starts with :), -// then Literal (strings/numbers), then TypedReference (which looks like an identifier) -Argument - = VariableBinding - / Literal - / TypedReference - -// Variable binding: :name or :name.path.subpath -VariableBinding - = ":" name:Identifier path:("." Identifier)* { - return makeVariable(name, path.map(p => p[1])); - } - -// Typed reference: Type::path.subpath (e.g., document::params.id) -TypedReference - = refType:Identifier "::" path:Path { - return { type: 'Reference', refType: refType, path: path }; - } - -// Path for typed references -Path - = head:Identifier tail:("." Identifier)* { - const parts = [head]; - for (const t of tail) { - parts.push(t[1]); - } - return parts; - } - -// Literals -Literal - = StringLiteral - / NumberLiteral - -// String literals (single or double quoted) -StringLiteral - = '"' chars:([^"\\] / EscapeSequence)* '"' { - return { type: 'Literal', value: chars.join(''), dataType: 'string' }; - } - / "'" chars:([^'\\] / EscapeSequence)* "'" { - return { type: 'Literal', value: chars.join(''), dataType: 'string' }; - } - -// Escape sequences -EscapeSequence - = "\\" char:["'\\nrt] { - const escapes = { '"': '"', "'": "'", '\\': '\\', 'n': '\n', 'r': '\r', 't': '\t' }; - return escapes[char] || char; - } - -// Number literals -NumberLiteral - = digits:([0-9]+) { - return { type: 'Literal', value: parseInt(digits.join(''), 10), dataType: 'number' }; - } - -// Identifiers (support hyphens like doc-123, user-456) -Identifier - = first:[a-zA-Z_] rest:[a-zA-Z0-9_-]* { - return first + rest.join(''); - } - -// Whitespace and comments -_ "whitespace" - = (WS / LineComment / BlockComment)* - -WS - = [ \t\n\r]+ - -LineComment - = "//" [^\n]* - -BlockComment - = "/*" (!"*/" .)* "*/" diff --git a/src/ast/index.js b/src/ast/index.js deleted file mode 100644 index 5bc0568..0000000 --- a/src/ast/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * AST Module - Main export file - * Provides access to all AST functionality for DSL compilation - */ - -// Core AST components -export { DSLCompiler } from './DSLCompiler.js'; - -// Parser -export { PeggyDSLParser } from './parser/PeggyDSLParser.js'; - -// Generator -export { RuleGenerator } from './generator/RuleGenerator.js'; - -// Validation -export { validateDslText } from './validation/DSLValidation.js'; - -// All AST nodes -export * from './nodes/index.js'; - -// Re-export for convenience -export { DSLCompiler as default } from './DSLCompiler.js'; diff --git a/src/ast/interpreter/BuiltInFunctions.js b/src/ast/interpreter/BuiltInFunctions.js deleted file mode 100644 index 39c5118..0000000 --- a/src/ast/interpreter/BuiltInFunctions.js +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Built-in DSL Functions - * - * Native functions for use in DSL expressions - * Includes IP operations, time functions, string utilities - */ - -// Use optimized fast versions for hot paths -import { - isIpInCidrFast, - isPrivateIpFast, - ipToIntFast, - isIPv4Fast -} from '../../utils/ip-utils-fast.js'; -import { - isIPv6, - isLoopbackIp, - ipEquals, - getIpVersion -} from '../../utils/ip-utils.js'; - -/** - * Registry of built-in functions - */ -export const BUILT_IN_FUNCTIONS = { - // IP Address Functions - Using optimized fast versions - ip_in_cidr: { - params: ['ip', 'cidr'], - evaluate: (ip, cidr) => { - if (!ip || !cidr) return false; - return isIpInCidrFast(String(ip), String(cidr)); - } - }, - - ip_equals: { - params: ['ip1', 'ip2'], - evaluate: (ip1, ip2) => { - return ipEquals(String(ip1), String(ip2)); - } - }, - - ip_version: { - params: ['ip'], - evaluate: (ip) => { - return getIpVersion(String(ip)); - } - }, - - ip_is_private: { - params: ['ip'], - evaluate: (ip) => { - if (!ip) return false; - return isPrivateIpFast(String(ip)); - } - }, - - ip_is_loopback: { - params: ['ip'], - evaluate: (ip) => { - if (!ip) return false; - // Fast check: 127.x.x.x - return ipToIntFast(String(ip)) >>> 24 === 127; - } - }, - - ip_is_v4: { - params: ['ip'], - evaluate: (ip) => { - if (!ip) return false; - return isIPv4Fast(String(ip)); - } - }, - - ip_is_v6: { - params: ['ip'], - evaluate: (ip) => { - if (!ip) return false; - return isIPv6(String(ip)); - } - }, - - // Time Functions - hour_of_day: { - params: ['timestamp'], - evaluate: (timestamp) => { - const ts = typeof timestamp === 'number' ? timestamp : Date.now(); - return new Date(ts).getHours(); - } - }, - - day_of_week: { - params: ['timestamp'], - evaluate: (timestamp) => { - const ts = typeof timestamp === 'number' ? timestamp : Date.now(); - return new Date(ts).getDay(); // 0 = Sunday - } - }, - - // String Functions - contains: { - params: ['string', 'substring'], - evaluate: (str, substr) => { - if (!str || !substr) return false; - return String(str).includes(String(substr)); - } - }, - - starts_with: { - params: ['string', 'prefix'], - evaluate: (str, prefix) => { - if (!str || !prefix) return false; - return String(str).startsWith(String(prefix)); - } - }, - - ends_with: { - params: ['string', 'suffix'], - evaluate: (str, suffix) => { - if (!str || !suffix) return false; - return String(str).endsWith(String(suffix)); - } - }, - - // Comparison Functions - equals: { - params: ['a', 'b'], - evaluate: (a, b) => a === b - }, - - greater_than: { - params: ['a', 'b'], - evaluate: (a, b) => a > b - }, - - less_than: { - params: ['a', 'b'], - evaluate: (a, b) => a < b - }, - - in_range: { - params: ['value', 'min', 'max'], - evaluate: (value, min, max) => value >= min && value <= max - } -}; - -/** - * Check if a function name is a built-in - */ -export function isBuiltInFunction(name) { - return name in BUILT_IN_FUNCTIONS; -} - -/** - * Evaluate a built-in function - */ -export function evaluateBuiltIn(name, args) { - const func = BUILT_IN_FUNCTIONS[name]; - if (!func) { - throw new Error(`Unknown built-in function: ${name}`); - } - - if (args.length !== func.params.length) { - throw new Error( - `Function ${name} expects ${func.params.length} arguments, got ${args.length}` - ); - } - - return func.evaluate(...args); -} - -/** - * Get function signature - */ -export function getFunctionSignature(name) { - const func = BUILT_IN_FUNCTIONS[name]; - if (!func) return null; - - return { - name, - params: func.params - }; -} diff --git a/src/ast/interpreter/ExpressionInterpreter.js b/src/ast/interpreter/ExpressionInterpreter.js deleted file mode 100644 index 8581bda..0000000 --- a/src/ast/interpreter/ExpressionInterpreter.js +++ /dev/null @@ -1,323 +0,0 @@ -/** - * Expression Interpreter - * - * Interprets inline DSL expressions by evaluating them against existing - * compiled DSL rules in the graph. No temporary rules are created. - */ - -import { PredicateResolver } from './PredicateResolver.js'; - -export class ExpressionInterpreter { - constructor(context, options = {}) { - this.context = context; - this.graphStores = context.graphStores; - this.resolver = new PredicateResolver(context); - this.customBuiltIns = options.customBuiltIns || {}; - } - - /** - * Interpret an expression AST against the graph - * - * @param {Object} ast - Parsed expression AST - * @param {Object} bindings - Variable bindings - * @returns {Object} Interpretation result - */ - async interpret(ast, bindings) { - switch (ast.type) { - case 'Fusion': - return this.interpretFusion(ast, bindings); - case 'Or': - return this.interpretOr(ast, bindings); - case 'And': - return this.interpretAnd(ast, bindings); - case 'Not': - return this.interpretNot(ast, bindings); - case 'Defeasible': - return this.interpretDefeasible(ast, bindings); - case 'Predicate': - return this.interpretPredicate(ast, bindings); - default: - throw new Error(`Unknown AST node type: ${ast.type}`); - } - } - - /** - * Interpret FUSION block - ALL expressions must be true - * Uses OWA semantics: minimum possibility across all expressions - */ - async interpretFusion(ast, bindings) { - const results = await Promise.all( - ast.expressions.map(expr => this.interpret(expr, bindings)) - ); - - const allAllowed = results.every(r => r.allowed); - const minPossibility = results.length > 0 - ? Math.min(...results.map(r => r.possibility || 0)) - : 0; - - return { - allowed: allAllowed, - possibility: minPossibility, - type: 'Fusion', - details: results - }; - } - - /** - * Interpret OR - ANY expression can be true (short-circuited) - */ - async interpretOr(ast, bindings) { - for (const operand of ast.operands) { - const result = await this.interpret(operand, bindings); - if (result.allowed) { - return { - allowed: true, - possibility: result.possibility, - type: 'Or', - satisfiedBy: operand - }; - } - } - - return { - allowed: false, - possibility: 0, - type: 'Or' - }; - } - - /** - * Interpret AND - ALL expressions must be true - */ - async interpretAnd(ast, bindings) { - const results = []; - let minPossibility = 1; - - for (const operand of ast.operands) { - const result = await this.interpret(operand, bindings); - results.push(result); - minPossibility = Math.min(minPossibility, result.possibility || 0); - - if (!result.allowed) { - return { - allowed: false, - possibility: 0, - type: 'And', - failedAt: operand, - details: results - }; - } - } - - return { - allowed: true, - possibility: minPossibility, - type: 'And', - details: results - }; - } - - /** - * Interpret NOT - negate the operand result - */ - async interpretNot(ast, bindings) { - const result = await this.interpret(ast.operand, bindings); - - return { - allowed: !result.allowed, - possibility: result.allowed ? 0 : 1, - type: 'Not', - inner: result - }; - } - - /** - * Interpret Defeasible - primary UNLESS exception - * If exception is true, primary is defeated - */ - async interpretDefeasible(ast, bindings) { - // Check exception first (short-circuit if possible) - const exceptionResult = await this.interpret(ast.exception, bindings); - - if (exceptionResult.allowed) { - return { - allowed: false, - possibility: 0, - type: 'Defeasible', - reason: 'Defeated by exception', - defeatedBy: exceptionResult - }; - } - - // Exception is false, evaluate primary - const primaryResult = await this.interpret(ast.primary, bindings); - - return { - ...primaryResult, - type: 'Defeasible', - primary: primaryResult, - exception: exceptionResult - }; - } - - /** - * Interpret Predicate - call existing DSL rule via graph.check() - * OR evaluate built-in function - * - * This is where we use the ALREADY COMPILED DSL rules. - * We do NOT create temporary rules. - */ - async interpretPredicate(ast, bindings) { - // Check for built-in functions first (ip_in_cidr, etc.) - const { isBuiltInFunction, evaluateBuiltIn } = await import('./BuiltInFunctions.js'); - const resolvedArgs = ast.args.map(arg => this.resolveArgument(arg, bindings)); - - // Check custom built-ins first (e.g., PriceOps predicates) - if (this.customBuiltIns[ast.name]) { - const result = await this.customBuiltIns[ast.name](...resolvedArgs); - return { - allowed: result === true || result === 1, - possibility: result === true || result === 1 ? 1 : 0, - type: 'BuiltInFunction', - function: ast.name, - args: resolvedArgs, - result - }; - } - - if (isBuiltInFunction(ast.name)) { - const result = evaluateBuiltIn(ast.name, resolvedArgs); - - return { - allowed: result === true || result === 1, - possibility: result === true || result === 1 ? 1 : 0, - type: 'BuiltInFunction', - function: ast.name, - args: resolvedArgs, - result - }; - } - - // Resolve predicate to existing rule - const rule = this.resolver.resolve(ast.name); - if (!rule) { - throw new Error(`Unknown predicate: ${ast.name} - must be defined in compiled DSL`); - } - - // Extract subject (user) and optional object - const subject = resolvedArgs[0]; // First arg is always the subject - // For single-argument predicates, use subject as object to avoid "missing_node" errors - const object = resolvedArgs[1] || subject; // Second arg is optional object - - // Get the appropriate graph store - const graphStore = this.context.getGraphStore - ? this.context.getGraphStore(rule.scope, { - tenantId: bindings.tenant, - applicationId: bindings.applicationId - }) - : this.graphStores[rule.scope]; - if (!graphStore) { - throw new Error(`Graph store not found for scope: ${rule.scope}`); - } - - // Execute check using EXISTING compiled rule - // The graphStore.check() will use the pre-compiled DSL rule config - const checkOptions = {}; - if (bindings.partialGraph) { - checkOptions.partialGraph = bindings.partialGraph; - } - - const result = graphStore.check(subject, ast.name, object, checkOptions); - - return { - allowed: result?.allowed || result?.possibility === 1, - possibility: result?.possibility || 0, - type: 'Predicate', - predicate: ast.name, - scope: rule.scope, - subject, - object, - rawResult: result - }; - } - - /** - * Resolve an argument to its actual value - */ - resolveArgument(arg, bindings) { - switch (arg.type) { - case 'Variable': - return this.resolveVariable(arg, bindings); - case 'Reference': - return this.resolveReference(arg, bindings); - case 'Literal': - return arg.value; - default: - throw new Error(`Unknown argument type: ${arg.type}`); - } - } - - /** - * Resolve a variable binding - * :user -> bindings.user - * :params.id -> bindings.params.id - */ - resolveVariable(variable, bindings) { - let value = bindings[variable.name]; - - // Handle nested paths: :params.id - if (variable.path && variable.path.length > 0) { - for (const key of variable.path) { - if (value === undefined || value === null) { - return undefined; - } - value = value[key]; - } - } - - return value; - } - - /** - * Resolve a typed reference - * document::params.id -> bindings.params.id with type info - */ - resolveReference(ref, bindings) { - // Typed references like document::params.id - // The type (document) is metadata, the value comes from the path - let value = bindings; - - for (const key of ref.path) { - if (value === undefined || value === null) { - return undefined; - } - value = value[key]; - } - - return value; - } -} - -/** - * Utility to collect all predicates from an AST - * Used for validation before interpretation - */ -export function collectPredicates(ast, predicates = []) { - if (ast.type === 'Predicate') { - predicates.push(ast); - } - - // Recursively collect from child nodes - const childKeys = ['expressions', 'operands', 'operand', 'primary', 'exception', 'inner']; - for (const key of childKeys) { - if (ast[key]) { - if (Array.isArray(ast[key])) { - ast[key].forEach(child => collectPredicates(child, predicates)); - } else { - collectPredicates(ast[key], predicates); - } - } - } - - return predicates; -} diff --git a/src/ast/interpreter/PredicateResolver.js b/src/ast/interpreter/PredicateResolver.js deleted file mode 100644 index c1f74d7..0000000 --- a/src/ast/interpreter/PredicateResolver.js +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Predicate Resolver - * - * Maps predicate names to existing compiled DSL rules across all graph scopes. - * Does NOT create new rules - only looks up existing ones. - */ - -export class PredicateResolver { - constructor(context) { - this.context = context; - this.graphStores = context.graphStores || {}; - this.cache = new Map(); - } - - /** - * Resolve a predicate name to its DSL rule - * - * @param {string} predicateName - Name of the predicate - * @returns {Object|null} Rule info or null if not found - */ - resolve(predicateName) { - // Check cache first - if (this.cache.has(predicateName)) { - return this.cache.get(predicateName); - } - - // Look up in all graph scopes - const rule = this.findRule(predicateName); - - if (rule) { - this.cache.set(predicateName, rule); - } - - return rule; - } - - /** - * Find a rule across all graph scopes - * Prefers logical rules over direct rules for evidence predicates - */ - findRule(predicateName) { - const scopes = [ - 'tenantExternal', - 'tenantInternal', - 'rootExternal', - 'rootInternal', - 'masterExternal', - 'masterInternal' - ]; - - let directRule = null; - let directScope = null; - - for (const scopeName of scopes) { - const graphStore = this.graphStores[scopeName]; - if (!graphStore) { - continue; - } - - // Handle both: Arbiter directly (has .check()) or wrapper with .arbiter - const arbiter = graphStore.arbiter || graphStore; - const config = arbiter.relationConfigs?.get(predicateName); - - if (config) { - // Prefer logical rules (intersection/union) over direct rules - // This ensures evidence rules work correctly across all scopes - if (config.type === 'intersection' || config.type === 'union' || config.type === 'logical') { - return { - name: predicateName, - scope: scopeName, - config: config, - arity: this.inferArity(config) - }; - } - - // Remember the first direct rule as fallback - if (!directRule && config.type === 'direct') { - directRule = config; - directScope = scopeName; - } - } - } - - // Return direct rule if no logical rule found - if (directRule) { - return { - name: predicateName, - scope: directScope, - config: directRule, - arity: this.inferArity(directRule) - }; - } - - return null; - } - - /** - * Infer the arity (parameter count) from rule config - */ - inferArity(config) { - // Most DSL evidence rules have 1 or 2 parameters: - // - 1 param: just the subject (user) - // - 2 params: subject (user) + object - - if (config.arity) { - return config.arity; - } - - // Default to checking if it's a relation that typically needs an object - // This is a heuristic - in practice, the DSL defines this explicitly - if (config.type === 'tuple_to_userset' || config.type === 'direct') { - return 2; // Likely needs subject + object - } - - return 1; // Default to 1 param - } - - /** - * Check if a predicate exists without full resolution - */ - exists(predicateName) { - return this.resolve(predicateName) !== null; - } - - /** - * Get all available predicates across all scopes - */ - getAllPredicates() { - const predicates = []; - const scopes = [ - 'tenantExternal', - 'tenantInternal', - 'rootExternal', - 'rootInternal', - 'masterExternal', - 'masterInternal' - ]; - - for (const scopeName of scopes) { - const graphStore = this.graphStores[scopeName]; - if (!graphStore) { - continue; - } - - // Handle both: Arbiter directly (has .check()) or wrapper with .arbiter - const arbiter = graphStore.arbiter || graphStore; - if (arbiter.relationConfigs) { - for (const [name, config] of arbiter.relationConfigs) { - predicates.push({ - name, - scope: scopeName, - arity: this.inferArity(config) - }); - } - } - } - - return predicates; - } - - /** - * Clear the cache (useful for testing or when rules change) - */ - clearCache() { - this.cache.clear(); - } -} diff --git a/src/ast/nodes/AggregationNode.js b/src/ast/nodes/AggregationNode.js deleted file mode 100644 index e44a958..0000000 --- a/src/ast/nodes/AggregationNode.js +++ /dev/null @@ -1,162 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for aggregation expressions - * Represents: aggregate { ... } USING majority - */ -export class AggregationNode extends BaseNode { - constructor(location = null) { - super('Aggregation', location); - this.expressions = []; // Array of expressions to aggregate - this.method = null; // Aggregation method ('majority', 'max', 'min', 'sum', 'avg') - this.weights = null; // Optional weights array - } - - /** - * Add an expression to this aggregation - * @param {ExpressionNode} expression - Expression to add - */ - addExpression(expression) { - this.expressions.push(expression); - this.addChild(expression); - } - - /** - * Set the aggregation method - * @param {string} method - Aggregation method - */ - setMethod(method) { - this.method = method; - } - - /** - * Set weights for this aggregation - * @param {number[]} weights - Weights array - */ - setWeights(weights) { - this.weights = weights; - } - - /** - * Get all expressions - * @returns {ExpressionNode[]} Expressions to aggregate - */ - getExpressions() { - return this.expressions; - } - - /** - * Get the aggregation method - * @returns {string|null} Aggregation method or null - */ - getMethod() { - return this.method; - } - - /** - * Get the weights for this aggregation - * @returns {number[]|null} Weights or null - */ - getWeights() { - return this.weights; - } - - /** - * Check if this aggregation has weights - * @returns {boolean} True if has weights - */ - hasWeights() { - return this.weights !== null && this.weights.length > 0; - } - - /** - * Check if this is a majority aggregation - * @returns {boolean} True if majority - */ - isMajority() { - return this.method === 'majority'; - } - - /** - * Check if this is a max aggregation - * @returns {boolean} True if max - */ - isMax() { - return this.method === 'max'; - } - - /** - * Check if this is a min aggregation - * @returns {boolean} True if min - */ - isMin() { - return this.method === 'min'; - } - - /** - * Check if this is a sum aggregation - * @returns {boolean} True if sum - */ - isSum() { - return this.method === 'sum'; - } - - /** - * Check if this is an average aggregation - * @returns {boolean} True if average - */ - isAverage() { - return this.method === 'avg'; - } - - /** - * Get the number of expressions - * @returns {number} Number of expressions - */ - getExpressionCount() { - return this.expressions.length; - } - - /** - * Validate the aggregation - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate method - const validMethods = ['majority', 'max', 'min', 'sum', 'avg', 'count']; - if (!this.method || !validMethods.includes(this.method)) { - errors.push(`Invalid aggregation method: ${this.method}`); - } - - // Validate expressions - if (this.expressions.length === 0) { - errors.push('Aggregation must have at least one expression'); - } - - // Validate each expression - this.expressions.forEach((expr, index) => { - const exprErrors = expr.validate ? expr.validate() : []; - errors.push(...exprErrors.map(err => `Expression ${index + 1}: ${err}`)); - }); - - // Validate weights - if (this.weights !== null) { - if (!Array.isArray(this.weights)) { - errors.push('Weights must be an array'); - } else if (this.weights.length !== this.expressions.length) { - errors.push('Weights array length must match expression count'); - } else if (this.weights.some(w => typeof w !== 'number' || w < 0)) { - errors.push('All weights must be non-negative numbers'); - } - } - - return errors; - } - - toString() { - const weightsStr = this.hasWeights() ? ` weights[${this.weights.length}]` : ''; - return `Aggregation(${this.method}, ${this.expressions.length} expressions${weightsStr})`; - } -} diff --git a/src/ast/nodes/BaseNode.js b/src/ast/nodes/BaseNode.js deleted file mode 100644 index d3be2e5..0000000 --- a/src/ast/nodes/BaseNode.js +++ /dev/null @@ -1,157 +0,0 @@ -/** - * Base AST Node class for all DSL AST nodes - * Provides common functionality for all AST nodes - */ -export class BaseNode { - constructor(type, location = null) { - this.type = type; - this.location = location; // { start, end, line, column } - this.parent = null; - this.children = []; - } - - /** - * Add a child node to this node - * @param {BaseNode} child - Child node to add - */ - addChild(child) { - if (child) { - child.parent = this; - this.children.push(child); - } - return this; - } - - /** - * Add multiple child nodes - * @param {BaseNode[]} children - Array of child nodes - */ - addChildren(children) { - children.forEach(child => this.addChild(child)); - return this; - } - - /** - * Get all children of a specific type - * @param {string} type - Node type to filter by - * @returns {BaseNode[]} Filtered children - */ - getChildrenOfType(type) { - return this.children.filter(child => child.type === type); - } - - /** - * Find the first child of a specific type - * @param {string} type - Node type to find - * @returns {BaseNode|null} First matching child or null - */ - getChildOfType(type) { - return this.children.find(child => child.type === type) || null; - } - - /** - * Get all descendants of a specific type - * @param {string} type - Node type to find - * @returns {BaseNode[]} All matching descendants - */ - getDescendantsOfType(type) { - const results = []; - this.children.forEach(child => { - if (child.type === type) { - results.push(child); - } - results.push(...child.getDescendantsOfType(type)); - }); - return results; - } - - /** - * Accept a visitor (visitor pattern) - * @param {Object} visitor - Visitor object with visit methods - * @returns {*} Result of visitor.visit{NodeType}(this) - */ - accept(visitor) { - const methodName = `visit${this.type}`; - if (visitor[methodName]) { - return visitor[methodName](this); - } - if (visitor.visit) { - return visitor.visit(this); - } - return null; - } - - /** - * Get a string representation of this node - * @returns {string} String representation - */ - toString() { - return `${this.type}(${this.children.length} children)`; - } - - /** - * Get a detailed string representation for debugging - * @returns {string} Detailed string representation - */ - toDebugString() { - const childrenStr = this.children.map(child => - child.toDebugString ? child.toDebugString() : child.toString() - ).join(', '); - return `${this.type}(${childrenStr})`; - } - - /** - * Clone this node and all its children - * @returns {BaseNode} Cloned node - */ - clone() { - const cloned = new this.constructor(); - cloned.type = this.type; - cloned.location = this.location ? { ...this.location } : null; - cloned.children = this.children.map(child => child.clone()); - cloned.children.forEach(child => child.parent = cloned); - return cloned; - } - - /** - * Get the root node of the AST - * @returns {BaseNode} Root node - */ - getRoot() { - let current = this; - while (current.parent) { - current = current.parent; - } - return current; - } - - /** - * Get the depth of this node in the AST - * @returns {number} Depth from root - */ - getDepth() { - let depth = 0; - let current = this.parent; - while (current) { - depth++; - current = current.parent; - } - return depth; - } - - /** - * Check if this node is a descendant of another node - * @param {BaseNode} ancestor - Potential ancestor node - * @returns {boolean} True if ancestor is an ancestor of this node - */ - isDescendantOf(ancestor) { - let current = this.parent; - while (current) { - if (current === ancestor) { - return true; - } - current = current.parent; - } - return false; - } -} diff --git a/src/ast/nodes/BehaviorNode.js b/src/ast/nodes/BehaviorNode.js deleted file mode 100644 index 3e25127..0000000 --- a/src/ast/nodes/BehaviorNode.js +++ /dev/null @@ -1,151 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for field behaviors (decay, blur, ttl) - * Represents: BEHAVES { decaying down hourly } - */ -export class BehaviorNode extends BaseNode { - constructor(type, location = null) { - super('Behavior', location); - this.type = type; // 'decay', 'blur', 'ttl' - this.parameters = new Map(); - } - - /** - * Set a parameter for this behavior - * @param {string} name - Parameter name - * @param {*} value - Parameter value - */ - setParameter(name, value) { - this.parameters.set(name, value); - } - - /** - * Get a parameter value - * @param {string} name - Parameter name - * @returns {*} Parameter value or null - */ - getParameter(name) { - return this.parameters.get(name) || null; - } - - /** - * Check if this is a decay behavior - * @returns {boolean} True if decay behavior - */ - isDecay() { - return this.type === 'decay'; - } - - /** - * Check if this is a blur behavior - * @returns {boolean} True if blur behavior - */ - isBlur() { - return this.type === 'blur'; - } - - /** - * Check if this is a TTL behavior - * @returns {boolean} True if TTL behavior - */ - isTTL() { - return this.type === 'ttl'; - } - - /** - * For decay behaviors, get the direction - * @returns {string|null} Decay direction or null - */ - getDecayDirection() { - return this.getParameter('direction'); - } - - /** - * For decay behaviors, get the period - * @returns {string|null} Decay period or null - */ - getDecayPeriod() { - return this.getParameter('period'); - } - - /** - * For blur behaviors, get the mode - * @returns {string|null} Blur mode or null - */ - getBlurMode() { - return this.getParameter('mode'); - } - - /** - * For blur behaviors, get the confidence level - * @returns {string|null} Confidence level or null - */ - getBlurConfidence() { - return this.getParameter('confidence'); - } - - /** - * For TTL behaviors, get the duration - * @returns {string|null} TTL duration or null - */ - getTTLDuration() { - return this.getParameter('duration'); - } - - /** - * Validate the behavior - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate behavior type - if (!['decay', 'blur', 'ttl'].includes(this.type)) { - errors.push(`Invalid behavior type: ${this.type}`); - } - - // Validate decay behavior parameters - if (this.isDecay()) { - const direction = this.getDecayDirection(); - if (!direction || !['up', 'down', 'neutral', 'stable'].includes(direction)) { - errors.push(`Invalid decay direction: ${direction}`); - } - - const period = this.getDecayPeriod(); - if (!period || !['hourly', 'daily', 'weekly', 'monthly'].includes(period)) { - errors.push(`Invalid decay period: ${period}`); - } - } - - // Validate blur behavior parameters - if (this.isBlur()) { - const mode = this.getBlurMode(); - if (!mode || !['fixed', 'adaptive', 'confidence'].includes(mode)) { - errors.push(`Invalid blur mode: ${mode}`); - } - - const confidence = this.getBlurConfidence(); - if (confidence && !['confidence_90', 'confidence_95', 'confidence_99'].includes(confidence)) { - errors.push(`Invalid blur confidence: ${confidence}`); - } - } - - // Validate TTL behavior parameters - if (this.isTTL()) { - const duration = this.getTTLDuration(); - if (!duration || !/^\d+[hd]$/.test(duration)) { - errors.push(`Invalid TTL duration: ${duration}`); - } - } - - return errors; - } - - toString() { - const params = Array.from(this.parameters.entries()) - .map(([key, value]) => `${key}: ${value}`) - .join(', '); - return `Behavior(${this.type}, ${params})`; - } -} diff --git a/src/ast/nodes/DefeasibleLogicNode.js b/src/ast/nodes/DefeasibleLogicNode.js deleted file mode 100644 index acbe47c..0000000 --- a/src/ast/nodes/DefeasibleLogicNode.js +++ /dev/null @@ -1,150 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for defeasible logic statements - * Represents: ALWAYS, WHEN, UNLESS, REQUIRES statements - */ -export class DefeasibleLogicNode extends BaseNode { - constructor(logicType, location = null) { - super('DefeasibleLogic', location); - this.logicType = logicType; // 'ALWAYS', 'WHEN', 'UNLESS', 'REQUIRES' - this.condition = null; // ExpressionNode or EvidenceBodyNode - this.defeater = null; // ExpressionNode or EvidenceBodyNode (for WHEN/UNLESS) - } - - /** - * Set the condition for this defeasible logic - * @param {BaseNode} condition - Condition to set - */ - setCondition(condition) { - this.condition = condition; - this.addChild(condition); - } - - /** - * Set the defeater for this defeasible logic (for WHEN/UNLESS) - * @param {BaseNode} defeater - Defeater to set - */ - setDefeater(defeater) { - this.defeater = defeater; - this.addChild(defeater); - } - - /** - * Check if this is an ALWAYS statement - * @returns {boolean} True if ALWAYS - */ - isAlways() { - return this.logicType === 'ALWAYS'; - } - - /** - * Check if this is a WHEN statement - * @returns {boolean} True if WHEN - */ - isWhen() { - return this.logicType === 'WHEN'; - } - - /** - * Check if this is an UNLESS statement - * @returns {boolean} True if UNLESS - */ - isUnless() { - return this.logicType === 'UNLESS'; - } - - /** - * Check if this is a REQUIRES statement - * @returns {boolean} True if REQUIRES - */ - isRequires() { - return this.logicType === 'REQUIRES'; - } - - /** - * Check if this is a strict rule (ALWAYS) - * @returns {boolean} True if strict - */ - isStrict() { - return this.isAlways(); - } - - /** - * Check if this is a defeasible rule (WHEN) - * @returns {boolean} True if defeasible - */ - isDefeasible() { - return this.isWhen(); - } - - /** - * Check if this is a defeater (UNLESS) - * @returns {boolean} True if defeater - */ - isDefeater() { - return this.isUnless(); - } - - /** - * Check if this is a requirement (REQUIRES) - * @returns {boolean} True if requirement - */ - isRequirement() { - return this.isRequires(); - } - - /** - * Get the precedence level for this logic type - * @returns {number} Precedence level (higher = more important) - */ - getPrecedence() { - switch (this.logicType) { - case 'ALWAYS': return 3; // Highest precedence - case 'WHEN': return 2; // Medium precedence - case 'UNLESS': return 2; // Medium precedence - case 'REQUIRES': return 1; // Lowest precedence - default: return 0; - } - } - - /** - * Validate the defeasible logic - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate logic type - if (!['ALWAYS', 'WHEN', 'UNLESS', 'REQUIRES'].includes(this.logicType)) { - errors.push(`Invalid logic type: ${this.logicType}`); - } - - // Validate condition - if (!this.condition) { - errors.push(`${this.logicType} statement must have a condition`); - } else { - const condErrors = this.condition.validate ? this.condition.validate() : []; - errors.push(...condErrors); - } - - // Validate defeater for WHEN/UNLESS - if ((this.isWhen() || this.isUnless()) && !this.defeater) { - errors.push(`${this.logicType} statement must have a defeater`); - } - - // Validate defeater if present - if (this.defeater) { - const defErrors = this.defeater.validate ? this.defeater.validate() : []; - errors.push(...defErrors); - } - - return errors; - } - - toString() { - const condStr = this.condition ? this.condition.toString() : 'null'; - const defStr = this.defeater ? ` UNLESS ${this.defeater.toString()}` : ''; - return `DefeasibleLogic(${this.logicType} ${condStr}${defStr})`; - } -} diff --git a/src/ast/nodes/DefinitionNode.js b/src/ast/nodes/DefinitionNode.js deleted file mode 100644 index c2a20df..0000000 --- a/src/ast/nodes/DefinitionNode.js +++ /dev/null @@ -1,117 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for type definitions - * Represents: definition User { ... } - */ -export class DefinitionNode extends BaseNode { - constructor(name, definitionType = 'type', location = null) { - super('Definition', location); - this.name = name; - this.definitionType = definitionType; // 'type', 'interface', etc. - this.fields = []; - this.behaviors = new Map(); // field name -> behavior - this.cacheDirectives = new Map(); // field name -> cache directive - } - - /** - * Add a field to the definition - * @param {FieldNode} field - Field to add - */ - addField(field) { - this.fields.push(field); - this.addChild(field); - } - - /** - * Set behavior for a field - * @param {string} fieldName - Name of the field - * @param {BehaviorNode} behavior - Behavior to set - */ - setBehavior(fieldName, behavior) { - this.behaviors.set(fieldName, behavior); - } - - /** - * Set cache directive for a field - * @param {string} fieldName - Name of the field - * @param {string} directive - Cache directive ('lazy') - */ - setCacheDirective(fieldName, directive) { - if (directive === 'eager') { - if (!DefinitionNode._warnedEagerCacheDirective) { - DefinitionNode._warnedEagerCacheDirective = true; - console.warn('[DefinitionNode] CACHE eager is deprecated; treating as CACHE lazy.'); - } - this.cacheDirectives.set(fieldName, 'lazy'); - return; - } - this.cacheDirectives.set(fieldName, directive); - } - - /** - * Get behavior for a field - * @param {string} fieldName - Name of the field - * @returns {BehaviorNode|null} Behavior or null - */ - getBehavior(fieldName) { - return this.behaviors.get(fieldName) || null; - } - - /** - * Get cache directive for a field - * @param {string} fieldName - Name of the field - * @returns {string|null} Cache directive or null - */ - getCacheDirective(fieldName) { - return this.cacheDirectives.get(fieldName) || null; - } - - /** - * Find a field by name - * @param {string} fieldName - Name to search for - * @returns {FieldNode|null} Found field or null - */ - getField(fieldName) { - return this.fields.find(field => field.name === fieldName) || null; - } - - /** - * Get all fields with a specific type - * @param {string} type - Type to filter by - * @returns {FieldNode[]} Filtered fields - */ - getFieldsOfType(type) { - return this.fields.filter(field => field.type === type); - } - - /** - * Validate the definition - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Check for duplicate field names - const fieldNames = new Set(); - this.fields.forEach(field => { - if (fieldNames.has(field.name)) { - errors.push(`Duplicate field name '${field.name}' in definition '${this.name}'`); - } else { - fieldNames.add(field.name); - } - }); - - // Validate each field - this.fields.forEach(field => { - const fieldErrors = field.validate ? field.validate() : []; - errors.push(...fieldErrors); - }); - - return errors; - } - - toString() { - return `Definition(${this.name}: ${this.fields.length} fields)`; - } -} diff --git a/src/ast/nodes/DirectEvidenceNode.js b/src/ast/nodes/DirectEvidenceNode.js deleted file mode 100644 index c08c9eb..0000000 --- a/src/ast/nodes/DirectEvidenceNode.js +++ /dev/null @@ -1,78 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for direct evidence statements - * Represents: owns(user, doc) - */ -export class DirectEvidenceNode extends BaseNode { - constructor(location = null) { - super('DirectEvidence', location); - this.predicate = null; // PredicateNode - this.negated = false; - } - - /** - * Set the predicate for this direct evidence - * @param {PredicateNode} predicate - Predicate to set - */ - setPredicate(predicate) { - this.predicate = predicate; - this.addChild(predicate); - } - - /** - * Set whether this evidence is negated - * @param {boolean} negated - Whether evidence is negated - */ - setNegated(negated) { - this.negated = negated; - } - - /** - * Check if this evidence is negated - * @returns {boolean} True if negated - */ - isNegated() { - return this.negated; - } - - /** - * Get the predicate name - * @returns {string|null} Predicate name or null - */ - getPredicateName() { - return this.predicate ? this.predicate.name : null; - } - - /** - * Get the predicate arguments - * @returns {ExpressionNode[]} Predicate arguments - */ - getArguments() { - return this.predicate ? this.predicate.arguments : []; - } - - /** - * Validate the direct evidence - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate predicate - if (!this.predicate) { - errors.push('Direct evidence must have a predicate'); - } else { - const predErrors = this.predicate.validate ? this.predicate.validate() : []; - errors.push(...predErrors); - } - - return errors; - } - - toString() { - const negStr = this.negated ? 'NOT ' : ''; - const predStr = this.predicate ? this.predicate.toString() : 'null'; - return `DirectEvidence(${negStr}${predStr})`; - } -} diff --git a/src/ast/nodes/EvidenceBodyNode.js b/src/ast/nodes/EvidenceBodyNode.js deleted file mode 100644 index 823616a..0000000 --- a/src/ast/nodes/EvidenceBodyNode.js +++ /dev/null @@ -1,82 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for evidence body containing statements - * Represents: { statement1; statement2; ... } - */ -export class EvidenceBodyNode extends BaseNode { - constructor(location = null) { - super('EvidenceBody', location); - this.statements = []; - } - - /** - * Add a statement to the evidence body - * @param {BaseNode} statement - Statement to add - */ - addStatement(statement) { - this.statements.push(statement); - this.addChild(statement); - } - - /** - * Get all statements of a specific type - * @param {string} type - Statement type to filter by - * @returns {BaseNode[]} Filtered statements - */ - getStatementsOfType(type) { - return this.statements.filter(stmt => stmt.type === type); - } - - /** - * Get all direct evidence statements - * @returns {DirectEvidenceNode[]} Direct evidence statements - */ - getDirectEvidence() { - return this.getStatementsOfType('DirectEvidence'); - } - - /** - * Get all pattern matching statements - * @returns {PatternMatchNode[]} Pattern matching statements - */ - getPatternMatches() { - return this.getStatementsOfType('PatternMatch'); - } - - /** - * Get all defeasible logic statements - * @returns {DefeasibleLogicNode[]} Defeasible logic statements - */ - getDefeasibleLogic() { - return this.getStatementsOfType('DefeasibleLogic'); - } - - /** - * Get all fusion statements - * @returns {FusionNode[]} Fusion statements - */ - getFusions() { - return this.getStatementsOfType('Fusion'); - } - - /** - * Validate the evidence body - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate each statement - this.statements.forEach((stmt, index) => { - const stmtErrors = stmt.validate ? stmt.validate() : []; - errors.push(...stmtErrors.map(err => `Statement ${index + 1}: ${err}`)); - }); - - return errors; - } - - toString() { - return `EvidenceBody(${this.statements.length} statements)`; - } -} diff --git a/src/ast/nodes/EvidenceNode.js b/src/ast/nodes/EvidenceNode.js deleted file mode 100644 index 1245484..0000000 --- a/src/ast/nodes/EvidenceNode.js +++ /dev/null @@ -1,117 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for evidence definitions - * Represents: evidence canRead(user: User, doc: Document) { ... } PROVIDES string - */ -export class EvidenceNode extends BaseNode { - constructor(name, location = null) { - super('Evidence', location); - this.name = name; - this.parameters = []; - this.returnType = null; - this.body = null; // EvidenceBodyNode - this.provides = null; // Return type specification - } - - /** - * Add a parameter to the evidence - * @param {ParameterNode} parameter - Parameter to add - */ - addParameter(parameter) { - this.parameters.push(parameter); - this.addChild(parameter); - } - - /** - * Set the body of the evidence - * @param {EvidenceBodyNode} body - Evidence body - */ - setBody(body) { - this.body = body; - this.addChild(body); - } - - /** - * Set the return type for this evidence - * @param {string} returnType - Return type - */ - setReturnType(returnType) { - this.returnType = returnType; - this.provides = returnType; - } - - /** - * Get the parameter names as an array - * @returns {string[]} Array of parameter names - */ - getParameterNames() { - return this.parameters.map(param => param.name); - } - - /** - * Get the parameter types as an array - * @returns {string[]} Array of parameter types - */ - getParameterTypes() { - return this.parameters.map(param => param.type); - } - - /** - * Find a parameter by name - * @param {string} name - Parameter name to find - * @returns {ParameterNode|null} Found parameter or null - */ - getParameter(name) { - return this.parameters.find(param => param.name === name) || null; - } - - /** - * Get the signature string for this evidence - * @returns {string} Evidence signature - */ - getSignature() { - const paramStr = this.parameters.map(param => `${param.name}: ${param.type}`).join(', '); - return `${this.name}(${paramStr})`; - } - - /** - * Check if this evidence has a return type - * @returns {boolean} True if has return type - */ - hasReturnType() { - return this.returnType !== null; - } - - /** - * Validate the evidence - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate evidence name - if (!this.name || typeof this.name !== 'string') { - errors.push(`Invalid evidence name: ${this.name}`); - } - - // Validate parameters - this.parameters.forEach((param, index) => { - const paramErrors = param.validate ? param.validate() : []; - errors.push(...paramErrors.map(err => `Parameter ${index + 1}: ${err}`)); - }); - - // Validate body - if (this.body) { - const bodyErrors = this.body.validate ? this.body.validate() : []; - errors.push(...bodyErrors); - } - - return errors; - } - - toString() { - const providesStr = this.returnType ? ` PROVIDES ${this.returnType}` : ''; - return `Evidence(${this.getSignature()}${providesStr})`; - } -} diff --git a/src/ast/nodes/ExpressionNode.js b/src/ast/nodes/ExpressionNode.js deleted file mode 100644 index 958aa4f..0000000 --- a/src/ast/nodes/ExpressionNode.js +++ /dev/null @@ -1,260 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for expressions (variables, literals, attribute access, etc.) - */ -export class ExpressionNode extends BaseNode { - constructor(expressionType, location = null) { - super('Expression', location); - this.expressionType = expressionType; // 'variable', 'literal', 'attribute', 'function', etc. - this.value = null; - this.name = null; - this.attribute = null; - this.object = null; - this.arguments = []; - this.operator = null; - this.left = null; - this.right = null; - } - - /** - * Set the value for this expression - * @param {*} value - Value to set - */ - setValue(value) { - this.value = value; - } - - /** - * Set the name for this expression - * @param {string} name - Name to set - */ - setName(name) { - this.name = name; - } - - /** - * Set the attribute for this expression - * @param {string} attribute - Attribute to set - */ - setAttribute(attribute) { - this.attribute = attribute; - } - - /** - * Set the object for this expression - * @param {ExpressionNode} object - Object to set - */ - setObject(object) { - this.object = object; - this.addChild(object); - } - - /** - * Add an argument to this expression - * @param {ExpressionNode} argument - Argument to add - */ - addArgument(argument) { - this.arguments.push(argument); - this.addChild(argument); - } - - /** - * Set the operator for this expression - * @param {string} operator - Operator to set - */ - setOperator(operator) { - this.operator = operator; - } - - /** - * Set the left operand for this expression - * @param {ExpressionNode} left - Left operand to set - */ - setLeft(left) { - this.left = left; - this.addChild(left); - } - - /** - * Set the right operand for this expression - * @param {ExpressionNode} right - Right operand to set - */ - setRight(right) { - this.right = right; - this.addChild(right); - } - - /** - * Check if this is a variable expression - * @returns {boolean} True if variable - */ - isVariable() { - return this.expressionType === 'variable'; - } - - /** - * Check if this is a literal expression - * @returns {boolean} True if literal - */ - isLiteral() { - return this.expressionType === 'literal'; - } - - /** - * Check if this is an attribute access expression - * @returns {boolean} True if attribute access - */ - isAttributeAccess() { - return this.expressionType === 'attribute'; - } - - /** - * Check if this is a function call expression - * @returns {boolean} True if function call - */ - isFunctionCall() { - return this.expressionType === 'function'; - } - - /** - * Check if this is a binary operation expression - * @returns {boolean} True if binary operation - */ - isBinaryOperation() { - return this.expressionType === 'binary'; - } - - /** - * Check if this is a wildcard variable - * @returns {boolean} True if wildcard - */ - isWildcard() { - return this.isVariable() && this.name && this.name.startsWith('*'); - } - - /** - * Get the variable name (without wildcard prefix) - * @returns {string|null} Variable name or null - */ - getVariableName() { - if (this.isVariable() && this.name) { - return this.name.startsWith('*') ? this.name.substring(1) : this.name; - } - return null; - } - - /** - * Get the full attribute path - * @returns {string|null} Full attribute path or null - */ - getAttributePath() { - if (this.isAttributeAccess()) { - const objStr = this.object ? this.object.toString() : ''; - return `${objStr}.${this.attribute}`; - } - return null; - } - - /** - * Get the function signature - * @returns {string|null} Function signature or null - */ - getFunctionSignature() { - if (this.isFunctionCall()) { - const argStr = this.arguments.map(arg => arg.toString()).join(', '); - return `${this.name}(${argStr})`; - } - return null; - } - - /** - * Validate the expression - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate expression type - const validTypes = ['variable', 'literal', 'attribute', 'function', 'binary']; - if (!validTypes.includes(this.expressionType)) { - errors.push(`Invalid expression type: ${this.expressionType}`); - } - - // Validate variable expressions - if (this.isVariable() && !this.name) { - errors.push('Variable expression must have a name'); - } - - // Validate literal expressions - if (this.isLiteral() && this.value === null) { - errors.push('Literal expression must have a value'); - } - - // Validate attribute access expressions - if (this.isAttributeAccess()) { - if (!this.attribute) { - errors.push('Attribute access expression must have an attribute'); - } - if (this.object) { - const objErrors = this.object.validate ? this.object.validate() : []; - errors.push(...objErrors); - } - } - - // Validate function call expressions - if (this.isFunctionCall()) { - if (!this.name) { - errors.push('Function call expression must have a name'); - } - this.arguments.forEach((arg, index) => { - const argErrors = arg.validate ? arg.validate() : []; - errors.push(...argErrors.map(err => `Argument ${index + 1}: ${err}`)); - }); - } - - // Validate binary operation expressions - if (this.isBinaryOperation()) { - if (!this.operator) { - errors.push('Binary operation expression must have an operator'); - } - if (!this.left) { - errors.push('Binary operation expression must have a left operand'); - } - if (!this.right) { - errors.push('Binary operation expression must have a right operand'); - } - if (this.left) { - const leftErrors = this.left.validate ? this.left.validate() : []; - errors.push(...leftErrors); - } - if (this.right) { - const rightErrors = this.right.validate ? this.right.validate() : []; - errors.push(...rightErrors); - } - } - - return errors; - } - - toString() { - switch (this.expressionType) { - case 'variable': - return `Variable(${this.name})`; - case 'literal': - return `Literal(${this.value})`; - case 'attribute': - const objStr = this.object ? this.object.toString() : ''; - return `Attribute(${objStr}.${this.attribute})`; - case 'function': - const argStr = this.arguments.map(arg => arg.toString()).join(', '); - return `Function(${this.name}(${argStr}))`; - case 'binary': - const leftStr = this.left ? this.left.toString() : 'null'; - const rightStr = this.right ? this.right.toString() : 'null'; - return `Binary(${leftStr} ${this.operator} ${rightStr})`; - default: - return `Expression(${this.expressionType})`; - } - } -} diff --git a/src/ast/nodes/FactNode.js b/src/ast/nodes/FactNode.js deleted file mode 100644 index e592b5b..0000000 --- a/src/ast/nodes/FactNode.js +++ /dev/null @@ -1,166 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for fact definitions - * Represents: fact hasRole(user: User, role: string) CACHE lazy - */ -export class FactNode extends BaseNode { - constructor(name, location = null) { - super('Fact', location); - this.name = name; - this.parameters = []; - this.returnType = null; - this.properties = new Map(); // transitive, symmetrical, etc. - this.cacheDirective = null; - this.limit = null; - } - - /** - * Add a parameter to the fact - * @param {ParameterNode} parameter - Parameter to add - */ - addParameter(parameter) { - this.parameters.push(parameter); - this.addChild(parameter); - } - - /** - * Set the return type for this fact - * @param {string} returnType - Return type - */ - setReturnType(returnType) { - this.returnType = returnType; - } - - /** - * Set a property for this fact - * @param {string} name - Property name - * @param {*} value - Property value - */ - setProperty(name, value) { - this.properties.set(name, value); - } - - /** - * Get a property value - * @param {string} name - Property name - * @returns {*} Property value or null - */ - getProperty(name) { - return this.properties.get(name) || null; - } - - /** - * Set the cache directive for this fact - * @param {string} directive - Cache directive ('lazy') - */ - setCacheDirective(directive) { - if (directive === 'eager') { - if (!FactNode._warnedEagerCacheDirective) { - FactNode._warnedEagerCacheDirective = true; - console.warn('[FactNode] CACHE eager is deprecated; treating as CACHE lazy.'); - } - this.cacheDirective = 'lazy'; - return; - } - this.cacheDirective = directive; - } - - /** - * Set the limit for this fact - * @param {number} limit - Limit value - */ - setLimit(limit) { - this.limit = limit; - } - - /** - * Check if this fact is transitive - * @returns {boolean} True if transitive - */ - isTransitive() { - return this.getProperty('transitive') === true; - } - - /** - * Check if this fact is symmetrical - * @returns {boolean} True if symmetrical - */ - isSymmetrical() { - return this.getProperty('symmetrical') === true; - } - - /** - * Get the parameter names as an array - * @returns {string[]} Array of parameter names - */ - getParameterNames() { - return this.parameters.map(param => param.name); - } - - /** - * Get the parameter types as an array - * @returns {string[]} Array of parameter types - */ - getParameterTypes() { - return this.parameters.map(param => param.type); - } - - /** - * Find a parameter by name - * @param {string} name - Parameter name to find - * @returns {ParameterNode|null} Found parameter or null - */ - getParameter(name) { - return this.parameters.find(param => param.name === name) || null; - } - - /** - * Get the signature string for this fact - * @returns {string} Fact signature - */ - getSignature() { - const paramStr = this.parameters.map(param => `${param.name}: ${param.type}`).join(', '); - return `${this.name}(${paramStr})`; - } - - /** - * Validate the fact - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate fact name - if (!this.name || typeof this.name !== 'string') { - errors.push(`Invalid fact name: ${this.name}`); - } - - // Validate parameters - this.parameters.forEach((param, index) => { - const paramErrors = param.validate ? param.validate() : []; - errors.push(...paramErrors.map(err => `Parameter ${index + 1}: ${err}`)); - }); - - // Validate cache directive - if (this.cacheDirective && !['lazy'].includes(this.cacheDirective)) { - errors.push(`Invalid cache directive: ${this.cacheDirective}`); - } - - // Validate limit - if (this.limit !== null && (typeof this.limit !== 'number' || this.limit < 0)) { - errors.push(`Invalid limit: ${this.limit}`); - } - - return errors; - } - - toString() { - const props = Array.from(this.properties.entries()) - .map(([key, value]) => `${key}: ${value}`) - .join(', '); - const cacheStr = this.cacheDirective ? ` CACHE ${this.cacheDirective}` : ''; - const limitStr = this.limit ? ` LIMIT ${this.limit}` : ''; - return `Fact(${this.getSignature()}${props ? `, ${props}` : ''}${cacheStr}${limitStr})`; - } -} diff --git a/src/ast/nodes/FieldNode.js b/src/ast/nodes/FieldNode.js deleted file mode 100644 index f45630a..0000000 --- a/src/ast/nodes/FieldNode.js +++ /dev/null @@ -1,141 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for field definitions within type definitions - * Represents: fieldName: type BEHAVES { ... } CACHE lazy - */ -export class FieldNode extends BaseNode { - constructor(name, type, location = null) { - super('Field', location); - this.name = name; - this.type = type; - this.isArray = false; - this.behavior = null; - this.cacheDirective = null; - this.isOptional = false; - this.defaultValue = null; - } - - /** - * Set the behavior for this field - * @param {BehaviorNode} behavior - Behavior to set - */ - setBehavior(behavior) { - this.behavior = behavior; - this.addChild(behavior); - } - - /** - * Set the cache directive for this field - * @param {string} directive - Cache directive ('lazy') - */ - setCacheDirective(directive) { - if (directive === 'eager') { - if (!FieldNode._warnedEagerCacheDirective) { - FieldNode._warnedEagerCacheDirective = true; - console.warn('[FieldNode] CACHE eager is deprecated; treating as CACHE lazy.'); - } - this.cacheDirective = 'lazy'; - return; - } - this.cacheDirective = directive; - } - - /** - * Mark this field as an array type - * @param {boolean} isArray - Whether this is an array - */ - setArray(isArray) { - this.isArray = isArray; - } - - /** - * Set whether this field is optional - * @param {boolean} optional - Whether field is optional - */ - setOptional(optional) { - this.isOptional = optional; - } - - /** - * Set default value for this field - * @param {*} value - Default value - */ - setDefaultValue(value) { - this.defaultValue = value; - } - - /** - * Get the full type string including array notation - * @returns {string} Full type string - */ - getFullType() { - let typeStr = this.type; - if (this.isArray) { - typeStr += '[]'; - } - if (this.isOptional) { - typeStr += '?'; - } - return typeStr; - } - - /** - * Check if this field has decay behavior - * @returns {boolean} True if field has decay behavior - */ - hasDecayBehavior() { - return this.behavior && this.behavior.type === 'decay'; - } - - /** - * Check if this field has blur behavior - * @returns {boolean} True if field has blur behavior - */ - hasBlurBehavior() { - return this.behavior && this.behavior.type === 'blur'; - } - - /** - * Check if this field has TTL behavior - * @returns {boolean} True if field has TTL behavior - */ - hasTTLBehavior() { - return this.behavior && this.behavior.type === 'ttl'; - } - - /** - * Validate the field - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate field name - if (!this.name || typeof this.name !== 'string') { - errors.push(`Invalid field name: ${this.name}`); - } - - // Validate type - if (!this.type || typeof this.type !== 'string') { - errors.push(`Invalid field type: ${this.type}`); - } - - // Validate behavior if present - if (this.behavior) { - const behaviorErrors = this.behavior.validate ? this.behavior.validate() : []; - errors.push(...behaviorErrors); - } - - // Validate cache directive - if (this.cacheDirective && !['lazy'].includes(this.cacheDirective)) { - errors.push(`Invalid cache directive: ${this.cacheDirective}`); - } - - return errors; - } - - toString() { - return `Field(${this.name}: ${this.getFullType()})`; - } -} diff --git a/src/ast/nodes/FusionNode.js b/src/ast/nodes/FusionNode.js deleted file mode 100644 index 9d9f8cf..0000000 --- a/src/ast/nodes/FusionNode.js +++ /dev/null @@ -1,170 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for fusion statements - * Represents: fusion max { ... } - */ -export class FusionNode extends BaseNode { - constructor(strategy, location = null) { - super('Fusion', location); - this.strategy = strategy; // 'max', 'min', 'majority', 'average', etc. - this.evidence = []; // Array of evidence statements - this.weights = null; // Optional weights array - } - - /** - * Add evidence to this fusion - * @param {BaseNode} evidence - Evidence to add - */ - addEvidence(evidence) { - this.evidence.push(evidence); - this.addChild(evidence); - } - - /** - * Set weights for this fusion - * @param {number[]} weights - Weights array - */ - setWeights(weights) { - this.weights = weights; - } - - /** - * Get the fusion strategy - * @returns {string} Fusion strategy - */ - getStrategy() { - return this.strategy; - } - - /** - * Get all evidence statements - * @returns {BaseNode[]} Evidence statements - */ - getEvidence() { - return this.evidence; - } - - /** - * Get the weights for this fusion - * @returns {number[]|null} Weights or null - */ - getWeights() { - return this.weights; - } - - /** - * Check if this fusion has weights - * @returns {boolean} True if has weights - */ - hasWeights() { - return this.weights !== null && this.weights.length > 0; - } - - /** - * Check if this is a max fusion - * @returns {boolean} True if max fusion - */ - isMax() { - return this.strategy === 'max'; - } - - /** - * Check if this is a min fusion - * @returns {boolean} True if min fusion - */ - isMin() { - return this.strategy === 'min'; - } - - /** - * Check if this is a majority fusion - * @returns {boolean} True if majority fusion - */ - isMajority() { - return this.strategy === 'majority'; - } - - /** - * Check if this is an average fusion - * @returns {boolean} True if average fusion - */ - isAverage() { - return this.strategy === 'average'; - } - - /** - * Get the number of evidence statements - * @returns {number} Number of evidence statements - */ - getEvidenceCount() { - return this.evidence.length; - } - - /** - * Validate the fusion - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate strategy - const validStrategies = [ - 'max', - 'min', - 'majority', - 'average', - 'sum', - 'sum_unbounded', - 'median', - 'optimistic', - 'pessimistic', - 'top2', - 'top3', - 'priority', - 'custom', - 'count' - ]; - if (!validStrategies.includes(this.strategy)) { - errors.push(`Invalid fusion strategy: ${this.strategy}`); - } - - // Validate evidence - if (this.evidence.length === 0) { - errors.push('Fusion must have at least one evidence statement'); - } - - // Validate each evidence statement - this.evidence.forEach((ev, index) => { - const evErrors = ev.validate ? ev.validate() : []; - errors.push(...evErrors.map(err => `Evidence ${index + 1}: ${err}`)); - }); - - // Validate weights - if (this.weights !== null) { - if (!Array.isArray(this.weights)) { - errors.push('Weights must be an array'); - } else if (this.weights.length !== this.evidence.length) { - errors.push('Weights array length must match evidence count'); - } else if (this.weights.some(w => typeof w !== 'number' || w < 0)) { - errors.push('All weights must be non-negative numbers'); - } else if (this.strategy === 'custom') { - const total = this.weights.reduce((sum, w) => sum + w, 0); - if (Math.abs(total - 1.0) > 1e-6) { - errors.push('Custom weights must sum to 1.0'); - } - } - } - - if (this.strategy === 'custom' && (!this.weights || this.weights.length === 0)) { - errors.push('Custom fusion requires weights'); - } - - return errors; - } - - toString() { - const weightsStr = this.hasWeights() ? ` weights[${this.weights.length}]` : ''; - return `Fusion(${this.strategy}, ${this.evidence.length} evidence${weightsStr})`; - } -} diff --git a/src/ast/nodes/MeasureBodyNode.js b/src/ast/nodes/MeasureBodyNode.js deleted file mode 100644 index 3d0ebc1..0000000 --- a/src/ast/nodes/MeasureBodyNode.js +++ /dev/null @@ -1,130 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for measure body containing expressions - * Represents: { user.role } - */ -export class MeasureBodyNode extends BaseNode { - constructor(location = null) { - super('MeasureBody', location); - this.expression = null; // ExpressionNode - this.fusion = null; // FusionNode (optional) - this.aggregation = null; // AggregationNode (optional) - } - - /** - * Set the expression for this measure body - * @param {ExpressionNode} expression - Expression to set - */ - setExpression(expression) { - this.expression = expression; - this.addChild(expression); - } - - /** - * Set the fusion for this measure body - * @param {FusionNode} fusion - Fusion to set - */ - setFusion(fusion) { - this.fusion = fusion; - this.addChild(fusion); - } - - /** - * Set the aggregation for this measure body - * @param {AggregationNode} aggregation - Aggregation to set - */ - setAggregation(aggregation) { - this.aggregation = aggregation; - this.addChild(aggregation); - } - - /** - * Get the expression - * @returns {ExpressionNode|null} Expression or null - */ - getExpression() { - return this.expression; - } - - /** - * Get the fusion - * @returns {FusionNode|null} Fusion or null - */ - getFusion() { - return this.fusion; - } - - /** - * Get the aggregation - * @returns {AggregationNode|null} Aggregation or null - */ - getAggregation() { - return this.aggregation; - } - - /** - * Check if this measure body has an expression - * @returns {boolean} True if has expression - */ - hasExpression() { - return this.expression !== null; - } - - /** - * Check if this measure body has fusion - * @returns {boolean} True if has fusion - */ - hasFusion() { - return this.fusion !== null; - } - - /** - * Check if this measure body has aggregation - * @returns {boolean} True if has aggregation - */ - hasAggregation() { - return this.aggregation !== null; - } - - /** - * Validate the measure body - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Must have at least one of expression, fusion, or aggregation - if (!this.expression && !this.fusion && !this.aggregation) { - errors.push('Measure body must have an expression, fusion, or aggregation'); - } - - // Validate expression if present - if (this.expression) { - const exprErrors = this.expression.validate ? this.expression.validate() : []; - errors.push(...exprErrors); - } - - // Validate fusion if present - if (this.fusion) { - const fusionErrors = this.fusion.validate ? this.fusion.validate() : []; - errors.push(...fusionErrors); - } - - // Validate aggregation if present - if (this.aggregation) { - const aggErrors = this.aggregation.validate ? this.aggregation.validate() : []; - errors.push(...aggErrors); - } - - return errors; - } - - toString() { - const parts = []; - if (this.expression) parts.push(this.expression.toString()); - if (this.fusion) parts.push(this.fusion.toString()); - if (this.aggregation) parts.push(this.aggregation.toString()); - return `MeasureBody(${parts.join(', ')})`; - } -} diff --git a/src/ast/nodes/MeasureNode.js b/src/ast/nodes/MeasureNode.js deleted file mode 100644 index 5cfac29..0000000 --- a/src/ast/nodes/MeasureNode.js +++ /dev/null @@ -1,117 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for measure definitions - * Represents: measure userRole(user: User) { ... } PROVIDES string - */ -export class MeasureNode extends BaseNode { - constructor(name, location = null) { - super('Measure', location); - this.name = name; - this.parameters = []; - this.returnType = null; - this.body = null; // MeasureBodyNode - this.provides = null; // Return type specification - } - - /** - * Add a parameter to the measure - * @param {ParameterNode} parameter - Parameter to add - */ - addParameter(parameter) { - this.parameters.push(parameter); - this.addChild(parameter); - } - - /** - * Set the body of the measure - * @param {MeasureBodyNode} body - Measure body - */ - setBody(body) { - this.body = body; - this.addChild(body); - } - - /** - * Set the return type for this measure - * @param {string} returnType - Return type - */ - setReturnType(returnType) { - this.returnType = returnType; - this.provides = returnType; - } - - /** - * Get the parameter names as an array - * @returns {string[]} Array of parameter names - */ - getParameterNames() { - return this.parameters.map(param => param.name); - } - - /** - * Get the parameter types as an array - * @returns {string[]} Array of parameter types - */ - getParameterTypes() { - return this.parameters.map(param => param.type); - } - - /** - * Find a parameter by name - * @param {string} name - Parameter name to find - * @returns {ParameterNode|null} Found parameter or null - */ - getParameter(name) { - return this.parameters.find(param => param.name === name) || null; - } - - /** - * Get the signature string for this measure - * @returns {string} Measure signature - */ - getSignature() { - const paramStr = this.parameters.map(param => `${param.name}: ${param.type}`).join(', '); - return `${this.name}(${paramStr})`; - } - - /** - * Check if this measure has a return type - * @returns {boolean} True if has return type - */ - hasReturnType() { - return this.returnType !== null; - } - - /** - * Validate the measure - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate measure name - if (!this.name || typeof this.name !== 'string') { - errors.push(`Invalid measure name: ${this.name}`); - } - - // Validate parameters - this.parameters.forEach((param, index) => { - const paramErrors = param.validate ? param.validate() : []; - errors.push(...paramErrors.map(err => `Parameter ${index + 1}: ${err}`)); - }); - - // Validate body - if (this.body) { - const bodyErrors = this.body.validate ? this.body.validate() : []; - errors.push(...bodyErrors); - } - - return errors; - } - - toString() { - const providesStr = this.returnType ? ` PROVIDES ${this.returnType}` : ''; - return `Measure(${this.getSignature()}${providesStr})`; - } -} diff --git a/src/ast/nodes/ParameterNode.js b/src/ast/nodes/ParameterNode.js deleted file mode 100644 index 0906c29..0000000 --- a/src/ast/nodes/ParameterNode.js +++ /dev/null @@ -1,79 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for function/evidence parameters - * Represents: user: User, role: string - */ -export class ParameterNode extends BaseNode { - constructor(name, type, location = null) { - super('Parameter', location); - this.name = name; - this.type = type; - this.isOptional = false; - this.defaultValue = null; - this.isArray = false; - } - - /** - * Set whether this parameter is optional - * @param {boolean} optional - Whether parameter is optional - */ - setOptional(optional) { - this.isOptional = optional; - } - - /** - * Set default value for this parameter - * @param {*} value - Default value - */ - setDefaultValue(value) { - this.defaultValue = value; - } - - /** - * Set whether this parameter is an array - * @param {boolean} isArray - Whether parameter is an array - */ - setArray(isArray) { - this.isArray = isArray; - } - - /** - * Get the full type string including array notation - * @returns {string} Full type string - */ - getFullType() { - let typeStr = this.type; - if (this.isArray) { - typeStr += '[]'; - } - if (this.isOptional) { - typeStr += '?'; - } - return typeStr; - } - - /** - * Validate the parameter - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate parameter name - if (!this.name || typeof this.name !== 'string') { - errors.push(`Invalid parameter name: ${this.name}`); - } - - // Validate type - if (!this.type || typeof this.type !== 'string') { - errors.push(`Invalid parameter type: ${this.type}`); - } - - return errors; - } - - toString() { - return `Parameter(${this.name}: ${this.getFullType()})`; - } -} diff --git a/src/ast/nodes/PatternMatchNode.js b/src/ast/nodes/PatternMatchNode.js deleted file mode 100644 index dcdde2e..0000000 --- a/src/ast/nodes/PatternMatchNode.js +++ /dev/null @@ -1,142 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for pattern matching statements - * Represents: isMember(user, *group) { ... } limit 5 - */ -export class PatternMatchNode extends BaseNode { - constructor(location = null) { - super('PatternMatch', location); - this.predicate = null; // PredicateNode - this.body = null; // EvidenceBodyNode - this.limit = null; - this.withClause = null; // WithClauseNode - this.negated = false; - } - - /** - * Set the predicate for this pattern match - * @param {PredicateNode} predicate - Predicate to set - */ - setPredicate(predicate) { - this.predicate = predicate; - this.addChild(predicate); - } - - /** - * Set the body of the pattern match - * @param {EvidenceBodyNode} body - Evidence body - */ - setBody(body) { - this.body = body; - this.addChild(body); - } - - /** - * Set the limit for this pattern match - * @param {number} limit - Limit value - */ - setLimit(limit) { - this.limit = limit; - } - - /** - * Set the with clause for this pattern match - * @param {WithClauseNode} withClause - With clause - */ - setWithClause(withClause) { - this.withClause = withClause; - this.addChild(withClause); - } - - /** - * Set whether this pattern match is negated - * @param {boolean} negated - Whether pattern match is negated - */ - setNegated(negated) { - this.negated = negated; - } - - /** - * Check if this pattern match is negated - * @returns {boolean} True if negated - */ - isNegated() { - return this.negated; - } - - /** - * Get the predicate name - * @returns {string|null} Predicate name or null - */ - getPredicateName() { - return this.predicate ? this.predicate.name : null; - } - - /** - * Get the predicate arguments - * @returns {ExpressionNode[]} Predicate arguments - */ - getArguments() { - return this.predicate ? this.predicate.arguments : []; - } - - /** - * Check if this pattern match has a limit - * @returns {boolean} True if has limit - */ - hasLimit() { - return this.limit !== null; - } - - /** - * Check if this pattern match has a with clause - * @returns {boolean} True if has with clause - */ - hasWithClause() { - return this.withClause !== null; - } - - /** - * Validate the pattern match - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate predicate - if (!this.predicate) { - errors.push('Pattern match must have a predicate'); - } else { - const predErrors = this.predicate.validate ? this.predicate.validate() : []; - errors.push(...predErrors); - } - - // Validate body - if (this.body) { - const bodyErrors = this.body.validate ? this.body.validate() : []; - errors.push(...bodyErrors); - } - - // Validate limit - if (this.limit !== null && (typeof this.limit !== 'number' || this.limit < 0)) { - errors.push(`Invalid limit: ${this.limit}`); - } - - // Validate with clause - if (this.withClause) { - const withErrors = this.withClause.validate ? this.withClause.validate() : []; - errors.push(...withErrors); - } - - return errors; - } - - toString() { - const negStr = this.negated ? 'NOT ' : ''; - const predStr = this.predicate ? this.predicate.toString() : 'null'; - const limitStr = this.limit ? ` limit ${this.limit}` : ''; - const withStr = this.withClause ? ` ${this.withClause.toString()}` : ''; - return `PatternMatch(${negStr}${predStr}${limitStr}${withStr})`; - } -} diff --git a/src/ast/nodes/PredicateNode.js b/src/ast/nodes/PredicateNode.js deleted file mode 100644 index 6021041..0000000 --- a/src/ast/nodes/PredicateNode.js +++ /dev/null @@ -1,106 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for predicate calls - * Represents: hasRole(user, role), owns(user, doc) - */ -export class PredicateNode extends BaseNode { - constructor(name, location = null) { - super('Predicate', location); - this.name = name; - this.arguments = []; - } - - /** - * Add an argument to this predicate - * @param {ExpressionNode} argument - Argument to add - */ - addArgument(argument) { - this.arguments.push(argument); - this.addChild(argument); - } - - /** - * Get the predicate name - * @returns {string} Predicate name - */ - getName() { - return this.name; - } - - /** - * Get all arguments - * @returns {ExpressionNode[]} Predicate arguments - */ - getArguments() { - return this.arguments; - } - - /** - * Get the number of arguments - * @returns {number} Number of arguments - */ - getArgumentCount() { - return this.arguments.length; - } - - /** - * Get an argument by index - * @param {number} index - Argument index - * @returns {ExpressionNode|null} Argument or null - */ - getArgument(index) { - return this.arguments[index] || null; - } - - /** - * Check if this predicate has a specific number of arguments - * @param {number} count - Expected argument count - * @returns {boolean} True if has expected count - */ - hasArgumentCount(count) { - return this.arguments.length === count; - } - - /** - * Check if this predicate has any arguments - * @returns {boolean} True if has arguments - */ - hasArguments() { - return this.arguments.length > 0; - } - - /** - * Get the signature string for this predicate - * @returns {string} Predicate signature - */ - getSignature() { - const argStr = this.arguments.map(arg => arg.toString()).join(', '); - return `${this.name}(${argStr})`; - } - - /** - * Validate the predicate - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate predicate name - if (!this.name || typeof this.name !== 'string') { - errors.push(`Invalid predicate name: ${this.name}`); - } - - // Validate arguments - this.arguments.forEach((arg, index) => { - const argErrors = arg.validate ? arg.validate() : []; - errors.push(...argErrors.map(err => `Argument ${index + 1}: ${err}`)); - }); - - return errors; - } - - toString() { - return `Predicate(${this.getSignature()})`; - } -} diff --git a/src/ast/nodes/ProgramNode.js b/src/ast/nodes/ProgramNode.js deleted file mode 100644 index 50b276e..0000000 --- a/src/ast/nodes/ProgramNode.js +++ /dev/null @@ -1,158 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * Root node of the AST representing the entire DSL program - */ -export class ProgramNode extends BaseNode { - constructor(location = null) { - super('Program', location); - this.definitions = []; - this.facts = []; - this.evidence = []; - this.measures = []; - } - - /** - * Add a definition to the program - * @param {DefinitionNode} definition - Definition to add - */ - addDefinition(definition) { - this.definitions.push(definition); - this.addChild(definition); - } - - /** - * Add a fact to the program - * @param {FactNode} fact - Fact to add - */ - addFact(fact) { - this.facts.push(fact); - this.addChild(fact); - } - - /** - * Add evidence to the program - * @param {EvidenceNode} evidence - Evidence to add - */ - addEvidence(evidence) { - this.evidence.push(evidence); - this.addChild(evidence); - } - - /** - * Add a measure to the program - * @param {MeasureNode} measure - Measure to add - */ - addMeasure(measure) { - this.measures.push(measure); - this.addChild(measure); - } - - /** - * Get all definitions of a specific type - * @param {string} type - Definition type to filter by - * @returns {DefinitionNode[]} Filtered definitions - */ - getDefinitionsOfType(type) { - return this.definitions.filter(def => def.definitionType === type); - } - - /** - * Find a definition by name - * @param {string} name - Name to search for - * @returns {DefinitionNode|null} Found definition or null - */ - getDefinitionByName(name) { - return this.definitions.find(def => def.name === name) || null; - } - - /** - * Find evidence by name - * @param {string} name - Name to search for - * @returns {EvidenceNode|null} Found evidence or null - */ - getEvidenceByName(name) { - return this.evidence.find(ev => ev.name === name) || null; - } - - /** - * Find a fact by name - * @param {string} name - Name to search for - * @returns {FactNode|null} Found fact or null - */ - getFactByName(name) { - return this.facts.find(fact => fact.name === name) || null; - } - - /** - * Find a measure by name - * @param {string} name - Name to search for - * @returns {MeasureNode|null} Found measure or null - */ - getMeasureByName(name) { - return this.measures.find(measure => measure.name === name) || null; - } - - /** - * Get all symbols (definitions, facts, evidence, measures) by name - * @param {string} name - Name to search for - * @returns {BaseNode[]} All matching symbols - */ - getSymbolsByName(name) { - return [ - ...this.definitions.filter(def => def.name === name), - ...this.facts.filter(fact => fact.name === name), - ...this.evidence.filter(ev => ev.name === name), - ...this.measures.filter(measure => measure.name === name) - ]; - } - - /** - * Validate the program structure - * @returns {Object} Validation result with errors and warnings - */ - validate() { - const errors = []; - const warnings = []; - - // Check for duplicate names - const allNames = new Map(); - [...this.definitions, ...this.facts, ...this.evidence, ...this.measures].forEach(symbol => { - if (allNames.has(symbol.name)) { - errors.push(`Duplicate symbol name: ${symbol.name}`); - } else { - allNames.set(symbol.name, symbol); - } - }); - - // Validate each definition - this.definitions.forEach(def => { - const defErrors = def.validate ? def.validate() : []; - errors.push(...defErrors); - }); - - // Validate each fact - this.facts.forEach(fact => { - const factErrors = fact.validate ? fact.validate() : []; - errors.push(...factErrors); - }); - - // Validate each evidence - this.evidence.forEach(ev => { - const evErrors = ev.validate ? ev.validate() : []; - errors.push(...evErrors); - }); - - // Validate each measure - this.measures.forEach(measure => { - const measureErrors = measure.validate ? measure.validate() : []; - errors.push(...measureErrors); - }); - - return { errors, warnings, isValid: errors.length === 0 }; - } - - toString() { - return `Program(${this.definitions.length} definitions, ${this.facts.length} facts, ${this.evidence.length} evidence, ${this.measures.length} measures)`; - } -} diff --git a/src/ast/nodes/SourceNode.js b/src/ast/nodes/SourceNode.js deleted file mode 100644 index e85b863..0000000 --- a/src/ast/nodes/SourceNode.js +++ /dev/null @@ -1,87 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for source definitions - * Represents: source *mfa(user: User) PROVIDES Proof within 10m - * - * Sources are injectable object/proof references that must be - * provided in the partial graph before authorization evaluation. - * They always carry a PROVIDES type and an optional freshness window. - */ -export class SourceNode extends BaseNode { - constructor(name, location = null) { - super('Source', location); - this.name = name; - this.injectable = false; - this.parameters = []; - this.returnType = null; - this.provides = null; - this.within = null; - this.cacheDirective = null; - } - - addParameter(parameter) { - this.parameters.push(parameter); - this.addChild(parameter); - } - - setReturnType(returnType) { - this.returnType = returnType; - this.provides = returnType; - } - - setWithin(within) { - this.within = within; - } - - setCacheDirective(directive) { - this.cacheDirective = directive; - } - - setInjectable(value) { - this.injectable = !!value; - } - - getParameterNames() { - return this.parameters.map(param => param.name); - } - - getParameterTypes() { - return this.parameters.map(param => param.type); - } - - getParameter(name) { - return this.parameters.find(param => param.name === name) || null; - } - - getSignature() { - const paramStr = this.parameters.map(param => `${param.name}: ${param.type}`).join(', '); - return `${this.name}(${paramStr})`; - } - - hasReturnType() { - return this.returnType !== null; - } - - validate() { - const errors = []; - - if (!this.name || typeof this.name !== 'string') { - errors.push(`Invalid source name: ${this.name}`); - } - - this.parameters.forEach((param, index) => { - const paramErrors = param.validate ? param.validate() : []; - errors.push(...paramErrors.map(err => `Parameter ${index + 1}: ${err}`)); - }); - - return errors; - } - - toString() { - const injectableStr = this.injectable ? '*' : ''; - const providesStr = this.returnType ? ` PROVIDES ${this.returnType}` : ''; - const withinStr = this.within ? ` within ${this.within.value}` : ''; - return `Source(${injectableStr}${this.getSignature()}${providesStr}${withinStr})`; - } -} diff --git a/src/ast/nodes/WithClauseNode.js b/src/ast/nodes/WithClauseNode.js deleted file mode 100644 index 281d9ee..0000000 --- a/src/ast/nodes/WithClauseNode.js +++ /dev/null @@ -1,154 +0,0 @@ -import { BaseNode } from './BaseNode.js'; - -/** - * AST node for with clauses in pattern matching - * Represents: with similarity > 0.7 - */ -export class WithClauseNode extends BaseNode { - constructor(location = null) { - super('WithClause', location); - this.condition = null; // ExpressionNode - this.operator = null; // '>', '>=', '<', '<=', '==', '!=' - this.value = null; // Literal value - } - - /** - * Set the condition for this with clause - * @param {ExpressionNode} condition - Condition to set - */ - setCondition(condition) { - this.condition = condition; - this.addChild(condition); - } - - /** - * Set the operator for this with clause - * @param {string} operator - Operator to set - */ - setOperator(operator) { - this.operator = operator; - } - - /** - * Set the value for this with clause - * @param {*} value - Value to set - */ - setValue(value) { - this.value = value; - } - - /** - * Get the condition expression - * @returns {ExpressionNode|null} Condition expression or null - */ - getCondition() { - return this.condition; - } - - /** - * Get the operator - * @returns {string|null} Operator or null - */ - getOperator() { - return this.operator; - } - - /** - * Get the value - * @returns {*} Value or null - */ - getValue() { - return this.value; - } - - /** - * Check if this is a greater than comparison - * @returns {boolean} True if greater than - */ - isGreaterThan() { - return this.operator === '>'; - } - - /** - * Check if this is a greater than or equal comparison - * @returns {boolean} True if greater than or equal - */ - isGreaterThanOrEqual() { - return this.operator === '>='; - } - - /** - * Check if this is a less than comparison - * @returns {boolean} True if less than - */ - isLessThan() { - return this.operator === '<'; - } - - /** - * Check if this is a less than or equal comparison - * @returns {boolean} True if less than or equal - */ - isLessThanOrEqual() { - return this.operator === '<='; - } - - /** - * Check if this is an equality comparison - * @returns {boolean} True if equality - */ - isEqual() { - return this.operator === '=='; - } - - /** - * Check if this is a not equal comparison - * @returns {boolean} True if not equal - */ - isNotEqual() { - return this.operator === '!='; - } - - /** - * Get the comparison string - * @returns {string} Comparison string - */ - getComparisonString() { - const condStr = this.condition ? this.condition.toString() : 'null'; - const valStr = this.value !== null ? this.value.toString() : 'null'; - return `${condStr} ${this.operator} ${valStr}`; - } - - /** - * Validate the with clause - * @returns {string[]} Array of error messages - */ - validate() { - const errors = []; - - // Validate condition - if (!this.condition) { - errors.push('With clause must have a condition'); - } else { - const condErrors = this.condition.validate ? this.condition.validate() : []; - errors.push(...condErrors); - } - - // Validate operator - const validOperators = ['>', '>=', '<', '<=', '==', '!=']; - if (!this.operator || !validOperators.includes(this.operator)) { - errors.push(`Invalid operator: ${this.operator}`); - } - - // Validate value - if (this.value === null) { - errors.push('With clause must have a value'); - } - - return errors; - } - - toString() { - return `WithClause(${this.getComparisonString()})`; - } -} diff --git a/src/ast/nodes/index.js b/src/ast/nodes/index.js deleted file mode 100644 index 77baaf8..0000000 --- a/src/ast/nodes/index.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * AST Node exports - * Central export file for all AST node classes - */ - -export { BaseNode } from './BaseNode.js'; -export { ProgramNode } from './ProgramNode.js'; -export { DefinitionNode } from './DefinitionNode.js'; -export { FieldNode } from './FieldNode.js'; -export { BehaviorNode } from './BehaviorNode.js'; -export { FactNode } from './FactNode.js'; -export { ParameterNode } from './ParameterNode.js'; -export { EvidenceNode } from './EvidenceNode.js'; -export { EvidenceBodyNode } from './EvidenceBodyNode.js'; -export { DirectEvidenceNode } from './DirectEvidenceNode.js'; -export { PatternMatchNode } from './PatternMatchNode.js'; -export { DefeasibleLogicNode } from './DefeasibleLogicNode.js'; -export { FusionNode } from './FusionNode.js'; -export { PredicateNode } from './PredicateNode.js'; -export { ExpressionNode } from './ExpressionNode.js'; -export { WithClauseNode } from './WithClauseNode.js'; -export { MeasureNode } from './MeasureNode.js'; -export { MeasureBodyNode } from './MeasureBodyNode.js'; -export { AggregationNode } from './AggregationNode.js'; diff --git a/src/ast/parser/DSLParser.js b/src/ast/parser/DSLParser.js deleted file mode 100644 index 7477947..0000000 --- a/src/ast/parser/DSLParser.js +++ /dev/null @@ -1,4998 +0,0 @@ -// @generated by Peggy 5.0.6. -// -// https://peggyjs.org/ - - -class peg$SyntaxError extends SyntaxError { - constructor(message, expected, found, location) { - super(message); - this.expected = expected; - this.found = found; - this.location = location; - this.name = "SyntaxError"; - } - - format(sources) { - let str = "Error: " + this.message; - if (this.location) { - let src = null; - const st = sources.find(s => s.source === this.location.source); - if (st) { - src = st.text.split(/\r\n|\n|\r/g); - } - const s = this.location.start; - const offset_s = (this.location.source && (typeof this.location.source.offset === "function")) - ? this.location.source.offset(s) - : s; - const loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column; - if (src) { - const e = this.location.end; - const filler = "".padEnd(offset_s.line.toString().length, " "); - const line = src[s.line - 1]; - const last = s.line === e.line ? e.column : line.length + 1; - const hatLen = (last - s.column) || 1; - str += "\n --> " + loc + "\n" - + filler + " |\n" - + offset_s.line + " | " + line + "\n" - + filler + " | " + "".padEnd(s.column - 1, " ") - + "".padEnd(hatLen, "^"); - } else { - str += "\n at " + loc; - } - } - return str; - } - - static buildMessage(expected, found) { - function hex(ch) { - return ch.codePointAt(0).toString(16).toUpperCase(); - } - - const nonPrintable = Object.prototype.hasOwnProperty.call(RegExp.prototype, "unicode") - ? new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]", "gu") - : null; - function unicodeEscape(s) { - if (nonPrintable) { - return s.replace(nonPrintable, ch => "\\u{" + hex(ch) + "}"); - } - return s; - } - - function literalEscape(s) { - return unicodeEscape(s - .replace(/\\/g, "\\\\") - .replace(/"/g, "\\\"") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) - .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); - } - - function classEscape(s) { - return unicodeEscape(s - .replace(/\\/g, "\\\\") - .replace(/\]/g, "\\]") - .replace(/\^/g, "\\^") - .replace(/-/g, "\\-") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) - .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); - } - - const DESCRIBE_EXPECTATION_FNS = { - literal(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; - }, - - class(expectation) { - const escapedParts = expectation.parts.map( - part => (Array.isArray(part) - ? classEscape(part[0]) + "-" + classEscape(part[1]) - : classEscape(part)) - ); - - return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]" + (expectation.unicode ? "u" : ""); - }, - - any() { - return "any character"; - }, - - end() { - return "end of input"; - }, - - other(expectation) { - return expectation.description; - }, - }; - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - const descriptions = expected.map(describeExpectation); - descriptions.sort(); - - if (descriptions.length > 0) { - let j = 1; - for (let i = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; - } - } - - function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; - } - - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; - } -} - -function peg$parse(input, options) { - options = options !== undefined ? options : {}; - - const peg$FAILED = {}; - const peg$source = options.grammarSource; - - const peg$startRuleFunctions = { - Program: peg$parseProgram, - }; - let peg$startRuleFunction = peg$parseProgram; - - const peg$c0 = "definition"; - const peg$c1 = "type"; - const peg$c2 = "{"; - const peg$c3 = "}"; - const peg$c4 = ":"; - const peg$c5 = "[]"; - const peg$c6 = "fact"; - const peg$c7 = "relation"; - const peg$c8 = "("; - const peg$c9 = ")"; - const peg$c10 = "evidence"; - const peg$c11 = "!"; - const peg$c12 = "measure"; - const peg$c13 = "return"; - const peg$c14 = "NEVER"; - const peg$c15 = "ALWAYS"; - const peg$c16 = "REQUIRES"; - const peg$c17 = "WHEN"; - const peg$c18 = "UNLESS"; - const peg$c19 = "|"; - const peg$c20 = "fusion"; - const peg$c21 = ","; - const peg$c22 = "*"; - const peg$c23 = "with"; - const peg$c24 = "aggregate"; - const peg$c25 = "USING"; - const peg$c26 = "PROVIDES"; - const peg$c27 = "BEHAVES"; - const peg$c28 = "AS"; - const peg$c29 = "edge"; - const peg$c30 = "transitive"; - const peg$c31 = "hierarchical"; - const peg$c32 = "symmetrical_graph"; - const peg$c33 = "symmetrical"; - const peg$c34 = "limit"; - const peg$c35 = "decaying"; - const peg$c36 = "up"; - const peg$c37 = "down"; - const peg$c38 = "neutral"; - const peg$c39 = "stable"; - const peg$c40 = "hourly"; - const peg$c41 = "daily"; - const peg$c42 = "weekly"; - const peg$c43 = "monthly"; - const peg$c44 = "blurring"; - const peg$c45 = "fixed"; - const peg$c46 = "adaptive"; - const peg$c47 = "confidence"; - const peg$c48 = "confidence_90"; - const peg$c49 = "confidence_95"; - const peg$c50 = "confidence_99"; - const peg$c51 = "ttl"; - const peg$c52 = "CACHE"; - const peg$c53 = "eager"; - const peg$c54 = "lazy"; - const peg$c55 = "||"; - const peg$c56 = "&&"; - const peg$c57 = "is"; - const peg$c58 = "=="; - const peg$c59 = "!="; - const peg$c60 = ">="; - const peg$c61 = "<="; - const peg$c62 = "within"; - const peg$c63 = "NOT"; - const peg$c64 = "."; - const peg$c65 = "\""; - const peg$c66 = "\\"; - const peg$c67 = "'"; - const peg$c68 = "true"; - const peg$c69 = "false"; - const peg$c70 = "//"; - const peg$c71 = "/*"; - const peg$c72 = "*/"; - - const peg$r0 = /^[<>]/; - const peg$r1 = /^[+\-]/; - const peg$r2 = /^[*\/]/; - const peg$r3 = /^["\\]/; - const peg$r4 = /^['\\]/; - const peg$r5 = /^[0-9]/; - const peg$r6 = /^[dhmw]/; - const peg$r7 = /^[a-zA-Z_]/; - const peg$r8 = /^[a-zA-Z0-9_]/; - const peg$r9 = /^[ \t\r\n]/; - const peg$r10 = /^[^\r\n]/; - - const peg$e0 = peg$otherExpectation("A type definition"); - const peg$e1 = peg$literalExpectation("definition", false); - const peg$e2 = peg$literalExpectation("type", false); - const peg$e3 = peg$literalExpectation("{", false); - const peg$e4 = peg$literalExpectation("}", false); - const peg$e5 = peg$literalExpectation(":", false); - const peg$e6 = peg$literalExpectation("[]", false); - const peg$e7 = peg$otherExpectation("A statement of fact (or relation in ADR-000)"); - const peg$e8 = peg$literalExpectation("fact", false); - const peg$e9 = peg$literalExpectation("relation", false); - const peg$e10 = peg$literalExpectation("(", false); - const peg$e11 = peg$literalExpectation(")", false); - const peg$e12 = peg$otherExpectation("An evidence rule"); - const peg$e13 = peg$literalExpectation("evidence", false); - const peg$e14 = peg$literalExpectation("!", false); - const peg$e15 = peg$otherExpectation("A derived measurement or value"); - const peg$e16 = peg$literalExpectation("measure", false); - const peg$e17 = peg$literalExpectation("return", false); - const peg$e18 = peg$literalExpectation("NEVER", false); - const peg$e19 = peg$literalExpectation("ALWAYS", false); - const peg$e20 = peg$literalExpectation("REQUIRES", false); - const peg$e21 = peg$literalExpectation("WHEN", false); - const peg$e22 = peg$literalExpectation("UNLESS", false); - const peg$e23 = peg$literalExpectation("|", false); - const peg$e24 = peg$literalExpectation("fusion", false); - const peg$e25 = peg$literalExpectation(",", false); - const peg$e26 = peg$literalExpectation("*", false); - const peg$e27 = peg$literalExpectation("with", false); - const peg$e28 = peg$literalExpectation("aggregate", false); - const peg$e29 = peg$literalExpectation("USING", false); - const peg$e30 = peg$literalExpectation("PROVIDES", false); - const peg$e31 = peg$literalExpectation("BEHAVES", false); - const peg$e32 = peg$literalExpectation("AS", false); - const peg$e33 = peg$literalExpectation("edge", false); - const peg$e34 = peg$literalExpectation("transitive", false); - const peg$e35 = peg$literalExpectation("hierarchical", false); - const peg$e36 = peg$literalExpectation("symmetrical_graph", false); - const peg$e37 = peg$literalExpectation("symmetrical", false); - const peg$e38 = peg$literalExpectation("limit", false); - const peg$e39 = peg$literalExpectation("decaying", false); - const peg$e40 = peg$literalExpectation("up", false); - const peg$e41 = peg$literalExpectation("down", false); - const peg$e42 = peg$literalExpectation("neutral", false); - const peg$e43 = peg$literalExpectation("stable", false); - const peg$e44 = peg$literalExpectation("hourly", false); - const peg$e45 = peg$literalExpectation("daily", false); - const peg$e46 = peg$literalExpectation("weekly", false); - const peg$e47 = peg$literalExpectation("monthly", false); - const peg$e48 = peg$literalExpectation("blurring", false); - const peg$e49 = peg$literalExpectation("fixed", false); - const peg$e50 = peg$literalExpectation("adaptive", false); - const peg$e51 = peg$literalExpectation("confidence", false); - const peg$e52 = peg$literalExpectation("confidence_90", false); - const peg$e53 = peg$literalExpectation("confidence_95", false); - const peg$e54 = peg$literalExpectation("confidence_99", false); - const peg$e55 = peg$literalExpectation("ttl", false); - const peg$e56 = peg$literalExpectation("CACHE", false); - const peg$e57 = peg$literalExpectation("eager", false); - const peg$e58 = peg$literalExpectation("lazy", false); - const peg$e59 = peg$literalExpectation("||", false); - const peg$e60 = peg$literalExpectation("&&", false); - const peg$e61 = peg$literalExpectation("is", false); - const peg$e62 = peg$literalExpectation("==", false); - const peg$e63 = peg$literalExpectation("!=", false); - const peg$e64 = peg$literalExpectation(">=", false); - const peg$e65 = peg$literalExpectation("<=", false); - const peg$e66 = peg$classExpectation(["<", ">"], false, false, false); - const peg$e67 = peg$literalExpectation("within", false); - const peg$e68 = peg$classExpectation(["+", "-"], false, false, false); - const peg$e69 = peg$classExpectation(["*", "/"], false, false, false); - const peg$e70 = peg$literalExpectation("NOT", false); - const peg$e71 = peg$literalExpectation(".", false); - const peg$e72 = peg$otherExpectation("The non-recursive base for an expression chain"); - const peg$e73 = peg$otherExpectation("A string literal"); - const peg$e74 = peg$literalExpectation("\"", false); - const peg$e75 = peg$classExpectation(["\"", "\\"], false, false, false); - const peg$e76 = peg$anyExpectation(); - const peg$e77 = peg$literalExpectation("\\", false); - const peg$e78 = peg$literalExpectation("'", false); - const peg$e79 = peg$classExpectation(["'", "\\"], false, false, false); - const peg$e80 = peg$otherExpectation("A floating-point number"); - const peg$e81 = peg$classExpectation([["0", "9"]], false, false, false); - const peg$e82 = peg$otherExpectation("An integer"); - const peg$e83 = peg$otherExpectation("A boolean literal"); - const peg$e84 = peg$literalExpectation("true", false); - const peg$e85 = peg$literalExpectation("false", false); - const peg$e86 = peg$otherExpectation("A time duration literal"); - const peg$e87 = peg$classExpectation(["d", "h", "m", "w"], false, false, false); - const peg$e88 = peg$classExpectation([["a", "z"], ["A", "Z"], "_"], false, false, false); - const peg$e89 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_"], false, false, false); - const peg$e90 = peg$classExpectation([" ", "\t", "\r", "\n"], false, false, false); - const peg$e91 = peg$literalExpectation("//", false); - const peg$e92 = peg$classExpectation(["\r", "\n"], true, false, false); - const peg$e93 = peg$literalExpectation("/*", false); - const peg$e94 = peg$literalExpectation("*/", false); - - function peg$f0(statements) { - const allStatements = statements.map(s => s[0]); - return { - type: "Program", - body: allStatements, - definitions: allStatements.filter(s => s.type === "Definition"), - facts: allStatements.filter(s => s.type === "Fact"), - evidence: allStatements.filter(s => s.type === "Evidence"), - measures: allStatements.filter(s => s.type === "Measure") - }; - } - function peg$f1(name, fields) { - return { type: "Definition", name, fields: fields.map(f => f[0]) }; - } - function peg$f2(name, fieldType, isArray, behavior, cache) { - return { - type: "Field", - name, - fieldType, - isArray: !!isArray, - behavior: behavior || null, - cache: cache || null - }; - } - function peg$f3(name, params, behavior, properties, cache, limit) { - return { - type: "Fact", - name, - params: params || [], - behavior: behavior || null, - properties: properties.map(p => p[0]), - cache: cache || null, - limit: limit || null - }; - } - function peg$f4(bang, name, params, limit, body, provides) { - return { - type: "Evidence", - name, - params: params || [], - limit: limit || null, - body, - provides: provides || null, - challenge: !!bang - }; - } - function peg$f5(name, params, body, provides) { - return { - type: "Measure", - name, - params: params || [], - body, - provides: provides || null - }; - } - function peg$f6(statements) { - return { type: "EvidenceBody", statements: statements.map(s => s[0]) }; - } - function peg$f7(statements, returnStmt) { - return { - type: "MeasureBody", - statements: statements.map(s => s[0]), - returnStatement: returnStmt || null - }; - } - function peg$f8(expression) { - return { type: "ReturnStatement", expression }; - } - function peg$f9(type, condition) { - return { type: "DefeasibleLogic", logicType: type, condition }; - } - function peg$f10(condition, defeater) { - return { type: "DefeasibleLogic", logicType: "WHEN", condition, defeater }; - } - function peg$f11(condition) { - return { type: "DefeasibleLogic", logicType: "WHEN", condition }; - } - function peg$f12(predicate, binding, body, limit, withClause) { - return { - type: "PatternMatch", - predicate, - binding: binding || null, - limit: limit || null, - body, - withClause: withClause || null - }; - } - function peg$f13(measure, variable, fusionStrategy, body, limit) { - return { - type: "CollectionProcessing", - measure, - variable, - fusion: fusionStrategy ? { strategy: fusionStrategy[1] } : null, - body, - limit: limit || null - }; - } - function peg$f14(name, args) { - return { type: "Predicate", name, args: args || [] }; - } - function peg$f15(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f16(name) { return { type: "Wildcard", name }; } - function peg$f17(name) { return name; } - function peg$f18(condition) { return condition; } - function peg$f19(strategy, expressions) { - return { type: "Fusion", strategy, expressions }; - } - function peg$f20(expressions, using) { - return { type: "Aggregation", expressions, using: using || null }; - } - function peg$f21(method) { return method; } - function peg$f22(name) { return { type: "TypeName", name }; } - function peg$f23(literal) { return { type: "TypeName", name: literal.value }; } - function peg$f24(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f25(name, paramType, isArray) { - return { type: "Parameter", name, paramType, isArray: !!isArray }; - } - function peg$f26(providesType) { return providesType; } - function peg$f27(behavior) { - return { type: "BehaviorAnnotation", behavior }; - } - function peg$f28() { return "transitive"; } - function peg$f29() { return "symmetrical"; } - function peg$f30(value) { return value; } - function peg$f31(b) { return b; } - function peg$f32(direction, period) { - return { type: "Behavior", behaviorType: "decay", direction, period }; - } - function peg$f33(mode, confidence) { - return { type: "Behavior", behaviorType: "blur", mode, confidence: confidence ? confidence[1] : null }; - } - function peg$f34(duration) { - return { type: "Behavior", behaviorType: "ttl", duration }; - } - function peg$f35(directive) { return directive; } - function peg$f36(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f37(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f38(head, typeName) { - return { type: "BinaryExpression", operator: "is", left: head, right: typeName }; - } - function peg$f39(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f40(head, right) { - return { type: "BinaryExpression", operator: "within", left: head, right }; - } - function peg$f41(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f42(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f43(operator, operand) { return { type: "UnaryExpression", operator: "NOT", operand }; } - function peg$f44(primary, binding) { - if (binding) { - return { type: "BindingAccess", expression: primary, binding }; - } - return primary; - } - function peg$f45(head, tail) { - return tail.reduce((obj, part) => { - return { - type: "AttributeAccess", - object: obj, - attribute: part[3], // The Identifier is the 4th element (index 3) - location: location() - }; - }, head); - } - function peg$f46(expr) { return expr; } - function peg$f47(name, args) { - return { type: "PredicateCall", name, args: args || [], challenge: true }; - } - function peg$f48(name, args) { - return { type: "PredicateCall", name, args: args || [] }; - } - function peg$f49(name) { return { type: "Variable", name }; } - function peg$f50(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f51(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f52(chars) { - return { type: "Literal", value: JSON.parse(text()) }; - } - function peg$f53(chars) { - return { type: "Literal", value: JSON.parse("\"" + chars.map(c => c[0] === '\\' ? c[1] : c[1]).join('') + "\"") }; - } - function peg$f54(value) { return { type: "Literal", value: parseFloat(text()) }; } - function peg$f55(value) { return { type: "Literal", value: parseInt(text(), 10) }; } - function peg$f56(value) { return { type: "Literal", value: value === "true" }; } - function peg$f57(value) { return { type: "Literal", value: text(), unit: text().slice(-1) }; } - function peg$f58(name) { return name; } - let peg$currPos = options.peg$currPos | 0; - let peg$savedPos = peg$currPos; - const peg$posDetailsCache = [{ line: 1, column: 1 }]; - let peg$maxFailPos = peg$currPos; - let peg$maxFailExpected = options.peg$maxFailExpected || []; - let peg$silentFails = options.peg$silentFails | 0; - - let peg$result; - - if (options.startRule) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function text() { - return input.substring(peg$savedPos, peg$currPos); - } - - function offset() { - return peg$savedPos; - } - - function range() { - return { - source: peg$source, - start: peg$savedPos, - end: peg$currPos, - }; - } - - function location() { - return peg$computeLocation(peg$savedPos, peg$currPos); - } - - function expected(description, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildStructuredError( - [peg$otherExpectation(description)], - input.substring(peg$savedPos, peg$currPos), - location - ); - } - - function error(message, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildSimpleError(message, location); - } - - function peg$getUnicode(pos = peg$currPos) { - const cp = input.codePointAt(pos); - if (cp === undefined) { - return ""; - } - return String.fromCodePoint(cp); - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text, ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase, unicode) { - return { type: "class", parts, inverted, ignoreCase, unicode }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$otherExpectation(description) { - return { type: "other", description }; - } - - function peg$computePosDetails(pos) { - let details = peg$posDetailsCache[pos]; - let p; - - if (details) { - return details; - } else { - if (pos >= peg$posDetailsCache.length) { - p = peg$posDetailsCache.length - 1; - } else { - p = pos; - while (!peg$posDetailsCache[--p]) {} - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column, - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - - return details; - } - } - - function peg$computeLocation(startPos, endPos, offset) { - const startPosDetails = peg$computePosDetails(startPos); - const endPosDetails = peg$computePosDetails(endPos); - - const res = { - source: peg$source, - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column, - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column, - }, - }; - if (offset && peg$source && (typeof peg$source.offset === "function")) { - res.start = peg$source.offset(res.start); - res.end = peg$source.offset(res.end); - } - return res; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildSimpleError(message, location) { - return new peg$SyntaxError(message, null, null, location); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError( - peg$SyntaxError.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parseProgram() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parse_(); - s2 = []; - s3 = peg$currPos; - s4 = peg$parseStatement(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parseStatement(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - s3 = peg$parse_(); - peg$savedPos = s0; - s0 = peg$f0(s2); - - return s0; - } - - function peg$parseStatement() { - let s0; - - s0 = peg$parseDefinition(); - if (s0 === peg$FAILED) { - s0 = peg$parseFact(); - if (s0 === peg$FAILED) { - s0 = peg$parseEvidence(); - if (s0 === peg$FAILED) { - s0 = peg$parseMeasure(); - } - } - } - - return s0; - } - - function peg$parseDefinition() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 10) === peg$c0) { - s1 = peg$c0; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c1) { - s1 = peg$c1; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = []; - s8 = peg$currPos; - s9 = peg$parseField(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s9 = [s9, s10]; - s8 = s9; - } else { - peg$currPos = s8; - s8 = peg$FAILED; - } - while (s8 !== peg$FAILED) { - s7.push(s8); - s8 = peg$currPos; - s9 = peg$parseField(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s9 = [s9, s10]; - s8 = s9; - } else { - peg$currPos = s8; - s8 = peg$FAILED; - } - } - if (input.charCodeAt(peg$currPos) === 125) { - s8 = peg$c3; - peg$currPos++; - } else { - s8 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s8 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f1(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e0); } - } - - return s0; - } - - function peg$parseField() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c4; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c5) { - s7 = peg$c5; - peg$currPos += 2; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - s8 = peg$parse_(); - s9 = peg$parseBehavior(); - if (s9 === peg$FAILED) { - s9 = null; - } - s10 = peg$parse_(); - s11 = peg$parseCacheDirective(); - if (s11 === peg$FAILED) { - s11 = null; - } - peg$savedPos = s0; - s0 = peg$f2(s1, s5, s7, s9, s11); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseFact() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c6) { - s1 = peg$c6; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c7) { - s1 = peg$c7; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s5 = peg$c8; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameterList(); - if (s7 === peg$FAILED) { - s7 = null; - } - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c9; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s11 = peg$parseBehaviorAnnotation(); - if (s11 === peg$FAILED) { - s11 = null; - } - s12 = peg$parse_(); - s13 = []; - s14 = peg$currPos; - s15 = peg$parseFactProperty(); - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s15 = [s15, s16]; - s14 = s15; - } else { - peg$currPos = s14; - s14 = peg$FAILED; - } - while (s14 !== peg$FAILED) { - s13.push(s14); - s14 = peg$currPos; - s15 = peg$parseFactProperty(); - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s15 = [s15, s16]; - s14 = s15; - } else { - peg$currPos = s14; - s14 = peg$FAILED; - } - } - s14 = peg$parseCacheDirective(); - if (s14 === peg$FAILED) { - s14 = null; - } - s15 = peg$parse_(); - s16 = peg$parseLimit(); - if (s16 === peg$FAILED) { - s16 = null; - } - peg$savedPos = s0; - s0 = peg$f3(s3, s7, s11, s13, s14, s16); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } - } - - return s0; - } - - function peg$parseEvidence() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c10) { - s1 = peg$c10; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e13); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 33) { - s3 = peg$c11; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } - } - if (s3 === peg$FAILED) { - s3 = null; - } - s4 = peg$parseIdentifier(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s6 = peg$c8; - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - s8 = peg$parseParameterList(); - if (s8 === peg$FAILED) { - s8 = null; - } - s9 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s10 = peg$c9; - peg$currPos++; - } else { - s10 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s10 !== peg$FAILED) { - s11 = peg$parse_(); - s12 = peg$parseLimit(); - if (s12 === peg$FAILED) { - s12 = null; - } - s13 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s14 = peg$c2; - peg$currPos++; - } else { - s14 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s14 !== peg$FAILED) { - s15 = peg$parse_(); - s16 = peg$parseEvidenceBody(); - s17 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s18 = peg$c3; - peg$currPos++; - } else { - s18 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s18 !== peg$FAILED) { - s19 = peg$parse_(); - s20 = peg$parseProvides(); - if (s20 === peg$FAILED) { - s20 = null; - } - peg$savedPos = s0; - s0 = peg$f4(s3, s4, s8, s12, s16, s20); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - - return s0; - } - - function peg$parseMeasure() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 7) === peg$c12) { - s1 = peg$c12; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s5 = peg$c8; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameterList(); - if (s7 === peg$FAILED) { - s7 = null; - } - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c9; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s11 = peg$c2; - peg$currPos++; - } else { - s11 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - s13 = peg$parseMeasureBody(); - s14 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s15 = peg$c3; - peg$currPos++; - } else { - s15 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s17 = peg$parseProvides(); - if (s17 === peg$FAILED) { - s17 = null; - } - peg$savedPos = s0; - s0 = peg$f5(s3, s7, s13, s17); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e15); } - } - - return s0; - } - - function peg$parseEvidenceBody() { - let s0, s1, s2, s3, s4; - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseEvidenceStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseEvidenceStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - peg$savedPos = s0; - s1 = peg$f6(s1); - s0 = s1; - - return s0; - } - - function peg$parseEvidenceStatement() { - let s0; - - s0 = peg$parseDefeasibleLogic(); - if (s0 === peg$FAILED) { - s0 = peg$parseFusion(); - if (s0 === peg$FAILED) { - s0 = peg$parseCollectionProcessing(); - if (s0 === peg$FAILED) { - s0 = peg$parsePatternMatch(); - if (s0 === peg$FAILED) { - s0 = peg$parseLogicalOr(); - } - } - } - } - - return s0; - } - - function peg$parseMeasureBody() { - let s0, s1, s2, s3, s4; - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseMeasureStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseMeasureStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - s2 = peg$parseReturnStatement(); - if (s2 === peg$FAILED) { - s2 = null; - } - peg$savedPos = s0; - s0 = peg$f7(s1, s2); - - return s0; - } - - function peg$parseMeasureStatement() { - let s0; - - s0 = peg$parseFusion(); - if (s0 === peg$FAILED) { - s0 = peg$parseAggregation(); - if (s0 === peg$FAILED) { - s0 = peg$parsePatternMatch(); - if (s0 === peg$FAILED) { - s0 = peg$parseLogicalOr(); - } - } - } - - return s0; - } - - function peg$parseReturnStatement() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c13) { - s1 = peg$c13; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e17); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f8(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseDefeasibleLogic() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c14) { - s1 = peg$c14; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c15) { - s1 = peg$c15; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e19); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c16) { - s1 = peg$c16; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } - } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f9(s1, s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c17) { - s1 = peg$c17; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c18) { - s5 = peg$c18; - peg$currPos += 6; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e22); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse__(); - if (s6 !== peg$FAILED) { - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f10(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c17) { - s1 = peg$c17; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f11(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - - return s0; - } - - function peg$parsePatternMatch() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; - - s0 = peg$currPos; - s1 = peg$parsePatternPredicate(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseBindingClause(); - if (s3 === peg$FAILED) { - s3 = null; - } - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseEvidenceBody(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s9 = peg$c3; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s11 = peg$parseLimit(); - if (s11 === peg$FAILED) { - s11 = null; - } - s12 = peg$parse_(); - s13 = peg$parseWithClause(); - if (s13 === peg$FAILED) { - s13 = null; - } - peg$savedPos = s0; - s0 = peg$f12(s1, s3, s7, s11, s13); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseCollectionProcessing() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17; - - s0 = peg$currPos; - s1 = peg$parseLogicalOr(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 124) { - s3 = peg$c19; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 124) { - s7 = peg$c19; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - s9 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c20) { - s10 = peg$c20; - peg$currPos += 6; - } else { - s10 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - if (s10 !== peg$FAILED) { - s11 = peg$parse__(); - if (s11 !== peg$FAILED) { - s12 = peg$parseIdentifier(); - if (s12 !== peg$FAILED) { - s10 = [s10, s11, s12]; - s9 = s10; - } else { - peg$currPos = s9; - s9 = peg$FAILED; - } - } else { - peg$currPos = s9; - s9 = peg$FAILED; - } - } else { - peg$currPos = s9; - s9 = peg$FAILED; - } - if (s9 === peg$FAILED) { - s9 = null; - } - s10 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s11 = peg$c2; - peg$currPos++; - } else { - s11 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - s13 = peg$parseEvidenceBody(); - if (s13 !== peg$FAILED) { - s14 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s15 = peg$c3; - peg$currPos++; - } else { - s15 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s17 = peg$parseLimit(); - if (s17 === peg$FAILED) { - s17 = null; - } - peg$savedPos = s0; - s0 = peg$f13(s1, s5, s9, s13, s17); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePatternPredicate() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s3 = peg$c8; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parsePatternArgumentList(); - if (s5 === peg$FAILED) { - s5 = null; - } - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s7 = peg$c9; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f14(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePatternArgumentList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parsePatternArgument(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parsePatternArgument(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parsePatternArgument(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f15(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePatternArgument() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c22; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f16(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parseLogicalOr(); - } - - return s0; - } - - function peg$parseBindingClause() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 124) { - s1 = peg$c19; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 124) { - s5 = peg$c19; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f17(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseWithClause() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c23) { - s1 = peg$c23; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e27); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f18(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseFusion() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c20) { - s1 = peg$c20; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseExpressionList(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s9 = peg$c3; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s9 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f19(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseAggregation() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 9) === peg$c24) { - s1 = peg$c24; - peg$currPos += 9; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e28); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s3 = peg$c2; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseExpressionList(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s7 = peg$c3; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - s9 = peg$parseUsing(); - if (s9 === peg$FAILED) { - s9 = null; - } - peg$savedPos = s0; - s0 = peg$f20(s5, s9); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseUsing() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c25) { - s1 = peg$c25; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f21(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseTypeName() { - let s0, s1; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f22(s1); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseString(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f23(s1); - } - s0 = s1; - } - - return s0; - } - - function peg$parseParameterList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseParameter(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameter(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameter(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f24(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseParameter() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c4; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c5) { - s7 = peg$c5; - peg$currPos += 2; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - peg$savedPos = s0; - s0 = peg$f25(s1, s5, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseProvides() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c26) { - s1 = peg$c26; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e30); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f26(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBehaviorAnnotation() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 7) === peg$c27) { - s1 = peg$c27; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e31); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c28) { - s3 = peg$c28; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e32); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c29) { - s5 = peg$c29; - peg$currPos += 4; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e33); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c30) { - s5 = peg$c30; - peg$currPos += 10; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 12) === peg$c31) { - s5 = peg$c31; - peg$currPos += 12; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e35); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 17) === peg$c32) { - s5 = peg$c32; - peg$currPos += 17; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } - } - } - } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f27(s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseFactProperty() { - let s0, s1; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 10) === peg$c30) { - s1 = peg$c30; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f28(); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 11) === peg$c33) { - s1 = peg$c33; - peg$currPos += 11; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f29(); - } - s0 = s1; - } - - return s0; - } - - function peg$parseLimit() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c34) { - s1 = peg$c34; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e38); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseInteger(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f30(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBehavior() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 7) === peg$c27) { - s1 = peg$c27; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e31); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s3 = peg$c2; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseDecayBehavior(); - if (s5 === peg$FAILED) { - s5 = peg$parseBlurBehavior(); - if (s5 === peg$FAILED) { - s5 = peg$parseTTLBehavior(); - } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s7 = peg$c3; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f31(s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseDecayBehavior() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c35) { - s1 = peg$c35; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e39); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c36) { - s3 = peg$c36; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e40); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c37) { - s3 = peg$c37; - peg$currPos += 4; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e41); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c38) { - s3 = peg$c38; - peg$currPos += 7; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e42); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c39) { - s3 = peg$c39; - peg$currPos += 6; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e43); } - } - } - } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c40) { - s5 = peg$c40; - peg$currPos += 6; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e44); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c41) { - s5 = peg$c41; - peg$currPos += 5; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e45); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c42) { - s5 = peg$c42; - peg$currPos += 6; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e46); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c43) { - s5 = peg$c43; - peg$currPos += 7; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e47); } - } - } - } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f32(s3, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBlurBehavior() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c44) { - s1 = peg$c44; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e48); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c45) { - s3 = peg$c45; - peg$currPos += 5; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e49); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c46) { - s3 = peg$c46; - peg$currPos += 8; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e50); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c47) { - s3 = peg$c47; - peg$currPos += 10; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e51); } - } - } - } - if (s3 !== peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse__(); - if (s5 !== peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c48) { - s6 = peg$c48; - peg$currPos += 13; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e52); } - } - if (s6 === peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c49) { - s6 = peg$c49; - peg$currPos += 13; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e53); } - } - if (s6 === peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c50) { - s6 = peg$c50; - peg$currPos += 13; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e54); } - } - } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = null; - } - peg$savedPos = s0; - s0 = peg$f33(s3, s4); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseTTLBehavior() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c51) { - s1 = peg$c51; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e55); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseDuration(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f34(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseCacheDirective() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c52) { - s1 = peg$c52; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e56); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c53) { - s3 = peg$c53; - peg$currPos += 5; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e57); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c54) { - s3 = peg$c54; - peg$currPos += 4; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e58); } - } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f35(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLogicalOr() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseLogicalAnd(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c55) { - s5 = peg$c55; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e59); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalAnd(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c55) { - s5 = peg$c55; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e59); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalAnd(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f36(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLogicalAnd() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseComparison(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c56) { - s5 = peg$c56; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e60); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c56) { - s5 = peg$c56; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e60); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f37(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseComparison() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseTemporalComparison(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c57) { - s3 = peg$c57; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e61); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - s5 = peg$parseTypeName(); - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f38(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseTemporalComparison(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c58) { - s5 = peg$c58; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e62); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c59) { - s5 = peg$c59; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e63); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c60) { - s5 = peg$c60; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e64); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c61) { - s5 = peg$c61; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e65); } - } - if (s5 === peg$FAILED) { - s5 = input.charAt(peg$currPos); - if (peg$r0.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e66); } - } - } - } - } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseTemporalComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c58) { - s5 = peg$c58; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e62); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c59) { - s5 = peg$c59; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e63); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c60) { - s5 = peg$c60; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e64); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c61) { - s5 = peg$c61; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e65); } - } - if (s5 === peg$FAILED) { - s5 = input.charAt(peg$currPos); - if (peg$r0.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e66); } - } - } - } - } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseTemporalComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f39(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - return s0; - } - - function peg$parseTemporalComparison() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parseAddition(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.substr(peg$currPos, 6) === peg$c62) { - s3 = peg$c62; - peg$currPos += 6; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e67); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - s5 = peg$parseDuration(); - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f40(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parseAddition(); - } - - return s0; - } - - function peg$parseAddition() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseMultiplication(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = input.charAt(peg$currPos); - if (peg$r1.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e68); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseMultiplication(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = input.charAt(peg$currPos); - if (peg$r1.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e68); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseMultiplication(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f41(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseMultiplication() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseUnary(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = input.charAt(peg$currPos); - if (peg$r2.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e69); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseUnary(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = input.charAt(peg$currPos); - if (peg$r2.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e69); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseUnary(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f42(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseUnary() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c63) { - s1 = peg$c63; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e70); } - } - if (s1 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c11; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseUnary(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f43(s1, s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parsePostfix(); - } - - return s0; - } - - function peg$parsePostfix() { - let s0, s1, s2; - - s0 = peg$currPos; - s1 = peg$parseAttributeAccess(); - if (s1 === peg$FAILED) { - s1 = peg$parsePrimaryTerm(); - } - if (s1 !== peg$FAILED) { - s2 = peg$parseBindingClause(); - if (s2 === peg$FAILED) { - s2 = null; - } - peg$savedPos = s0; - s0 = peg$f44(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseAttributeAccess() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parsePrimaryTerm(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c64; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e71); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseIdentifier(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c64; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e71); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseIdentifier(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f45(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePrimaryTerm() { - let s0, s1, s2, s3, s4, s5; - - peg$silentFails++; - s0 = peg$parseChallengePredicate(); - if (s0 === peg$FAILED) { - s0 = peg$parseLiteral(); - if (s0 === peg$FAILED) { - s0 = peg$parsePredicateCall(); - if (s0 === peg$FAILED) { - s0 = peg$parseVariable(); - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c8; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c9; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f46(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e72); } - } - - return s0; - } - - function peg$parseChallengePredicate() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c11; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseIdentifier(); - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s4 = peg$c8; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s6 = peg$parseArgumentList(); - if (s6 === peg$FAILED) { - s6 = null; - } - s7 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s8 = peg$c9; - peg$currPos++; - } else { - s8 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s8 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f47(s2, s6); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePredicateCall() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 40) { - s2 = peg$c8; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - s4 = peg$parseArgumentList(); - if (s4 === peg$FAILED) { - s4 = null; - } - s5 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s6 = peg$c9; - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s6 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f48(s1, s4); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseVariable() { - let s0, s1; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f49(s1); - } - s0 = s1; - - return s0; - } - - function peg$parseArgumentList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseLogicalOr(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f50(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseExpressionList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseLogicalOr(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f51(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLiteral() { - let s0; - - s0 = peg$parseString(); - if (s0 === peg$FAILED) { - s0 = peg$parseFloat(); - if (s0 === peg$FAILED) { - s0 = peg$parseInteger(); - if (s0 === peg$FAILED) { - s0 = peg$parseBoolean(); - if (s0 === peg$FAILED) { - s0 = peg$parseDuration(); - } - } - } - } - - return s0; - } - - function peg$parseString() { - let s0, s1, s2, s3, s4, s5; - - peg$silentFails++; - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c65; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e74); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r3.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e75); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c66; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r3.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e75); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c66; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c65; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e74); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f52(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c67; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e78); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r4.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c66; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r4.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c66; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c67; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e78); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f53(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e73); } - } - - return s0; - } - - function peg$parseFloat() { - let s0, s1, s2, s3, s4, s5; - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s3 = peg$c64; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e71); } - } - if (s3 !== peg$FAILED) { - s4 = []; - s5 = input.charAt(peg$currPos); - if (peg$r5.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - s5 = input.charAt(peg$currPos); - if (peg$r5.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f54(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e80); } - } - - return s0; - } - - function peg$parseInteger() { - let s0, s1, s2; - - peg$silentFails++; - s0 = peg$currPos; - s1 = []; - s2 = input.charAt(peg$currPos); - if (peg$r5.test(s2)) { - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s2 !== peg$FAILED) { - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = input.charAt(peg$currPos); - if (peg$r5.test(s2)) { - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - } - } else { - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f55(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e82); } - } - - return s0; - } - - function peg$parseBoolean() { - let s0, s1; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c68) { - s1 = peg$c68; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c69) { - s1 = peg$c69; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e85); } - } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f56(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e83); } - } - - return s0; - } - - function peg$parseDuration() { - let s0, s1, s2, s3; - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s3 = input.charAt(peg$currPos); - if (peg$r6.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e87); } - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f57(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e86); } - } - - return s0; - } - - function peg$parseIdentifier() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - s1 = peg$currPos; - peg$silentFails++; - s2 = peg$parseKeyword(); - peg$silentFails--; - if (s2 === peg$FAILED) { - s1 = undefined; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = peg$currPos; - s4 = input.charAt(peg$currPos); - if (peg$r7.test(s4)) { - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e88); } - } - if (s4 !== peg$FAILED) { - s5 = []; - s6 = input.charAt(peg$currPos); - if (peg$r8.test(s6)) { - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e89); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - s6 = input.charAt(peg$currPos); - if (peg$r8.test(s6)) { - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e89); } - } - } - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f58(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseKeyword() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 10) === peg$c0) { - s1 = peg$c0; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c1) { - s1 = peg$c1; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c6) { - s1 = peg$c6; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c7) { - s1 = peg$c7; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c10) { - s1 = peg$c10; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e13); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c12) { - s1 = peg$c12; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c27) { - s1 = peg$c27; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e31); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c28) { - s1 = peg$c28; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e32); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c52) { - s1 = peg$c52; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e56); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c35) { - s1 = peg$c35; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e39); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c44) { - s1 = peg$c44; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e48); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c51) { - s1 = peg$c51; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e55); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c30) { - s1 = peg$c30; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 11) === peg$c33) { - s1 = peg$c33; - peg$currPos += 11; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 12) === peg$c31) { - s1 = peg$c31; - peg$currPos += 12; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e35); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 17) === peg$c32) { - s1 = peg$c32; - peg$currPos += 17; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c29) { - s1 = peg$c29; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e33); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c34) { - s1 = peg$c34; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e38); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c26) { - s1 = peg$c26; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e30); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c20) { - s1 = peg$c20; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 9) === peg$c24) { - s1 = peg$c24; - peg$currPos += 9; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e28); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c25) { - s1 = peg$c25; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c14) { - s1 = peg$c14; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c15) { - s1 = peg$c15; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e19); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c17) { - s1 = peg$c17; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c18) { - s1 = peg$c18; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e22); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c16) { - s1 = peg$c16; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c23) { - s1 = peg$c23; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e27); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c68) { - s1 = peg$c68; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c69) { - s1 = peg$c69; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e85); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c63) { - s1 = peg$c63; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e70); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c62) { - s1 = peg$c62; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e67); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c13) { - s1 = peg$c13; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e17); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c57) { - s1 = peg$c57; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e61); } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - peg$silentFails++; - s3 = input.charAt(peg$currPos); - if (peg$r8.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e89); } - } - peg$silentFails--; - if (s3 === peg$FAILED) { - s2 = undefined; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parse_() { - let s0, s1; - - s0 = []; - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - } - - return s0; - } - - function peg$parse__() { - let s0, s1; - - s0 = []; - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - if (s1 !== peg$FAILED) { - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - } - } else { - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseWhiteSpace() { - let s0; - - s0 = input.charAt(peg$currPos); - if (peg$r9.test(s0)) { - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e90); } - } - - return s0; - } - - function peg$parseComment() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c70) { - s1 = peg$c70; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e91); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r10.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e92); } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r10.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e92); } - } - } - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c71) { - s1 = peg$c71; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e93); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - if (input.substr(peg$currPos, 2) === peg$c72) { - s5 = peg$c72; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e94); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - if (input.substr(peg$currPos, 2) === peg$c72) { - s5 = peg$c72; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e94); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (input.substr(peg$currPos, 2) === peg$c72) { - s3 = peg$c72; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e94); } - } - if (s3 !== peg$FAILED) { - s1 = [s1, s2, s3]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - return s0; - } - - - // The location() function provides line/column info for error reporting. - // The text() function returns the matched text for a rule. - - // Helper function to build a left-associative binary expression tree. - function buildLeftAssoc(head, tail) { - return tail.reduce((result, element) => { - return { - type: "BinaryExpression", - operator: element[1], - left: result, - right: element[3], - location: location() - }; - }, head); - } - - peg$result = peg$startRuleFunction(); - - const peg$success = (peg$result !== peg$FAILED && peg$currPos === input.length); - function peg$throw() { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? peg$getUnicode(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } - if (options.peg$library) { - return /** @type {any} */ ({ - peg$result, - peg$currPos, - peg$FAILED, - peg$maxFailExpected, - peg$maxFailPos, - peg$success, - peg$throw: peg$success ? undefined : peg$throw, - }); - } - if (peg$success) { - return peg$result; - } else { - peg$throw(); - } -} - -const peg$allowedStartRules = [ - "Program" -]; - -export { - peg$allowedStartRules as StartRules, - peg$SyntaxError as SyntaxError, - peg$parse as parse -}; diff --git a/src/ast/parser/DslParser.js b/src/ast/parser/DslParser.js deleted file mode 100644 index f7260eb..0000000 --- a/src/ast/parser/DslParser.js +++ /dev/null @@ -1,4998 +0,0 @@ -// @generated by Peggy 5.1.0. -// -// https://peggyjs.org/ - - -class peg$SyntaxError extends SyntaxError { - constructor(message, expected, found, location) { - super(message); - this.expected = expected; - this.found = found; - this.location = location; - this.name = "SyntaxError"; - } - - format(sources) { - let str = "Error: " + this.message; - if (this.location) { - let src = null; - const st = sources.find(s => s.source === this.location.source); - if (st) { - src = st.text.split(/\r\n|\n|\r/g); - } - const s = this.location.start; - const offset_s = (this.location.source && (typeof this.location.source.offset === "function")) - ? this.location.source.offset(s) - : s; - const loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column; - if (src) { - const e = this.location.end; - const filler = "".padEnd(offset_s.line.toString().length, " "); - const line = src[s.line - 1]; - const last = s.line === e.line ? e.column : line.length + 1; - const hatLen = (last - s.column) || 1; - str += "\n --> " + loc + "\n" - + filler + " |\n" - + offset_s.line + " | " + line + "\n" - + filler + " | " + "".padEnd(s.column - 1, " ") - + "".padEnd(hatLen, "^"); - } else { - str += "\n at " + loc; - } - } - return str; - } - - static buildMessage(expected, found) { - function hex(ch) { - return ch.codePointAt(0).toString(16).toUpperCase(); - } - - const nonPrintable = Object.prototype.hasOwnProperty.call(RegExp.prototype, "unicode") - ? new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]", "gu") - : null; - function unicodeEscape(s) { - if (nonPrintable) { - return s.replace(nonPrintable, ch => "\\u{" + hex(ch) + "}"); - } - return s; - } - - function literalEscape(s) { - return unicodeEscape(s - .replace(/\\/g, "\\\\") - .replace(/"/g, "\\\"") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) - .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); - } - - function classEscape(s) { - return unicodeEscape(s - .replace(/\\/g, "\\\\") - .replace(/\]/g, "\\]") - .replace(/\^/g, "\\^") - .replace(/-/g, "\\-") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) - .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); - } - - const DESCRIBE_EXPECTATION_FNS = { - literal(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; - }, - - class(expectation) { - const escapedParts = expectation.parts.map( - part => (Array.isArray(part) - ? classEscape(part[0]) + "-" + classEscape(part[1]) - : classEscape(part)) - ); - - return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]" + (expectation.unicode ? "u" : ""); - }, - - any() { - return "any character"; - }, - - end() { - return "end of input"; - }, - - other(expectation) { - return expectation.description; - }, - }; - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - const descriptions = expected.map(describeExpectation); - descriptions.sort(); - - if (descriptions.length > 0) { - let j = 1; - for (let i = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; - } - } - - function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; - } - - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; - } -} - -function peg$parse(input, options) { - options = options !== undefined ? options : {}; - - const peg$FAILED = {}; - const peg$source = options.grammarSource; - - const peg$startRuleFunctions = { - Program: peg$parseProgram, - }; - let peg$startRuleFunction = peg$parseProgram; - - const peg$c0 = "definition"; - const peg$c1 = "type"; - const peg$c2 = "{"; - const peg$c3 = "}"; - const peg$c4 = ":"; - const peg$c5 = "[]"; - const peg$c6 = "fact"; - const peg$c7 = "relation"; - const peg$c8 = "("; - const peg$c9 = ")"; - const peg$c10 = "evidence"; - const peg$c11 = "*"; - const peg$c12 = "measure"; - const peg$c13 = "return"; - const peg$c14 = "NEVER"; - const peg$c15 = "ALWAYS"; - const peg$c16 = "REQUIRES"; - const peg$c17 = "WHEN"; - const peg$c18 = "UNLESS"; - const peg$c19 = "|"; - const peg$c20 = "fusion"; - const peg$c21 = ","; - const peg$c22 = "with"; - const peg$c23 = "aggregate"; - const peg$c24 = "USING"; - const peg$c25 = "PROVIDES"; - const peg$c26 = "BEHAVES"; - const peg$c27 = "AS"; - const peg$c28 = "edge"; - const peg$c29 = "transitive"; - const peg$c30 = "hierarchical"; - const peg$c31 = "symmetrical_graph"; - const peg$c32 = "symmetrical"; - const peg$c33 = "limit"; - const peg$c34 = "decaying"; - const peg$c35 = "up"; - const peg$c36 = "down"; - const peg$c37 = "neutral"; - const peg$c38 = "stable"; - const peg$c39 = "hourly"; - const peg$c40 = "daily"; - const peg$c41 = "weekly"; - const peg$c42 = "monthly"; - const peg$c43 = "blurring"; - const peg$c44 = "fixed"; - const peg$c45 = "adaptive"; - const peg$c46 = "confidence"; - const peg$c47 = "confidence_90"; - const peg$c48 = "confidence_95"; - const peg$c49 = "confidence_99"; - const peg$c50 = "ttl"; - const peg$c51 = "CACHE"; - const peg$c52 = "eager"; - const peg$c53 = "lazy"; - const peg$c54 = "||"; - const peg$c55 = "&&"; - const peg$c56 = "is"; - const peg$c57 = "=="; - const peg$c58 = "!="; - const peg$c59 = ">="; - const peg$c60 = "<="; - const peg$c61 = "within"; - const peg$c62 = "NOT"; - const peg$c63 = "!"; - const peg$c64 = "."; - const peg$c65 = "\""; - const peg$c66 = "\\"; - const peg$c67 = "'"; - const peg$c68 = "true"; - const peg$c69 = "false"; - const peg$c70 = "//"; - const peg$c71 = "/*"; - const peg$c72 = "*/"; - - const peg$r0 = /^[<>]/; - const peg$r1 = /^[+\-]/; - const peg$r2 = /^[*\/]/; - const peg$r3 = /^["\\]/; - const peg$r4 = /^['\\]/; - const peg$r5 = /^[0-9]/; - const peg$r6 = /^[dhmw]/; - const peg$r7 = /^[a-zA-Z_]/; - const peg$r8 = /^[a-zA-Z0-9_]/; - const peg$r9 = /^[ \t\r\n]/; - const peg$r10 = /^[^\r\n]/; - - const peg$e0 = peg$otherExpectation("A type definition"); - const peg$e1 = peg$literalExpectation("definition", false); - const peg$e2 = peg$literalExpectation("type", false); - const peg$e3 = peg$literalExpectation("{", false); - const peg$e4 = peg$literalExpectation("}", false); - const peg$e5 = peg$literalExpectation(":", false); - const peg$e6 = peg$literalExpectation("[]", false); - const peg$e7 = peg$otherExpectation("A statement of fact (or relation in ADR-000)"); - const peg$e8 = peg$literalExpectation("fact", false); - const peg$e9 = peg$literalExpectation("relation", false); - const peg$e10 = peg$literalExpectation("(", false); - const peg$e11 = peg$literalExpectation(")", false); - const peg$e12 = peg$otherExpectation("An evidence rule"); - const peg$e13 = peg$literalExpectation("evidence", false); - const peg$e14 = peg$literalExpectation("*", false); - const peg$e15 = peg$otherExpectation("A derived measurement or value"); - const peg$e16 = peg$literalExpectation("measure", false); - const peg$e17 = peg$literalExpectation("return", false); - const peg$e18 = peg$literalExpectation("NEVER", false); - const peg$e19 = peg$literalExpectation("ALWAYS", false); - const peg$e20 = peg$literalExpectation("REQUIRES", false); - const peg$e21 = peg$literalExpectation("WHEN", false); - const peg$e22 = peg$literalExpectation("UNLESS", false); - const peg$e23 = peg$literalExpectation("|", false); - const peg$e24 = peg$literalExpectation("fusion", false); - const peg$e25 = peg$literalExpectation(",", false); - const peg$e26 = peg$literalExpectation("with", false); - const peg$e27 = peg$literalExpectation("aggregate", false); - const peg$e28 = peg$literalExpectation("USING", false); - const peg$e29 = peg$literalExpectation("PROVIDES", false); - const peg$e30 = peg$literalExpectation("BEHAVES", false); - const peg$e31 = peg$literalExpectation("AS", false); - const peg$e32 = peg$literalExpectation("edge", false); - const peg$e33 = peg$literalExpectation("transitive", false); - const peg$e34 = peg$literalExpectation("hierarchical", false); - const peg$e35 = peg$literalExpectation("symmetrical_graph", false); - const peg$e36 = peg$literalExpectation("symmetrical", false); - const peg$e37 = peg$literalExpectation("limit", false); - const peg$e38 = peg$literalExpectation("decaying", false); - const peg$e39 = peg$literalExpectation("up", false); - const peg$e40 = peg$literalExpectation("down", false); - const peg$e41 = peg$literalExpectation("neutral", false); - const peg$e42 = peg$literalExpectation("stable", false); - const peg$e43 = peg$literalExpectation("hourly", false); - const peg$e44 = peg$literalExpectation("daily", false); - const peg$e45 = peg$literalExpectation("weekly", false); - const peg$e46 = peg$literalExpectation("monthly", false); - const peg$e47 = peg$literalExpectation("blurring", false); - const peg$e48 = peg$literalExpectation("fixed", false); - const peg$e49 = peg$literalExpectation("adaptive", false); - const peg$e50 = peg$literalExpectation("confidence", false); - const peg$e51 = peg$literalExpectation("confidence_90", false); - const peg$e52 = peg$literalExpectation("confidence_95", false); - const peg$e53 = peg$literalExpectation("confidence_99", false); - const peg$e54 = peg$literalExpectation("ttl", false); - const peg$e55 = peg$literalExpectation("CACHE", false); - const peg$e56 = peg$literalExpectation("eager", false); - const peg$e57 = peg$literalExpectation("lazy", false); - const peg$e58 = peg$literalExpectation("||", false); - const peg$e59 = peg$literalExpectation("&&", false); - const peg$e60 = peg$literalExpectation("is", false); - const peg$e61 = peg$literalExpectation("==", false); - const peg$e62 = peg$literalExpectation("!=", false); - const peg$e63 = peg$literalExpectation(">=", false); - const peg$e64 = peg$literalExpectation("<=", false); - const peg$e65 = peg$classExpectation(["<", ">"], false, false, false); - const peg$e66 = peg$literalExpectation("within", false); - const peg$e67 = peg$classExpectation(["+", "-"], false, false, false); - const peg$e68 = peg$classExpectation(["*", "/"], false, false, false); - const peg$e69 = peg$literalExpectation("NOT", false); - const peg$e70 = peg$literalExpectation("!", false); - const peg$e71 = peg$literalExpectation(".", false); - const peg$e72 = peg$otherExpectation("The non-recursive base for an expression chain"); - const peg$e73 = peg$otherExpectation("A string literal"); - const peg$e74 = peg$literalExpectation("\"", false); - const peg$e75 = peg$classExpectation(["\"", "\\"], false, false, false); - const peg$e76 = peg$anyExpectation(); - const peg$e77 = peg$literalExpectation("\\", false); - const peg$e78 = peg$literalExpectation("'", false); - const peg$e79 = peg$classExpectation(["'", "\\"], false, false, false); - const peg$e80 = peg$otherExpectation("A floating-point number"); - const peg$e81 = peg$classExpectation([["0", "9"]], false, false, false); - const peg$e82 = peg$otherExpectation("An integer"); - const peg$e83 = peg$otherExpectation("A boolean literal"); - const peg$e84 = peg$literalExpectation("true", false); - const peg$e85 = peg$literalExpectation("false", false); - const peg$e86 = peg$otherExpectation("A time duration literal"); - const peg$e87 = peg$classExpectation(["d", "h", "m", "w"], false, false, false); - const peg$e88 = peg$classExpectation([["a", "z"], ["A", "Z"], "_"], false, false, false); - const peg$e89 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_"], false, false, false); - const peg$e90 = peg$classExpectation([" ", "\t", "\r", "\n"], false, false, false); - const peg$e91 = peg$literalExpectation("//", false); - const peg$e92 = peg$classExpectation(["\r", "\n"], true, false, false); - const peg$e93 = peg$literalExpectation("/*", false); - const peg$e94 = peg$literalExpectation("*/", false); - - function peg$f0(statements) { - const allStatements = statements.map(s => s[0]); - return { - type: "Program", - body: allStatements, - definitions: allStatements.filter(s => s.type === "Definition"), - facts: allStatements.filter(s => s.type === "Fact"), - evidence: allStatements.filter(s => s.type === "Evidence"), - measures: allStatements.filter(s => s.type === "Measure") - }; - } - function peg$f1(name, fields) { - return { type: "Definition", name, fields: fields.map(f => f[0]) }; - } - function peg$f2(name, fieldType, isArray, behavior, cache) { - return { - type: "Field", - name, - fieldType, - isArray: !!isArray, - behavior: behavior || null, - cache: cache || null - }; - } - function peg$f3(name, params, behavior, properties, cache, limit) { - return { - type: "Fact", - name, - params: params || [], - behavior: behavior || null, - properties: properties.map(p => p[0]), - cache: cache || null, - limit: limit || null - }; - } - function peg$f4(star, name, params, limit, body, provides) { - return { - type: "Evidence", - name, - params: params || [], - limit: limit || null, - body, - provides: provides || null, - challenge: !!star - }; - } - function peg$f5(name, params, body, provides) { - return { - type: "Measure", - name, - params: params || [], - body, - provides: provides || null - }; - } - function peg$f6(statements) { - return { type: "EvidenceBody", statements: statements.map(s => s[0]) }; - } - function peg$f7(statements, returnStmt) { - return { - type: "MeasureBody", - statements: statements.map(s => s[0]), - returnStatement: returnStmt || null - }; - } - function peg$f8(expression) { - return { type: "ReturnStatement", expression }; - } - function peg$f9(type, condition) { - return { type: "DefeasibleLogic", logicType: type, condition }; - } - function peg$f10(condition, defeater) { - return { type: "DefeasibleLogic", logicType: "WHEN", condition, defeater }; - } - function peg$f11(condition) { - return { type: "DefeasibleLogic", logicType: "WHEN", condition }; - } - function peg$f12(predicate, binding, body, limit, withClause) { - return { - type: "PatternMatch", - predicate, - binding: binding || null, - limit: limit || null, - body, - withClause: withClause || null - }; - } - function peg$f13(measure, variable, fusionStrategy, body, limit) { - return { - type: "CollectionProcessing", - measure, - variable, - fusion: fusionStrategy ? { strategy: fusionStrategy[1] } : null, - body, - limit: limit || null - }; - } - function peg$f14(name, args) { - return { type: "Predicate", name, args: args || [] }; - } - function peg$f15(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f16(name) { return { type: "Wildcard", name }; } - function peg$f17(name) { return name; } - function peg$f18(condition) { return condition; } - function peg$f19(strategy, expressions) { - return { type: "Fusion", strategy, expressions }; - } - function peg$f20(expressions, using) { - return { type: "Aggregation", expressions, using: using || null }; - } - function peg$f21(method) { return method; } - function peg$f22(name) { return { type: "TypeName", name }; } - function peg$f23(literal) { return { type: "TypeName", name: literal.value }; } - function peg$f24(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f25(name, paramType, isArray) { - return { type: "Parameter", name, paramType, isArray: !!isArray }; - } - function peg$f26(providesType) { return providesType; } - function peg$f27(behavior) { - return { type: "BehaviorAnnotation", behavior }; - } - function peg$f28() { return "transitive"; } - function peg$f29() { return "symmetrical"; } - function peg$f30(value) { return value; } - function peg$f31(b) { return b; } - function peg$f32(direction, period) { - return { type: "Behavior", behaviorType: "decay", direction, period }; - } - function peg$f33(mode, confidence) { - return { type: "Behavior", behaviorType: "blur", mode, confidence: confidence ? confidence[1] : null }; - } - function peg$f34(duration) { - return { type: "Behavior", behaviorType: "ttl", duration }; - } - function peg$f35(directive) { return directive; } - function peg$f36(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f37(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f38(head, typeName) { - return { type: "BinaryExpression", operator: "is", left: head, right: typeName }; - } - function peg$f39(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f40(head, right) { - return { type: "BinaryExpression", operator: "within", left: head, right }; - } - function peg$f41(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f42(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f43(operator, operand) { return { type: "UnaryExpression", operator: "NOT", operand }; } - function peg$f44(primary, binding) { - if (binding) { - return { type: "BindingAccess", expression: primary, binding }; - } - return primary; - } - function peg$f45(head, tail) { - return tail.reduce((obj, part) => { - return { - type: "AttributeAccess", - object: obj, - attribute: part[3], // The Identifier is the 4th element (index 3) - location: location() - }; - }, head); - } - function peg$f46(expr) { return expr; } - function peg$f47(name, args) { - return { type: "PredicateCall", name, args: args || [], challenge: true }; - } - function peg$f48(name, args) { - return { type: "PredicateCall", name, args: args || [] }; - } - function peg$f49(name) { return { type: "Variable", name }; } - function peg$f50(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f51(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f52(chars) { - return { type: "Literal", value: JSON.parse(text()) }; - } - function peg$f53(chars) { - return { type: "Literal", value: JSON.parse("\"" + chars.map(c => c[0] === '\\' ? c[1] : c[1]).join('') + "\"") }; - } - function peg$f54(value) { return { type: "Literal", value: parseFloat(text()) }; } - function peg$f55(value) { return { type: "Literal", value: parseInt(text(), 10) }; } - function peg$f56(value) { return { type: "Literal", value: value === "true" }; } - function peg$f57(value) { return { type: "Literal", value: text(), unit: text().slice(-1) }; } - function peg$f58(name) { return name; } - let peg$currPos = options.peg$currPos | 0; - let peg$savedPos = peg$currPos; - const peg$posDetailsCache = [{ line: 1, column: 1 }]; - let peg$maxFailPos = peg$currPos; - let peg$maxFailExpected = options.peg$maxFailExpected || []; - let peg$silentFails = options.peg$silentFails | 0; - - let peg$result; - - if (options.startRule) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function text() { - return input.substring(peg$savedPos, peg$currPos); - } - - function offset() { - return peg$savedPos; - } - - function range() { - return { - source: peg$source, - start: peg$savedPos, - end: peg$currPos, - }; - } - - function location() { - return peg$computeLocation(peg$savedPos, peg$currPos); - } - - function expected(description, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildStructuredError( - [peg$otherExpectation(description)], - input.substring(peg$savedPos, peg$currPos), - location - ); - } - - function error(message, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildSimpleError(message, location); - } - - function peg$getUnicode(pos = peg$currPos) { - const cp = input.codePointAt(pos); - if (cp === undefined) { - return ""; - } - return String.fromCodePoint(cp); - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text, ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase, unicode) { - return { type: "class", parts, inverted, ignoreCase, unicode }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$otherExpectation(description) { - return { type: "other", description }; - } - - function peg$computePosDetails(pos) { - let details = peg$posDetailsCache[pos]; - let p; - - if (details) { - return details; - } else { - if (pos >= peg$posDetailsCache.length) { - p = peg$posDetailsCache.length - 1; - } else { - p = pos; - while (!peg$posDetailsCache[--p]) {} - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column, - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - - return details; - } - } - - function peg$computeLocation(startPos, endPos, offset) { - const startPosDetails = peg$computePosDetails(startPos); - const endPosDetails = peg$computePosDetails(endPos); - - const res = { - source: peg$source, - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column, - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column, - }, - }; - if (offset && peg$source && (typeof peg$source.offset === "function")) { - res.start = peg$source.offset(res.start); - res.end = peg$source.offset(res.end); - } - return res; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildSimpleError(message, location) { - return new peg$SyntaxError(message, null, null, location); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError( - peg$SyntaxError.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parseProgram() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parse_(); - s2 = []; - s3 = peg$currPos; - s4 = peg$parseStatement(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parseStatement(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - s3 = peg$parse_(); - peg$savedPos = s0; - s0 = peg$f0(s2); - - return s0; - } - - function peg$parseStatement() { - let s0; - - s0 = peg$parseDefinition(); - if (s0 === peg$FAILED) { - s0 = peg$parseFact(); - if (s0 === peg$FAILED) { - s0 = peg$parseEvidence(); - if (s0 === peg$FAILED) { - s0 = peg$parseMeasure(); - } - } - } - - return s0; - } - - function peg$parseDefinition() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 10) === peg$c0) { - s1 = peg$c0; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c1) { - s1 = peg$c1; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = []; - s8 = peg$currPos; - s9 = peg$parseField(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s9 = [s9, s10]; - s8 = s9; - } else { - peg$currPos = s8; - s8 = peg$FAILED; - } - while (s8 !== peg$FAILED) { - s7.push(s8); - s8 = peg$currPos; - s9 = peg$parseField(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s9 = [s9, s10]; - s8 = s9; - } else { - peg$currPos = s8; - s8 = peg$FAILED; - } - } - if (input.charCodeAt(peg$currPos) === 125) { - s8 = peg$c3; - peg$currPos++; - } else { - s8 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s8 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f1(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e0); } - } - - return s0; - } - - function peg$parseField() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c4; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c5) { - s7 = peg$c5; - peg$currPos += 2; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - s8 = peg$parse_(); - s9 = peg$parseBehavior(); - if (s9 === peg$FAILED) { - s9 = null; - } - s10 = peg$parse_(); - s11 = peg$parseCacheDirective(); - if (s11 === peg$FAILED) { - s11 = null; - } - peg$savedPos = s0; - s0 = peg$f2(s1, s5, s7, s9, s11); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseFact() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c6) { - s1 = peg$c6; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c7) { - s1 = peg$c7; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s5 = peg$c8; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameterList(); - if (s7 === peg$FAILED) { - s7 = null; - } - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c9; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s11 = peg$parseBehaviorAnnotation(); - if (s11 === peg$FAILED) { - s11 = null; - } - s12 = peg$parse_(); - s13 = []; - s14 = peg$currPos; - s15 = peg$parseFactProperty(); - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s15 = [s15, s16]; - s14 = s15; - } else { - peg$currPos = s14; - s14 = peg$FAILED; - } - while (s14 !== peg$FAILED) { - s13.push(s14); - s14 = peg$currPos; - s15 = peg$parseFactProperty(); - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s15 = [s15, s16]; - s14 = s15; - } else { - peg$currPos = s14; - s14 = peg$FAILED; - } - } - s14 = peg$parseCacheDirective(); - if (s14 === peg$FAILED) { - s14 = null; - } - s15 = peg$parse_(); - s16 = peg$parseLimit(); - if (s16 === peg$FAILED) { - s16 = null; - } - peg$savedPos = s0; - s0 = peg$f3(s3, s7, s11, s13, s14, s16); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } - } - - return s0; - } - - function peg$parseEvidence() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c10) { - s1 = peg$c10; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e13); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 42) { - s3 = peg$c11; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } - } - if (s3 === peg$FAILED) { - s3 = null; - } - s4 = peg$parseIdentifier(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s6 = peg$c8; - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - s8 = peg$parseParameterList(); - if (s8 === peg$FAILED) { - s8 = null; - } - s9 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s10 = peg$c9; - peg$currPos++; - } else { - s10 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s10 !== peg$FAILED) { - s11 = peg$parse_(); - s12 = peg$parseLimit(); - if (s12 === peg$FAILED) { - s12 = null; - } - s13 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s14 = peg$c2; - peg$currPos++; - } else { - s14 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s14 !== peg$FAILED) { - s15 = peg$parse_(); - s16 = peg$parseEvidenceBody(); - s17 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s18 = peg$c3; - peg$currPos++; - } else { - s18 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s18 !== peg$FAILED) { - s19 = peg$parse_(); - s20 = peg$parseProvides(); - if (s20 === peg$FAILED) { - s20 = null; - } - peg$savedPos = s0; - s0 = peg$f4(s3, s4, s8, s12, s16, s20); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - - return s0; - } - - function peg$parseMeasure() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 7) === peg$c12) { - s1 = peg$c12; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s5 = peg$c8; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameterList(); - if (s7 === peg$FAILED) { - s7 = null; - } - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c9; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s11 = peg$c2; - peg$currPos++; - } else { - s11 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - s13 = peg$parseMeasureBody(); - s14 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s15 = peg$c3; - peg$currPos++; - } else { - s15 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s17 = peg$parseProvides(); - if (s17 === peg$FAILED) { - s17 = null; - } - peg$savedPos = s0; - s0 = peg$f5(s3, s7, s13, s17); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e15); } - } - - return s0; - } - - function peg$parseEvidenceBody() { - let s0, s1, s2, s3, s4; - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseEvidenceStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseEvidenceStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - peg$savedPos = s0; - s1 = peg$f6(s1); - s0 = s1; - - return s0; - } - - function peg$parseEvidenceStatement() { - let s0; - - s0 = peg$parseDefeasibleLogic(); - if (s0 === peg$FAILED) { - s0 = peg$parseFusion(); - if (s0 === peg$FAILED) { - s0 = peg$parseCollectionProcessing(); - if (s0 === peg$FAILED) { - s0 = peg$parsePatternMatch(); - if (s0 === peg$FAILED) { - s0 = peg$parseLogicalOr(); - } - } - } - } - - return s0; - } - - function peg$parseMeasureBody() { - let s0, s1, s2, s3, s4; - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseMeasureStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseMeasureStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - s2 = peg$parseReturnStatement(); - if (s2 === peg$FAILED) { - s2 = null; - } - peg$savedPos = s0; - s0 = peg$f7(s1, s2); - - return s0; - } - - function peg$parseMeasureStatement() { - let s0; - - s0 = peg$parseFusion(); - if (s0 === peg$FAILED) { - s0 = peg$parseAggregation(); - if (s0 === peg$FAILED) { - s0 = peg$parsePatternMatch(); - if (s0 === peg$FAILED) { - s0 = peg$parseLogicalOr(); - } - } - } - - return s0; - } - - function peg$parseReturnStatement() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c13) { - s1 = peg$c13; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e17); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f8(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseDefeasibleLogic() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c14) { - s1 = peg$c14; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c15) { - s1 = peg$c15; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e19); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c16) { - s1 = peg$c16; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } - } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f9(s1, s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c17) { - s1 = peg$c17; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c18) { - s5 = peg$c18; - peg$currPos += 6; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e22); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse__(); - if (s6 !== peg$FAILED) { - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f10(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c17) { - s1 = peg$c17; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f11(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - - return s0; - } - - function peg$parsePatternMatch() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; - - s0 = peg$currPos; - s1 = peg$parsePatternPredicate(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseBindingClause(); - if (s3 === peg$FAILED) { - s3 = null; - } - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseEvidenceBody(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s9 = peg$c3; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s11 = peg$parseLimit(); - if (s11 === peg$FAILED) { - s11 = null; - } - s12 = peg$parse_(); - s13 = peg$parseWithClause(); - if (s13 === peg$FAILED) { - s13 = null; - } - peg$savedPos = s0; - s0 = peg$f12(s1, s3, s7, s11, s13); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseCollectionProcessing() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17; - - s0 = peg$currPos; - s1 = peg$parseLogicalOr(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 124) { - s3 = peg$c19; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 124) { - s7 = peg$c19; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - s9 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c20) { - s10 = peg$c20; - peg$currPos += 6; - } else { - s10 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - if (s10 !== peg$FAILED) { - s11 = peg$parse__(); - if (s11 !== peg$FAILED) { - s12 = peg$parseIdentifier(); - if (s12 !== peg$FAILED) { - s10 = [s10, s11, s12]; - s9 = s10; - } else { - peg$currPos = s9; - s9 = peg$FAILED; - } - } else { - peg$currPos = s9; - s9 = peg$FAILED; - } - } else { - peg$currPos = s9; - s9 = peg$FAILED; - } - if (s9 === peg$FAILED) { - s9 = null; - } - s10 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s11 = peg$c2; - peg$currPos++; - } else { - s11 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - s13 = peg$parseEvidenceBody(); - if (s13 !== peg$FAILED) { - s14 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s15 = peg$c3; - peg$currPos++; - } else { - s15 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s17 = peg$parseLimit(); - if (s17 === peg$FAILED) { - s17 = null; - } - peg$savedPos = s0; - s0 = peg$f13(s1, s5, s9, s13, s17); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePatternPredicate() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s3 = peg$c8; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parsePatternArgumentList(); - if (s5 === peg$FAILED) { - s5 = null; - } - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s7 = peg$c9; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f14(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePatternArgumentList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parsePatternArgument(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parsePatternArgument(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parsePatternArgument(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f15(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePatternArgument() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c11; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f16(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parseLogicalOr(); - } - - return s0; - } - - function peg$parseBindingClause() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 124) { - s1 = peg$c19; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 124) { - s5 = peg$c19; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f17(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseWithClause() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c22) { - s1 = peg$c22; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f18(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseFusion() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c20) { - s1 = peg$c20; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseExpressionList(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s9 = peg$c3; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s9 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f19(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseAggregation() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 9) === peg$c23) { - s1 = peg$c23; - peg$currPos += 9; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e27); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s3 = peg$c2; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseExpressionList(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s7 = peg$c3; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - s9 = peg$parseUsing(); - if (s9 === peg$FAILED) { - s9 = null; - } - peg$savedPos = s0; - s0 = peg$f20(s5, s9); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseUsing() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c24) { - s1 = peg$c24; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e28); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f21(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseTypeName() { - let s0, s1; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f22(s1); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseString(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f23(s1); - } - s0 = s1; - } - - return s0; - } - - function peg$parseParameterList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseParameter(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameter(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameter(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f24(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseParameter() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c4; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c5) { - s7 = peg$c5; - peg$currPos += 2; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - peg$savedPos = s0; - s0 = peg$f25(s1, s5, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseProvides() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c25) { - s1 = peg$c25; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f26(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBehaviorAnnotation() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 7) === peg$c26) { - s1 = peg$c26; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e30); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c27) { - s3 = peg$c27; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e31); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c28) { - s5 = peg$c28; - peg$currPos += 4; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e32); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c29) { - s5 = peg$c29; - peg$currPos += 10; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e33); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 12) === peg$c30) { - s5 = peg$c30; - peg$currPos += 12; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 17) === peg$c31) { - s5 = peg$c31; - peg$currPos += 17; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e35); } - } - } - } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f27(s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseFactProperty() { - let s0, s1; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 10) === peg$c29) { - s1 = peg$c29; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e33); } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f28(); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 11) === peg$c32) { - s1 = peg$c32; - peg$currPos += 11; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f29(); - } - s0 = s1; - } - - return s0; - } - - function peg$parseLimit() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c33) { - s1 = peg$c33; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseInteger(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f30(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBehavior() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 7) === peg$c26) { - s1 = peg$c26; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e30); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s3 = peg$c2; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseDecayBehavior(); - if (s5 === peg$FAILED) { - s5 = peg$parseBlurBehavior(); - if (s5 === peg$FAILED) { - s5 = peg$parseTTLBehavior(); - } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s7 = peg$c3; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f31(s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseDecayBehavior() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c34) { - s1 = peg$c34; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e38); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c35) { - s3 = peg$c35; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e39); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c36) { - s3 = peg$c36; - peg$currPos += 4; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e40); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c37) { - s3 = peg$c37; - peg$currPos += 7; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e41); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c38) { - s3 = peg$c38; - peg$currPos += 6; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e42); } - } - } - } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c39) { - s5 = peg$c39; - peg$currPos += 6; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e43); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c40) { - s5 = peg$c40; - peg$currPos += 5; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e44); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c41) { - s5 = peg$c41; - peg$currPos += 6; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e45); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c42) { - s5 = peg$c42; - peg$currPos += 7; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e46); } - } - } - } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f32(s3, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBlurBehavior() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c43) { - s1 = peg$c43; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e47); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c44) { - s3 = peg$c44; - peg$currPos += 5; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e48); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c45) { - s3 = peg$c45; - peg$currPos += 8; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e49); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c46) { - s3 = peg$c46; - peg$currPos += 10; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e50); } - } - } - } - if (s3 !== peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse__(); - if (s5 !== peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c47) { - s6 = peg$c47; - peg$currPos += 13; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e51); } - } - if (s6 === peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c48) { - s6 = peg$c48; - peg$currPos += 13; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e52); } - } - if (s6 === peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c49) { - s6 = peg$c49; - peg$currPos += 13; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e53); } - } - } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = null; - } - peg$savedPos = s0; - s0 = peg$f33(s3, s4); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseTTLBehavior() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c50) { - s1 = peg$c50; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e54); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseDuration(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f34(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseCacheDirective() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c51) { - s1 = peg$c51; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e55); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c52) { - s3 = peg$c52; - peg$currPos += 5; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e56); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c53) { - s3 = peg$c53; - peg$currPos += 4; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e57); } - } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f35(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLogicalOr() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseLogicalAnd(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c54) { - s5 = peg$c54; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e58); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalAnd(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c54) { - s5 = peg$c54; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e58); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalAnd(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f36(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLogicalAnd() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseComparison(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c55) { - s5 = peg$c55; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e59); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c55) { - s5 = peg$c55; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e59); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f37(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseComparison() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseTemporalComparison(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c56) { - s3 = peg$c56; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e60); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - s5 = peg$parseTypeName(); - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f38(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseTemporalComparison(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c57) { - s5 = peg$c57; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e61); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c58) { - s5 = peg$c58; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e62); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c59) { - s5 = peg$c59; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e63); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c60) { - s5 = peg$c60; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e64); } - } - if (s5 === peg$FAILED) { - s5 = input.charAt(peg$currPos); - if (peg$r0.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e65); } - } - } - } - } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseTemporalComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c57) { - s5 = peg$c57; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e61); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c58) { - s5 = peg$c58; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e62); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c59) { - s5 = peg$c59; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e63); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c60) { - s5 = peg$c60; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e64); } - } - if (s5 === peg$FAILED) { - s5 = input.charAt(peg$currPos); - if (peg$r0.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e65); } - } - } - } - } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseTemporalComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f39(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - return s0; - } - - function peg$parseTemporalComparison() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parseAddition(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.substr(peg$currPos, 6) === peg$c61) { - s3 = peg$c61; - peg$currPos += 6; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e66); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - s5 = peg$parseDuration(); - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f40(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parseAddition(); - } - - return s0; - } - - function peg$parseAddition() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseMultiplication(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = input.charAt(peg$currPos); - if (peg$r1.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e67); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseMultiplication(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = input.charAt(peg$currPos); - if (peg$r1.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e67); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseMultiplication(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f41(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseMultiplication() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseUnary(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = input.charAt(peg$currPos); - if (peg$r2.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e68); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseUnary(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = input.charAt(peg$currPos); - if (peg$r2.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e68); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseUnary(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f42(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseUnary() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c62) { - s1 = peg$c62; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e69); } - } - if (s1 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c63; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e70); } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseUnary(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f43(s1, s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parsePostfix(); - } - - return s0; - } - - function peg$parsePostfix() { - let s0, s1, s2; - - s0 = peg$currPos; - s1 = peg$parseAttributeAccess(); - if (s1 === peg$FAILED) { - s1 = peg$parsePrimaryTerm(); - } - if (s1 !== peg$FAILED) { - s2 = peg$parseBindingClause(); - if (s2 === peg$FAILED) { - s2 = null; - } - peg$savedPos = s0; - s0 = peg$f44(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseAttributeAccess() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parsePrimaryTerm(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c64; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e71); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseIdentifier(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c64; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e71); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseIdentifier(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f45(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePrimaryTerm() { - let s0, s1, s2, s3, s4, s5; - - peg$silentFails++; - s0 = peg$parseChallengePredicate(); - if (s0 === peg$FAILED) { - s0 = peg$parseLiteral(); - if (s0 === peg$FAILED) { - s0 = peg$parsePredicateCall(); - if (s0 === peg$FAILED) { - s0 = peg$parseVariable(); - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c8; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c9; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f46(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e72); } - } - - return s0; - } - - function peg$parseChallengePredicate() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c11; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseIdentifier(); - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s4 = peg$c8; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s6 = peg$parseArgumentList(); - if (s6 === peg$FAILED) { - s6 = null; - } - s7 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s8 = peg$c9; - peg$currPos++; - } else { - s8 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s8 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f47(s2, s6); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePredicateCall() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 40) { - s2 = peg$c8; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - s4 = peg$parseArgumentList(); - if (s4 === peg$FAILED) { - s4 = null; - } - s5 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s6 = peg$c9; - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s6 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f48(s1, s4); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseVariable() { - let s0, s1; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f49(s1); - } - s0 = s1; - - return s0; - } - - function peg$parseArgumentList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseLogicalOr(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f50(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseExpressionList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseLogicalOr(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f51(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLiteral() { - let s0; - - s0 = peg$parseString(); - if (s0 === peg$FAILED) { - s0 = peg$parseFloat(); - if (s0 === peg$FAILED) { - s0 = peg$parseInteger(); - if (s0 === peg$FAILED) { - s0 = peg$parseBoolean(); - if (s0 === peg$FAILED) { - s0 = peg$parseDuration(); - } - } - } - } - - return s0; - } - - function peg$parseString() { - let s0, s1, s2, s3, s4, s5; - - peg$silentFails++; - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c65; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e74); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r3.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e75); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c66; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r3.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e75); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c66; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c65; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e74); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f52(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c67; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e78); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r4.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c66; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r4.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c66; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c67; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e78); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f53(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e73); } - } - - return s0; - } - - function peg$parseFloat() { - let s0, s1, s2, s3, s4, s5; - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s3 = peg$c64; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e71); } - } - if (s3 !== peg$FAILED) { - s4 = []; - s5 = input.charAt(peg$currPos); - if (peg$r5.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - s5 = input.charAt(peg$currPos); - if (peg$r5.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f54(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e80); } - } - - return s0; - } - - function peg$parseInteger() { - let s0, s1, s2; - - peg$silentFails++; - s0 = peg$currPos; - s1 = []; - s2 = input.charAt(peg$currPos); - if (peg$r5.test(s2)) { - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s2 !== peg$FAILED) { - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = input.charAt(peg$currPos); - if (peg$r5.test(s2)) { - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - } - } else { - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f55(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e82); } - } - - return s0; - } - - function peg$parseBoolean() { - let s0, s1; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c68) { - s1 = peg$c68; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c69) { - s1 = peg$c69; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e85); } - } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f56(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e83); } - } - - return s0; - } - - function peg$parseDuration() { - let s0, s1, s2, s3; - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s3 = input.charAt(peg$currPos); - if (peg$r6.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e87); } - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f57(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e86); } - } - - return s0; - } - - function peg$parseIdentifier() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - s1 = peg$currPos; - peg$silentFails++; - s2 = peg$parseKeyword(); - peg$silentFails--; - if (s2 === peg$FAILED) { - s1 = undefined; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = peg$currPos; - s4 = input.charAt(peg$currPos); - if (peg$r7.test(s4)) { - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e88); } - } - if (s4 !== peg$FAILED) { - s5 = []; - s6 = input.charAt(peg$currPos); - if (peg$r8.test(s6)) { - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e89); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - s6 = input.charAt(peg$currPos); - if (peg$r8.test(s6)) { - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e89); } - } - } - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f58(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseKeyword() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 10) === peg$c0) { - s1 = peg$c0; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c1) { - s1 = peg$c1; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c6) { - s1 = peg$c6; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c7) { - s1 = peg$c7; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c10) { - s1 = peg$c10; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e13); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c12) { - s1 = peg$c12; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c26) { - s1 = peg$c26; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e30); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c27) { - s1 = peg$c27; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e31); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c51) { - s1 = peg$c51; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e55); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c34) { - s1 = peg$c34; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e38); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c43) { - s1 = peg$c43; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e47); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c50) { - s1 = peg$c50; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e54); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c29) { - s1 = peg$c29; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e33); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 11) === peg$c32) { - s1 = peg$c32; - peg$currPos += 11; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 12) === peg$c30) { - s1 = peg$c30; - peg$currPos += 12; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 17) === peg$c31) { - s1 = peg$c31; - peg$currPos += 17; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e35); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c28) { - s1 = peg$c28; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e32); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c33) { - s1 = peg$c33; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c25) { - s1 = peg$c25; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c20) { - s1 = peg$c20; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 9) === peg$c23) { - s1 = peg$c23; - peg$currPos += 9; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e27); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c24) { - s1 = peg$c24; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e28); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c14) { - s1 = peg$c14; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c15) { - s1 = peg$c15; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e19); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c17) { - s1 = peg$c17; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c18) { - s1 = peg$c18; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e22); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c16) { - s1 = peg$c16; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c22) { - s1 = peg$c22; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e26); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c68) { - s1 = peg$c68; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c69) { - s1 = peg$c69; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e85); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c62) { - s1 = peg$c62; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e69); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c61) { - s1 = peg$c61; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e66); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c13) { - s1 = peg$c13; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e17); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c56) { - s1 = peg$c56; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e60); } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - peg$silentFails++; - s3 = input.charAt(peg$currPos); - if (peg$r8.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e89); } - } - peg$silentFails--; - if (s3 === peg$FAILED) { - s2 = undefined; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parse_() { - let s0, s1; - - s0 = []; - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - } - - return s0; - } - - function peg$parse__() { - let s0, s1; - - s0 = []; - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - if (s1 !== peg$FAILED) { - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - } - } else { - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseWhiteSpace() { - let s0; - - s0 = input.charAt(peg$currPos); - if (peg$r9.test(s0)) { - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e90); } - } - - return s0; - } - - function peg$parseComment() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c70) { - s1 = peg$c70; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e91); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r10.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e92); } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r10.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e92); } - } - } - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c71) { - s1 = peg$c71; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e93); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - if (input.substr(peg$currPos, 2) === peg$c72) { - s5 = peg$c72; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e94); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - if (input.substr(peg$currPos, 2) === peg$c72) { - s5 = peg$c72; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e94); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (input.substr(peg$currPos, 2) === peg$c72) { - s3 = peg$c72; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e94); } - } - if (s3 !== peg$FAILED) { - s1 = [s1, s2, s3]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - return s0; - } - - - // The location() function provides line/column info for error reporting. - // The text() function returns the matched text for a rule. - - // Helper function to build a left-associative binary expression tree. - function buildLeftAssoc(head, tail) { - return tail.reduce((result, element) => { - return { - type: "BinaryExpression", - operator: element[1], - left: result, - right: element[3], - location: location() - }; - }, head); - } - - peg$result = peg$startRuleFunction(); - - const peg$success = (peg$result !== peg$FAILED && peg$currPos === input.length); - function peg$throw() { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? peg$getUnicode(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } - if (options.peg$library) { - return /** @type {any} */ ({ - peg$result, - peg$currPos, - peg$FAILED, - peg$maxFailExpected, - peg$maxFailPos, - peg$success, - peg$throw: peg$success ? undefined : peg$throw, - }); - } - if (peg$success) { - return peg$result; - } else { - peg$throw(); - } -} - -const peg$allowedStartRules = [ - "Program" -]; - -export { - peg$allowedStartRules as StartRules, - peg$SyntaxError as SyntaxError, - peg$parse as parse -}; diff --git a/src/ast/parser/ExpressionParser.js b/src/ast/parser/ExpressionParser.js deleted file mode 100644 index c7ad57b..0000000 --- a/src/ast/parser/ExpressionParser.js +++ /dev/null @@ -1,1614 +0,0 @@ -// @generated by Peggy 5.1.0. -// -// https://peggyjs.org/ - - -class peg$SyntaxError extends SyntaxError { - constructor(message, expected, found, location) { - super(message); - this.expected = expected; - this.found = found; - this.location = location; - this.name = "SyntaxError"; - } - - format(sources) { - let str = "Error: " + this.message; - if (this.location) { - let src = null; - const st = sources.find(s => s.source === this.location.source); - if (st) { - src = st.text.split(/\r\n|\n|\r/g); - } - const s = this.location.start; - const offset_s = (this.location.source && (typeof this.location.source.offset === "function")) - ? this.location.source.offset(s) - : s; - const loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column; - if (src) { - const e = this.location.end; - const filler = "".padEnd(offset_s.line.toString().length, " "); - const line = src[s.line - 1]; - const last = s.line === e.line ? e.column : line.length + 1; - const hatLen = (last - s.column) || 1; - str += "\n --> " + loc + "\n" - + filler + " |\n" - + offset_s.line + " | " + line + "\n" - + filler + " | " + "".padEnd(s.column - 1, " ") - + "".padEnd(hatLen, "^"); - } else { - str += "\n at " + loc; - } - } - return str; - } - - static buildMessage(expected, found) { - function hex(ch) { - return ch.codePointAt(0).toString(16).toUpperCase(); - } - - const nonPrintable = Object.prototype.hasOwnProperty.call(RegExp.prototype, "unicode") - ? new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]", "gu") - : null; - function unicodeEscape(s) { - if (nonPrintable) { - return s.replace(nonPrintable, ch => "\\u{" + hex(ch) + "}"); - } - return s; - } - - function literalEscape(s) { - return unicodeEscape(s - .replace(/\\/g, "\\\\") - .replace(/"/g, "\\\"") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) - .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); - } - - function classEscape(s) { - return unicodeEscape(s - .replace(/\\/g, "\\\\") - .replace(/\]/g, "\\]") - .replace(/\^/g, "\\^") - .replace(/-/g, "\\-") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) - .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); - } - - const DESCRIBE_EXPECTATION_FNS = { - literal(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; - }, - - class(expectation) { - const escapedParts = expectation.parts.map( - part => (Array.isArray(part) - ? classEscape(part[0]) + "-" + classEscape(part[1]) - : classEscape(part)) - ); - - return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]" + (expectation.unicode ? "u" : ""); - }, - - any() { - return "any character"; - }, - - end() { - return "end of input"; - }, - - other(expectation) { - return expectation.description; - }, - }; - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - const descriptions = expected.map(describeExpectation); - descriptions.sort(); - - if (descriptions.length > 0) { - let j = 1; - for (let i = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; - } - } - - function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; - } - - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; - } -} - -function peg$parse(input, options) { - options = options !== undefined ? options : {}; - - const peg$FAILED = {}; - const peg$source = options.grammarSource; - - const peg$startRuleFunctions = { - Expression: peg$parseExpression, - }; - let peg$startRuleFunction = peg$parseExpression; - - const peg$c0 = "UNLESS"; - const peg$c1 = "FUSION"; - const peg$c2 = "{"; - const peg$c3 = "}"; - const peg$c4 = "max"; - const peg$c5 = "min"; - const peg$c6 = "majority"; - const peg$c7 = "average"; - const peg$c8 = "sum"; - const peg$c9 = "sum_unbounded"; - const peg$c10 = "median"; - const peg$c11 = "optimistic"; - const peg$c12 = "pessimistic"; - const peg$c13 = "top2"; - const peg$c14 = "top3"; - const peg$c15 = "priority"; - const peg$c16 = "*"; - const peg$c17 = "("; - const peg$c18 = ")"; - const peg$c19 = ","; - const peg$c20 = ":"; - const peg$c21 = "."; - const peg$c22 = "::"; - const peg$c23 = "\""; - const peg$c24 = "'"; - const peg$c25 = "\\"; - const peg$c26 = "//"; - const peg$c27 = "/*"; - const peg$c28 = "*/"; - - const peg$r0 = /^[^"\\]/; - const peg$r1 = /^[^'\\]/; - const peg$r2 = /^["'\\nrt]/; - const peg$r3 = /^[0-9]/; - const peg$r4 = /^[a-zA-Z_]/; - const peg$r5 = /^[a-zA-Z0-9_\-]/; - const peg$r6 = /^[ \t\n\r]/; - const peg$r7 = /^[^\n]/; - - const peg$e0 = peg$literalExpectation("UNLESS", false); - const peg$e1 = peg$literalExpectation("FUSION", false); - const peg$e2 = peg$literalExpectation("{", false); - const peg$e3 = peg$literalExpectation("}", false); - const peg$e4 = peg$literalExpectation("max", false); - const peg$e5 = peg$literalExpectation("min", false); - const peg$e6 = peg$literalExpectation("majority", false); - const peg$e7 = peg$literalExpectation("average", false); - const peg$e8 = peg$literalExpectation("sum", false); - const peg$e9 = peg$literalExpectation("sum_unbounded", false); - const peg$e10 = peg$literalExpectation("median", false); - const peg$e11 = peg$literalExpectation("optimistic", false); - const peg$e12 = peg$literalExpectation("pessimistic", false); - const peg$e13 = peg$literalExpectation("top2", false); - const peg$e14 = peg$literalExpectation("top3", false); - const peg$e15 = peg$literalExpectation("priority", false); - const peg$e16 = peg$literalExpectation("*", false); - const peg$e17 = peg$literalExpectation("(", false); - const peg$e18 = peg$literalExpectation(")", false); - const peg$e19 = peg$literalExpectation(",", false); - const peg$e20 = peg$literalExpectation(":", false); - const peg$e21 = peg$literalExpectation(".", false); - const peg$e22 = peg$literalExpectation("::", false); - const peg$e23 = peg$literalExpectation("\"", false); - const peg$e24 = peg$classExpectation(["\"", "\\"], true, false, false); - const peg$e25 = peg$literalExpectation("'", false); - const peg$e26 = peg$classExpectation(["'", "\\"], true, false, false); - const peg$e27 = peg$literalExpectation("\\", false); - const peg$e28 = peg$classExpectation(["\"", "'", "\\", "n", "r", "t"], false, false, false); - const peg$e29 = peg$classExpectation([["0", "9"]], false, false, false); - const peg$e30 = peg$classExpectation([["a", "z"], ["A", "Z"], "_"], false, false, false); - const peg$e31 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "-"], false, false, false); - const peg$e32 = peg$classExpectation([" ", "\t", "\n", "\r"], false, false, false); - const peg$e33 = peg$literalExpectation("//", false); - const peg$e34 = peg$classExpectation(["\n"], true, false, false); - const peg$e35 = peg$literalExpectation("/*", false); - const peg$e36 = peg$literalExpectation("*/", false); - const peg$e37 = peg$anyExpectation(); - - function peg$f0(expr) { return expr; } - function peg$f1(primary, exception) { - return makeDefeasible(primary, exception); - } - function peg$f2(aggregator, expressions) { - return makeFusion(expressions, aggregator); - } - function peg$f3(head, tail) { - const exprs = [head]; - for (const t of tail) { - exprs.push(t[1]); - } - return exprs; - } - function peg$f4(name, args) { - return makeChallengePredicate(name, args || []); - } - function peg$f5(name, args) { - return makePredicate(name, args || []); - } - function peg$f6(head, tail) { - const args = [head]; - for (const t of tail) { - args.push(t[3]); - } - return args; - } - function peg$f7(name, path) { - return makeVariable(name, path.map(p => p[1])); - } - function peg$f8(refType, path) { - return { type: 'Reference', refType: refType, path: path }; - } - function peg$f9(head, tail) { - const parts = [head]; - for (const t of tail) { - parts.push(t[1]); - } - return parts; - } - function peg$f10(chars) { - return { type: 'Literal', value: chars.join(''), dataType: 'string' }; - } - function peg$f11(chars) { - return { type: 'Literal', value: chars.join(''), dataType: 'string' }; - } - function peg$f12(char) { - const escapes = { '"': '"', "'": "'", '\\': '\\', 'n': '\n', 'r': '\r', 't': '\t' }; - return escapes[char] || char; - } - function peg$f13(digits) { - return { type: 'Literal', value: parseInt(digits.join(''), 10), dataType: 'number' }; - } - function peg$f14(first, rest) { - return first + rest.join(''); - } - let peg$currPos = options.peg$currPos | 0; - let peg$savedPos = peg$currPos; - const peg$posDetailsCache = [{ line: 1, column: 1 }]; - let peg$maxFailPos = peg$currPos; - let peg$maxFailExpected = options.peg$maxFailExpected || []; - let peg$silentFails = options.peg$silentFails | 0; - - let peg$result; - - if (options.startRule) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function text() { - return input.substring(peg$savedPos, peg$currPos); - } - - function offset() { - return peg$savedPos; - } - - function range() { - return { - source: peg$source, - start: peg$savedPos, - end: peg$currPos, - }; - } - - function location() { - return peg$computeLocation(peg$savedPos, peg$currPos); - } - - function expected(description, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildStructuredError( - [peg$otherExpectation(description)], - input.substring(peg$savedPos, peg$currPos), - location - ); - } - - function error(message, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildSimpleError(message, location); - } - - function peg$getUnicode(pos = peg$currPos) { - const cp = input.codePointAt(pos); - if (cp === undefined) { - return ""; - } - return String.fromCodePoint(cp); - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text, ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase, unicode) { - return { type: "class", parts, inverted, ignoreCase, unicode }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$otherExpectation(description) { - return { type: "other", description }; - } - - function peg$computePosDetails(pos) { - let details = peg$posDetailsCache[pos]; - let p; - - if (details) { - return details; - } else { - if (pos >= peg$posDetailsCache.length) { - p = peg$posDetailsCache.length - 1; - } else { - p = pos; - while (!peg$posDetailsCache[--p]) {} - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column, - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - - return details; - } - } - - function peg$computeLocation(startPos, endPos, offset) { - const startPosDetails = peg$computePosDetails(startPos); - const endPosDetails = peg$computePosDetails(endPos); - - const res = { - source: peg$source, - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column, - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column, - }, - }; - if (offset && peg$source && (typeof peg$source.offset === "function")) { - res.start = peg$source.offset(res.start); - res.end = peg$source.offset(res.end); - } - return res; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildSimpleError(message, location) { - return new peg$SyntaxError(message, null, null, location); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError( - peg$SyntaxError.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parseExpression() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - s1 = peg$parse_(); - s2 = peg$parseDefeasibleExpr(); - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - peg$savedPos = s0; - s0 = peg$f0(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseDefeasibleExpr() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parsePrimaryExpr(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.substr(peg$currPos, 6) === peg$c0) { - s3 = peg$c0; - peg$currPos += 6; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e0); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parsePredicateCall(); - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f1(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parsePrimaryExpr(); - } - - return s0; - } - - function peg$parsePrimaryExpr() { - let s0; - - s0 = peg$parseFusionBlock(); - if (s0 === peg$FAILED) { - s0 = peg$parseChallengePredicate(); - if (s0 === peg$FAILED) { - s0 = peg$parsePredicateCall(); - } - } - - return s0; - } - - function peg$parseFusionBlock() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c1) { - s1 = peg$c1; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseAggregatorKeyword(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseExpressionList(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s9 = peg$c3; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s9 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f2(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseAggregatorKeyword() { - let s0; - - if (input.substr(peg$currPos, 3) === peg$c4) { - s0 = peg$c4; - peg$currPos += 3; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c5) { - s0 = peg$c5; - peg$currPos += 3; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c6) { - s0 = peg$c6; - peg$currPos += 8; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c7) { - s0 = peg$c7; - peg$currPos += 7; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c8) { - s0 = peg$c8; - peg$currPos += 3; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c9) { - s0 = peg$c9; - peg$currPos += 13; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c10) { - s0 = peg$c10; - peg$currPos += 6; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c11) { - s0 = peg$c11; - peg$currPos += 10; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 11) === peg$c12) { - s0 = peg$c12; - peg$currPos += 11; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c13) { - s0 = peg$c13; - peg$currPos += 4; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e13); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c14) { - s0 = peg$c14; - peg$currPos += 4; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } - } - if (s0 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c15) { - s0 = peg$c15; - peg$currPos += 8; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e15); } - } - } - } - } - } - } - } - } - } - } - } - } - - return s0; - } - - function peg$parseExpressionList() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parseExpression(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = peg$parseExpression(); - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - s5 = peg$parseExpression(); - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f3(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseChallengePredicate() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c16; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseIdentifier(); - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s4 = peg$c17; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e17); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s6 = peg$parseArgumentList(); - if (s6 === peg$FAILED) { - s6 = null; - } - s7 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s8 = peg$c18; - peg$currPos++; - } else { - s8 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } - } - if (s8 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f4(s2, s6); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePredicateCall() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e17); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseArgumentList(); - if (s5 === peg$FAILED) { - s5 = null; - } - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s7 = peg$c18; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } - } - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f5(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseArgumentList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseArgument(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c19; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e19); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseArgument(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c19; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e19); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseArgument(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f6(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseArgument() { - let s0; - - s0 = peg$parseVariableBinding(); - if (s0 === peg$FAILED) { - s0 = peg$parseLiteral(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypedReference(); - } - } - - return s0; - } - - function peg$parseVariableBinding() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 58) { - s1 = peg$c20; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseIdentifier(); - if (s2 !== peg$FAILED) { - s3 = []; - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parseIdentifier(); - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - while (s4 !== peg$FAILED) { - s3.push(s4); - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parseIdentifier(); - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f7(s2, s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseTypedReference() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c22) { - s2 = peg$c22; - peg$currPos += 2; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e22); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parsePath(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f8(s1, s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePath() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s4 = peg$c21; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s4 = peg$c21; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f9(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLiteral() { - let s0; - - s0 = peg$parseStringLiteral(); - if (s0 === peg$FAILED) { - s0 = peg$parseNumberLiteral(); - } - - return s0; - } - - function peg$parseStringLiteral() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c23; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r0.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - if (s3 === peg$FAILED) { - s3 = peg$parseEscapeSequence(); - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r0.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - if (s3 === peg$FAILED) { - s3 = peg$parseEscapeSequence(); - } - } - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c23; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f10(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c24; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r1.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e26); } - } - if (s3 === peg$FAILED) { - s3 = peg$parseEscapeSequence(); - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r1.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e26); } - } - if (s3 === peg$FAILED) { - s3 = peg$parseEscapeSequence(); - } - } - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c24; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f11(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - return s0; - } - - function peg$parseEscapeSequence() { - let s0, s1, s2; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e27); } - } - if (s1 !== peg$FAILED) { - s2 = input.charAt(peg$currPos); - if (peg$r2.test(s2)) { - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e28); } - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f12(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseNumberLiteral() { - let s0, s1, s2; - - s0 = peg$currPos; - s1 = []; - s2 = input.charAt(peg$currPos); - if (peg$r3.test(s2)) { - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s2 !== peg$FAILED) { - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = input.charAt(peg$currPos); - if (peg$r3.test(s2)) { - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - } - } else { - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f13(s1); - } - s0 = s1; - - return s0; - } - - function peg$parseIdentifier() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - s1 = input.charAt(peg$currPos); - if (peg$r4.test(s1)) { - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e30); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e31); } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e31); } - } - } - peg$savedPos = s0; - s0 = peg$f14(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parse_() { - let s0, s1; - - peg$silentFails++; - s0 = []; - s1 = peg$parseWS(); - if (s1 === peg$FAILED) { - s1 = peg$parseLineComment(); - if (s1 === peg$FAILED) { - s1 = peg$parseBlockComment(); - } - } - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWS(); - if (s1 === peg$FAILED) { - s1 = peg$parseLineComment(); - if (s1 === peg$FAILED) { - s1 = peg$parseBlockComment(); - } - } - } - peg$silentFails--; - - return s0; - } - - function peg$parseWS() { - let s0, s1; - - s0 = []; - s1 = input.charAt(peg$currPos); - if (peg$r6.test(s1)) { - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e32); } - } - if (s1 !== peg$FAILED) { - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = input.charAt(peg$currPos); - if (peg$r6.test(s1)) { - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e32); } - } - } - } else { - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLineComment() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c26) { - s1 = peg$c26; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e33); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r7.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r7.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - } - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBlockComment() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c27) { - s1 = peg$c27; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e35); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - if (input.substr(peg$currPos, 2) === peg$c28) { - s5 = peg$c28; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - if (input.substr(peg$currPos, 2) === peg$c28) { - s5 = peg$c28; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (input.substr(peg$currPos, 2) === peg$c28) { - s3 = peg$c28; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } - } - if (s3 !== peg$FAILED) { - s1 = [s1, s2, s3]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - - // Helper functions - function makeVariable(name, path) { - return { type: 'Variable', name, path: path || [] }; - } - - function makePredicate(name, args) { - return { type: 'Predicate', name, args: args || [] }; - } - - function makeChallengePredicate(name, args) { - return { type: 'Predicate', name, args: args || [], challenge: true }; - } - - function makeFusion(expressions, aggregator) { - return { type: 'Fusion', aggregator, expressions }; - } - - function makeDefeasible(primary, exception) { - return { type: 'Defeasible', primary, exception }; - } - - peg$result = peg$startRuleFunction(); - - const peg$success = (peg$result !== peg$FAILED && peg$currPos === input.length); - function peg$throw() { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? peg$getUnicode(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } - if (options.peg$library) { - return /** @type {any} */ ({ - peg$result, - peg$currPos, - peg$FAILED, - peg$maxFailExpected, - peg$maxFailPos, - peg$success, - peg$throw: peg$success ? undefined : peg$throw, - }); - } - if (peg$success) { - return peg$result; - } else { - peg$throw(); - } -} - -const peg$allowedStartRules = [ - "Expression" -]; - -export { - peg$allowedStartRules as StartRules, - peg$SyntaxError as SyntaxError, - peg$parse as parse -}; diff --git a/src/ast/parser/GeneratedParser.js b/src/ast/parser/GeneratedParser.js deleted file mode 100644 index e61da22..0000000 --- a/src/ast/parser/GeneratedParser.js +++ /dev/null @@ -1,5186 +0,0 @@ -// @generated by Peggy 5.1.0. -// -// https://peggyjs.org/ - - -class peg$SyntaxError extends SyntaxError { - constructor(message, expected, found, location) { - super(message); - this.expected = expected; - this.found = found; - this.location = location; - this.name = "SyntaxError"; - } - - format(sources) { - let str = "Error: " + this.message; - if (this.location) { - let src = null; - const st = sources.find(s => s.source === this.location.source); - if (st) { - src = st.text.split(/\r\n|\n|\r/g); - } - const s = this.location.start; - const offset_s = (this.location.source && (typeof this.location.source.offset === "function")) - ? this.location.source.offset(s) - : s; - const loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column; - if (src) { - const e = this.location.end; - const filler = "".padEnd(offset_s.line.toString().length, " "); - const line = src[s.line - 1]; - const last = s.line === e.line ? e.column : line.length + 1; - const hatLen = (last - s.column) || 1; - str += "\n --> " + loc + "\n" - + filler + " |\n" - + offset_s.line + " | " + line + "\n" - + filler + " | " + "".padEnd(s.column - 1, " ") - + "".padEnd(hatLen, "^"); - } else { - str += "\n at " + loc; - } - } - return str; - } - - static buildMessage(expected, found) { - function hex(ch) { - return ch.codePointAt(0).toString(16).toUpperCase(); - } - - const nonPrintable = Object.prototype.hasOwnProperty.call(RegExp.prototype, "unicode") - ? new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]", "gu") - : null; - function unicodeEscape(s) { - if (nonPrintable) { - return s.replace(nonPrintable, ch => "\\u{" + hex(ch) + "}"); - } - return s; - } - - function literalEscape(s) { - return unicodeEscape(s - .replace(/\\/g, "\\\\") - .replace(/"/g, "\\\"") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) - .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); - } - - function classEscape(s) { - return unicodeEscape(s - .replace(/\\/g, "\\\\") - .replace(/\]/g, "\\]") - .replace(/\^/g, "\\^") - .replace(/-/g, "\\-") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) - .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); - } - - const DESCRIBE_EXPECTATION_FNS = { - literal(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; - }, - - class(expectation) { - const escapedParts = expectation.parts.map( - part => (Array.isArray(part) - ? classEscape(part[0]) + "-" + classEscape(part[1]) - : classEscape(part)) - ); - - return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]" + (expectation.unicode ? "u" : ""); - }, - - any() { - return "any character"; - }, - - end() { - return "end of input"; - }, - - other(expectation) { - return expectation.description; - }, - }; - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - const descriptions = expected.map(describeExpectation); - descriptions.sort(); - - if (descriptions.length > 0) { - let j = 1; - for (let i = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; - } - } - - function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; - } - - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; - } -} - -function peg$parse(input, options) { - options = options !== undefined ? options : {}; - - const peg$FAILED = {}; - const peg$source = options.grammarSource; - - const peg$startRuleFunctions = { - Program: peg$parseProgram, - }; - let peg$startRuleFunction = peg$parseProgram; - - const peg$c0 = "definition"; - const peg$c1 = "type"; - const peg$c2 = "{"; - const peg$c3 = "}"; - const peg$c4 = ":"; - const peg$c5 = "[]"; - const peg$c6 = "fact"; - const peg$c7 = "relation"; - const peg$c8 = "*"; - const peg$c9 = "("; - const peg$c10 = ")"; - const peg$c11 = "source"; - const peg$c12 = "within"; - const peg$c13 = "evidence"; - const peg$c14 = "measure"; - const peg$c15 = "return"; - const peg$c16 = "NEVER"; - const peg$c17 = "ALWAYS"; - const peg$c18 = "REQUIRES"; - const peg$c19 = "WHEN"; - const peg$c20 = "UNLESS"; - const peg$c21 = "|"; - const peg$c22 = "fusion"; - const peg$c23 = ","; - const peg$c24 = "with"; - const peg$c25 = "aggregate"; - const peg$c26 = "USING"; - const peg$c27 = "PROVIDES"; - const peg$c28 = "BEHAVES"; - const peg$c29 = "AS"; - const peg$c30 = "edge"; - const peg$c31 = "transitive"; - const peg$c32 = "hierarchical"; - const peg$c33 = "symmetrical_graph"; - const peg$c34 = "symmetrical"; - const peg$c35 = "limit"; - const peg$c36 = "decaying"; - const peg$c37 = "up"; - const peg$c38 = "down"; - const peg$c39 = "neutral"; - const peg$c40 = "stable"; - const peg$c41 = "hourly"; - const peg$c42 = "daily"; - const peg$c43 = "weekly"; - const peg$c44 = "monthly"; - const peg$c45 = "blurring"; - const peg$c46 = "fixed"; - const peg$c47 = "adaptive"; - const peg$c48 = "confidence"; - const peg$c49 = "confidence_90"; - const peg$c50 = "confidence_95"; - const peg$c51 = "confidence_99"; - const peg$c52 = "ttl"; - const peg$c53 = "CACHE"; - const peg$c54 = "eager"; - const peg$c55 = "lazy"; - const peg$c56 = "||"; - const peg$c57 = "&&"; - const peg$c58 = "is"; - const peg$c59 = "=="; - const peg$c60 = "!="; - const peg$c61 = ">="; - const peg$c62 = "<="; - const peg$c63 = "NOT"; - const peg$c64 = "!"; - const peg$c65 = "."; - const peg$c66 = "\""; - const peg$c67 = "\\"; - const peg$c68 = "'"; - const peg$c69 = "true"; - const peg$c70 = "false"; - const peg$c71 = "//"; - const peg$c72 = "/*"; - const peg$c73 = "*/"; - - const peg$r0 = /^[<>]/; - const peg$r1 = /^[+\-]/; - const peg$r2 = /^[*\/]/; - const peg$r3 = /^["\\]/; - const peg$r4 = /^['\\]/; - const peg$r5 = /^[0-9]/; - const peg$r6 = /^[dhmw]/; - const peg$r7 = /^[a-zA-Z_]/; - const peg$r8 = /^[a-zA-Z0-9_]/; - const peg$r9 = /^[ \t]/; - const peg$r10 = /^[ \t\r\n]/; - const peg$r11 = /^[^\r\n]/; - - const peg$e0 = peg$otherExpectation("A type definition"); - const peg$e1 = peg$literalExpectation("definition", false); - const peg$e2 = peg$literalExpectation("type", false); - const peg$e3 = peg$literalExpectation("{", false); - const peg$e4 = peg$literalExpectation("}", false); - const peg$e5 = peg$literalExpectation(":", false); - const peg$e6 = peg$literalExpectation("[]", false); - const peg$e7 = peg$otherExpectation("A statement of fact (or relation in ADR-000)"); - const peg$e8 = peg$literalExpectation("fact", false); - const peg$e9 = peg$literalExpectation("relation", false); - const peg$e10 = peg$literalExpectation("*", false); - const peg$e11 = peg$literalExpectation("(", false); - const peg$e12 = peg$literalExpectation(")", false); - const peg$e13 = peg$otherExpectation("An injectable source (proof provider)"); - const peg$e14 = peg$literalExpectation("source", false); - const peg$e15 = peg$otherExpectation("A freshness constraint on a source"); - const peg$e16 = peg$literalExpectation("within", false); - const peg$e17 = peg$otherExpectation("An evidence rule"); - const peg$e18 = peg$literalExpectation("evidence", false); - const peg$e19 = peg$otherExpectation("A derived measurement or value"); - const peg$e20 = peg$literalExpectation("measure", false); - const peg$e21 = peg$literalExpectation("return", false); - const peg$e22 = peg$literalExpectation("NEVER", false); - const peg$e23 = peg$literalExpectation("ALWAYS", false); - const peg$e24 = peg$literalExpectation("REQUIRES", false); - const peg$e25 = peg$literalExpectation("WHEN", false); - const peg$e26 = peg$literalExpectation("UNLESS", false); - const peg$e27 = peg$literalExpectation("|", false); - const peg$e28 = peg$literalExpectation("fusion", false); - const peg$e29 = peg$literalExpectation(",", false); - const peg$e30 = peg$literalExpectation("with", false); - const peg$e31 = peg$literalExpectation("aggregate", false); - const peg$e32 = peg$literalExpectation("USING", false); - const peg$e33 = peg$literalExpectation("PROVIDES", false); - const peg$e34 = peg$literalExpectation("BEHAVES", false); - const peg$e35 = peg$literalExpectation("AS", false); - const peg$e36 = peg$literalExpectation("edge", false); - const peg$e37 = peg$literalExpectation("transitive", false); - const peg$e38 = peg$literalExpectation("hierarchical", false); - const peg$e39 = peg$literalExpectation("symmetrical_graph", false); - const peg$e40 = peg$literalExpectation("symmetrical", false); - const peg$e41 = peg$literalExpectation("limit", false); - const peg$e42 = peg$literalExpectation("decaying", false); - const peg$e43 = peg$literalExpectation("up", false); - const peg$e44 = peg$literalExpectation("down", false); - const peg$e45 = peg$literalExpectation("neutral", false); - const peg$e46 = peg$literalExpectation("stable", false); - const peg$e47 = peg$literalExpectation("hourly", false); - const peg$e48 = peg$literalExpectation("daily", false); - const peg$e49 = peg$literalExpectation("weekly", false); - const peg$e50 = peg$literalExpectation("monthly", false); - const peg$e51 = peg$literalExpectation("blurring", false); - const peg$e52 = peg$literalExpectation("fixed", false); - const peg$e53 = peg$literalExpectation("adaptive", false); - const peg$e54 = peg$literalExpectation("confidence", false); - const peg$e55 = peg$literalExpectation("confidence_90", false); - const peg$e56 = peg$literalExpectation("confidence_95", false); - const peg$e57 = peg$literalExpectation("confidence_99", false); - const peg$e58 = peg$literalExpectation("ttl", false); - const peg$e59 = peg$literalExpectation("CACHE", false); - const peg$e60 = peg$literalExpectation("eager", false); - const peg$e61 = peg$literalExpectation("lazy", false); - const peg$e62 = peg$literalExpectation("||", false); - const peg$e63 = peg$literalExpectation("&&", false); - const peg$e64 = peg$literalExpectation("is", false); - const peg$e65 = peg$literalExpectation("==", false); - const peg$e66 = peg$literalExpectation("!=", false); - const peg$e67 = peg$literalExpectation(">=", false); - const peg$e68 = peg$literalExpectation("<=", false); - const peg$e69 = peg$classExpectation(["<", ">"], false, false, false); - const peg$e70 = peg$classExpectation(["+", "-"], false, false, false); - const peg$e71 = peg$classExpectation(["*", "/"], false, false, false); - const peg$e72 = peg$literalExpectation("NOT", false); - const peg$e73 = peg$literalExpectation("!", false); - const peg$e74 = peg$literalExpectation(".", false); - const peg$e75 = peg$otherExpectation("The non-recursive base for an expression chain"); - const peg$e76 = peg$otherExpectation("A string literal"); - const peg$e77 = peg$literalExpectation("\"", false); - const peg$e78 = peg$classExpectation(["\"", "\\"], false, false, false); - const peg$e79 = peg$anyExpectation(); - const peg$e80 = peg$literalExpectation("\\", false); - const peg$e81 = peg$literalExpectation("'", false); - const peg$e82 = peg$classExpectation(["'", "\\"], false, false, false); - const peg$e83 = peg$otherExpectation("A floating-point number"); - const peg$e84 = peg$classExpectation([["0", "9"]], false, false, false); - const peg$e85 = peg$otherExpectation("An integer"); - const peg$e86 = peg$otherExpectation("A boolean literal"); - const peg$e87 = peg$literalExpectation("true", false); - const peg$e88 = peg$literalExpectation("false", false); - const peg$e89 = peg$otherExpectation("A time duration literal"); - const peg$e90 = peg$classExpectation(["d", "h", "m", "w"], false, false, false); - const peg$e91 = peg$classExpectation([["a", "z"], ["A", "Z"], "_"], false, false, false); - const peg$e92 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_"], false, false, false); - const peg$e93 = peg$classExpectation([" ", "\t"], false, false, false); - const peg$e94 = peg$classExpectation([" ", "\t", "\r", "\n"], false, false, false); - const peg$e95 = peg$literalExpectation("//", false); - const peg$e96 = peg$classExpectation(["\r", "\n"], true, false, false); - const peg$e97 = peg$literalExpectation("/*", false); - const peg$e98 = peg$literalExpectation("*/", false); - - function peg$f0(statements) { - const allStatements = statements.map(s => s[0]); - return { - type: "Program", - body: allStatements, - definitions: allStatements.filter(s => s.type === "Definition"), - facts: allStatements.filter(s => s.type === "Fact"), - evidence: allStatements.filter(s => s.type === "Evidence"), - measures: allStatements.filter(s => s.type === "Measure"), - sources: allStatements.filter(s => s.type === "Source") - }; - } - function peg$f1(name, fields) { - return { type: "Definition", name, fields: fields.map(f => f[0]) }; - } - function peg$f2(name, fieldType, isArray, behavior, cache) { - return { - type: "Field", - name, - fieldType, - isArray: !!isArray, - behavior: behavior || null, - cache: cache || null - }; - } - function peg$f3(star, name, params, behavior, properties, cache, limit) { - return { - type: "Fact", - name, - params: params || [], - behavior: behavior || null, - properties: properties.map(p => p[0]), - cache: cache || null, - limit: limit || null, - injectable: !!star - }; - } - function peg$f4(star, name, params, provides, within) { - return { - type: "Source", - name, - params: params || [], - provides: provides || null, - injectable: !!star, - within: within || null - }; - } - function peg$f5(duration) { return duration; } - function peg$f6(star, name, params, limit, body, provides) { - return { - type: "Evidence", - name, - params: params || [], - limit: limit || null, - body, - provides: provides || null, - challenge: !!star - }; - } - function peg$f7(name, params, body, provides) { - return { - type: "Measure", - name, - params: params || [], - body, - provides: provides || null - }; - } - function peg$f8(statements) { - return { type: "EvidenceBody", statements: statements.map(s => s[0]) }; - } - function peg$f9(statements, returnStmt) { - return { - type: "MeasureBody", - statements: statements.map(s => s[0]), - returnStatement: returnStmt || null - }; - } - function peg$f10(expression) { - return { type: "ReturnStatement", expression }; - } - function peg$f11(type, condition) { - return { type: "DefeasibleLogic", logicType: type, condition }; - } - function peg$f12(condition, defeater) { - return { type: "DefeasibleLogic", logicType: "WHEN", condition, defeater }; - } - function peg$f13(condition) { - return { type: "DefeasibleLogic", logicType: "WHEN", condition }; - } - function peg$f14(predicate, binding, body, limit, withClause) { - return { - type: "PatternMatch", - predicate, - binding: binding || null, - limit: limit || null, - body, - withClause: withClause || null - }; - } - function peg$f15(measure, variable, fusionStrategy, body, limit) { - return { - type: "CollectionProcessing", - measure, - variable, - fusion: fusionStrategy ? { strategy: fusionStrategy[1] } : null, - body, - limit: limit || null - }; - } - function peg$f16(name, args) { - return { type: "Predicate", name, args: args || [] }; - } - function peg$f17(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f18(name) { return { type: "Wildcard", name }; } - function peg$f19(name) { return name; } - function peg$f20(condition) { return condition; } - function peg$f21(strategy, expressions) { - return { type: "Fusion", strategy, expressions }; - } - function peg$f22(expressions, using) { - return { type: "Aggregation", expressions, using: using || null }; - } - function peg$f23(method) { return method; } - function peg$f24(name) { return { type: "TypeName", name }; } - function peg$f25(literal) { return { type: "TypeName", name: literal.value }; } - function peg$f26(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f27(name, paramType, isArray) { - return { type: "Parameter", name, paramType, isArray: !!isArray }; - } - function peg$f28(providesType) { return providesType; } - function peg$f29(behavior) { - return { type: "BehaviorAnnotation", behavior }; - } - function peg$f30() { return "transitive"; } - function peg$f31() { return "symmetrical"; } - function peg$f32(value) { return value; } - function peg$f33(b) { return b; } - function peg$f34(direction, period) { - return { type: "Behavior", behaviorType: "decay", direction, period }; - } - function peg$f35(mode, confidence) { - return { type: "Behavior", behaviorType: "blur", mode, confidence: confidence ? confidence[1] : null }; - } - function peg$f36(duration) { - return { type: "Behavior", behaviorType: "ttl", duration }; - } - function peg$f37(directive) { return directive; } - function peg$f38(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f39(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f40(head, typeName) { - return { type: "BinaryExpression", operator: "is", left: head, right: typeName }; - } - function peg$f41(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f42(head, right) { - return { type: "BinaryExpression", operator: "within", left: head, right }; - } - function peg$f43(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f44(head, tail) { return buildLeftAssoc(head, tail); } - function peg$f45(operator, operand) { return { type: "UnaryExpression", operator: "NOT", operand }; } - function peg$f46(primary, binding) { - if (binding) { - return { type: "BindingAccess", expression: primary, binding }; - } - return primary; - } - function peg$f47(head, tail) { - return tail.reduce((obj, part) => { - return { - type: "AttributeAccess", - object: obj, - attribute: part[3], // The Identifier is the 4th element (index 3) - location: location() - }; - }, head); - } - function peg$f48(expr) { return expr; } - function peg$f49(name, args) { - return { type: "PredicateCall", name, args: args || [], challenge: true }; - } - function peg$f50(name, args) { - return { type: "PredicateCall", name, args: args || [] }; - } - function peg$f51(name) { return { type: "Variable", name }; } - function peg$f52(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f53(head, tail) { - return [head, ...tail.map(t => t[3])]; - } - function peg$f54(chars) { - return { type: "Literal", value: JSON.parse(text()) }; - } - function peg$f55(chars) { - return { type: "Literal", value: JSON.parse("\"" + chars.map(c => c[0] === '\\' ? c[1] : c[1]).join('') + "\"") }; - } - function peg$f56(value) { return { type: "Literal", value: parseFloat(text()) }; } - function peg$f57(value) { return { type: "Literal", value: parseInt(text(), 10) }; } - function peg$f58(value) { return { type: "Literal", value: value === "true" }; } - function peg$f59(value) { return { type: "Literal", value: text(), unit: text().slice(-1) }; } - function peg$f60(name) { return name; } - let peg$currPos = options.peg$currPos | 0; - let peg$savedPos = peg$currPos; - const peg$posDetailsCache = [{ line: 1, column: 1 }]; - let peg$maxFailPos = peg$currPos; - let peg$maxFailExpected = options.peg$maxFailExpected || []; - let peg$silentFails = options.peg$silentFails | 0; - - let peg$result; - - if (options.startRule) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function text() { - return input.substring(peg$savedPos, peg$currPos); - } - - function offset() { - return peg$savedPos; - } - - function range() { - return { - source: peg$source, - start: peg$savedPos, - end: peg$currPos, - }; - } - - function location() { - return peg$computeLocation(peg$savedPos, peg$currPos); - } - - function expected(description, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildStructuredError( - [peg$otherExpectation(description)], - input.substring(peg$savedPos, peg$currPos), - location - ); - } - - function error(message, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildSimpleError(message, location); - } - - function peg$getUnicode(pos = peg$currPos) { - const cp = input.codePointAt(pos); - if (cp === undefined) { - return ""; - } - return String.fromCodePoint(cp); - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text, ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase, unicode) { - return { type: "class", parts, inverted, ignoreCase, unicode }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$otherExpectation(description) { - return { type: "other", description }; - } - - function peg$computePosDetails(pos) { - let details = peg$posDetailsCache[pos]; - let p; - - if (details) { - return details; - } else { - if (pos >= peg$posDetailsCache.length) { - p = peg$posDetailsCache.length - 1; - } else { - p = pos; - while (!peg$posDetailsCache[--p]) {} - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column, - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - - return details; - } - } - - function peg$computeLocation(startPos, endPos, offset) { - const startPosDetails = peg$computePosDetails(startPos); - const endPosDetails = peg$computePosDetails(endPos); - - const res = { - source: peg$source, - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column, - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column, - }, - }; - if (offset && peg$source && (typeof peg$source.offset === "function")) { - res.start = peg$source.offset(res.start); - res.end = peg$source.offset(res.end); - } - return res; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildSimpleError(message, location) { - return new peg$SyntaxError(message, null, null, location); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError( - peg$SyntaxError.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parseProgram() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parse_(); - s2 = []; - s3 = peg$currPos; - s4 = peg$parseStatement(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parseStatement(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - s3 = peg$parse_(); - peg$savedPos = s0; - s0 = peg$f0(s2); - - return s0; - } - - function peg$parseStatement() { - let s0; - - s0 = peg$parseDefinition(); - if (s0 === peg$FAILED) { - s0 = peg$parseSource(); - if (s0 === peg$FAILED) { - s0 = peg$parseFact(); - if (s0 === peg$FAILED) { - s0 = peg$parseEvidence(); - if (s0 === peg$FAILED) { - s0 = peg$parseMeasure(); - } - } - } - } - - return s0; - } - - function peg$parseDefinition() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 10) === peg$c0) { - s1 = peg$c0; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c1) { - s1 = peg$c1; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = []; - s8 = peg$currPos; - s9 = peg$parseField(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s9 = [s9, s10]; - s8 = s9; - } else { - peg$currPos = s8; - s8 = peg$FAILED; - } - while (s8 !== peg$FAILED) { - s7.push(s8); - s8 = peg$currPos; - s9 = peg$parseField(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s9 = [s9, s10]; - s8 = s9; - } else { - peg$currPos = s8; - s8 = peg$FAILED; - } - } - if (input.charCodeAt(peg$currPos) === 125) { - s8 = peg$c3; - peg$currPos++; - } else { - s8 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s8 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f1(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e0); } - } - - return s0; - } - - function peg$parseField() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c4; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c5) { - s7 = peg$c5; - peg$currPos += 2; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - s8 = peg$parse_(); - s9 = peg$parseBehavior(); - if (s9 === peg$FAILED) { - s9 = null; - } - s10 = peg$parse_(); - s11 = peg$parseCacheDirective(); - if (s11 === peg$FAILED) { - s11 = null; - } - peg$savedPos = s0; - s0 = peg$f2(s1, s5, s7, s9, s11); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseFact() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c6) { - s1 = peg$c6; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c7) { - s1 = peg$c7; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 42) { - s3 = peg$c8; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s3 === peg$FAILED) { - s3 = null; - } - s4 = peg$parseIdentifier(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s6 = peg$c9; - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - s8 = peg$parseParameterList(); - if (s8 === peg$FAILED) { - s8 = null; - } - s9 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s10 = peg$c10; - peg$currPos++; - } else { - s10 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s10 !== peg$FAILED) { - s11 = peg$parse_(); - s12 = peg$parseBehaviorAnnotation(); - if (s12 === peg$FAILED) { - s12 = null; - } - s13 = peg$parse_(); - s14 = []; - s15 = peg$currPos; - s16 = peg$parseFactProperty(); - if (s16 !== peg$FAILED) { - s17 = peg$parse_(); - s16 = [s16, s17]; - s15 = s16; - } else { - peg$currPos = s15; - s15 = peg$FAILED; - } - while (s15 !== peg$FAILED) { - s14.push(s15); - s15 = peg$currPos; - s16 = peg$parseFactProperty(); - if (s16 !== peg$FAILED) { - s17 = peg$parse_(); - s16 = [s16, s17]; - s15 = s16; - } else { - peg$currPos = s15; - s15 = peg$FAILED; - } - } - s15 = peg$parseCacheDirective(); - if (s15 === peg$FAILED) { - s15 = null; - } - s16 = peg$parse_(); - s17 = peg$parseLimit(); - if (s17 === peg$FAILED) { - s17 = null; - } - peg$savedPos = s0; - s0 = peg$f3(s3, s4, s8, s12, s14, s15, s17); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } - } - - return s0; - } - - function peg$parseSource() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c11) { - s1 = peg$c11; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 42) { - s3 = peg$c8; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s3 === peg$FAILED) { - s3 = null; - } - s4 = peg$parseIdentifier(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s6 = peg$c9; - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - s8 = peg$parseParameterList(); - if (s8 === peg$FAILED) { - s8 = null; - } - s9 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s10 = peg$c10; - peg$currPos++; - } else { - s10 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s10 !== peg$FAILED) { - s11 = peg$parse_(); - s12 = peg$parseProvides(); - if (s12 === peg$FAILED) { - s12 = null; - } - s13 = peg$parse_(); - s14 = peg$parseWithinClause(); - if (s14 === peg$FAILED) { - s14 = null; - } - peg$savedPos = s0; - s0 = peg$f4(s3, s4, s8, s12, s14); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e13); } - } - - return s0; - } - - function peg$parseWithinClause() { - let s0, s1, s2, s3; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c12) { - s1 = peg$c12; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseDuration(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f5(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e15); } - } - - return s0; - } - - function peg$parseEvidence() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c13) { - s1 = peg$c13; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 42) { - s3 = peg$c8; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s3 === peg$FAILED) { - s3 = null; - } - s4 = peg$parseIdentifier(); - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s6 = peg$c9; - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - s8 = peg$parseParameterList(); - if (s8 === peg$FAILED) { - s8 = null; - } - s9 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s10 = peg$c10; - peg$currPos++; - } else { - s10 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s10 !== peg$FAILED) { - s11 = peg$parse_(); - s12 = peg$parseLimit(); - if (s12 === peg$FAILED) { - s12 = null; - } - s13 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s14 = peg$c2; - peg$currPos++; - } else { - s14 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s14 !== peg$FAILED) { - s15 = peg$parse_(); - s16 = peg$parseEvidenceBody(); - s17 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s18 = peg$c3; - peg$currPos++; - } else { - s18 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s18 !== peg$FAILED) { - s19 = peg$parse_(); - s20 = peg$parseProvides(); - if (s20 === peg$FAILED) { - s20 = null; - } - peg$savedPos = s0; - s0 = peg$f6(s3, s4, s8, s12, s16, s20); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e17); } - } - - return s0; - } - - function peg$parseMeasure() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 7) === peg$c14) { - s1 = peg$c14; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s5 = peg$c9; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameterList(); - if (s7 === peg$FAILED) { - s7 = null; - } - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c10; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s11 = peg$c2; - peg$currPos++; - } else { - s11 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - s13 = peg$parseMeasureBody(); - s14 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s15 = peg$c3; - peg$currPos++; - } else { - s15 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s17 = peg$parseProvides(); - if (s17 === peg$FAILED) { - s17 = null; - } - peg$savedPos = s0; - s0 = peg$f7(s3, s7, s13, s17); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e19); } - } - - return s0; - } - - function peg$parseEvidenceBody() { - let s0, s1, s2, s3, s4; - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseEvidenceStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseEvidenceStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - peg$savedPos = s0; - s1 = peg$f8(s1); - s0 = s1; - - return s0; - } - - function peg$parseEvidenceStatement() { - let s0; - - s0 = peg$parseDefeasibleLogic(); - if (s0 === peg$FAILED) { - s0 = peg$parseFusion(); - if (s0 === peg$FAILED) { - s0 = peg$parseCollectionProcessing(); - if (s0 === peg$FAILED) { - s0 = peg$parsePatternMatch(); - if (s0 === peg$FAILED) { - s0 = peg$parseLogicalOr(); - } - } - } - } - - return s0; - } - - function peg$parseMeasureBody() { - let s0, s1, s2, s3, s4; - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseMeasureStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseMeasureStatement(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - s2 = peg$parseReturnStatement(); - if (s2 === peg$FAILED) { - s2 = null; - } - peg$savedPos = s0; - s0 = peg$f9(s1, s2); - - return s0; - } - - function peg$parseMeasureStatement() { - let s0; - - s0 = peg$parseFusion(); - if (s0 === peg$FAILED) { - s0 = peg$parseAggregation(); - if (s0 === peg$FAILED) { - s0 = peg$parsePatternMatch(); - if (s0 === peg$FAILED) { - s0 = peg$parseLogicalOr(); - } - } - } - - return s0; - } - - function peg$parseReturnStatement() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c15) { - s1 = peg$c15; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f10(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseDefeasibleLogic() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c16) { - s1 = peg$c16; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e22); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c17) { - s1 = peg$c17; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c18) { - s1 = peg$c18; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f11(s1, s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c19) { - s1 = peg$c19; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c20) { - s5 = peg$c20; - peg$currPos += 6; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e26); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse__(); - if (s6 !== peg$FAILED) { - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f12(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c19) { - s1 = peg$c19; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f13(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - - return s0; - } - - function peg$parsePatternMatch() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; - - s0 = peg$currPos; - s1 = peg$parsePatternPredicate(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseBindingClause(); - if (s3 === peg$FAILED) { - s3 = null; - } - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseEvidenceBody(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s9 = peg$c3; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - s11 = peg$parseLimit(); - if (s11 === peg$FAILED) { - s11 = null; - } - s12 = peg$parse_(); - s13 = peg$parseWithClause(); - if (s13 === peg$FAILED) { - s13 = null; - } - peg$savedPos = s0; - s0 = peg$f14(s1, s3, s7, s11, s13); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseCollectionProcessing() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17; - - s0 = peg$currPos; - s1 = peg$parseLogicalOr(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 124) { - s3 = peg$c21; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e27); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 124) { - s7 = peg$c21; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e27); } - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - s9 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c22) { - s10 = peg$c22; - peg$currPos += 6; - } else { - s10 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e28); } - } - if (s10 !== peg$FAILED) { - s11 = peg$parse__(); - if (s11 !== peg$FAILED) { - s12 = peg$parseIdentifier(); - if (s12 !== peg$FAILED) { - s10 = [s10, s11, s12]; - s9 = s10; - } else { - peg$currPos = s9; - s9 = peg$FAILED; - } - } else { - peg$currPos = s9; - s9 = peg$FAILED; - } - } else { - peg$currPos = s9; - s9 = peg$FAILED; - } - if (s9 === peg$FAILED) { - s9 = null; - } - s10 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 123) { - s11 = peg$c2; - peg$currPos++; - } else { - s11 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - s13 = peg$parseEvidenceBody(); - if (s13 !== peg$FAILED) { - s14 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s15 = peg$c3; - peg$currPos++; - } else { - s15 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s15 !== peg$FAILED) { - s16 = peg$parse_(); - s17 = peg$parseLimit(); - if (s17 === peg$FAILED) { - s17 = null; - } - peg$savedPos = s0; - s0 = peg$f15(s1, s5, s9, s13, s17); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePatternPredicate() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s3 = peg$c9; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parsePatternArgumentList(); - if (s5 === peg$FAILED) { - s5 = null; - } - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s7 = peg$c10; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f16(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePatternArgumentList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parsePatternArgument(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c23; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parsePatternArgument(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c23; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parsePatternArgument(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f17(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePatternArgument() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c8; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f18(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parseLogicalOr(); - } - - return s0; - } - - function peg$parseBindingClause() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 124) { - s1 = peg$c21; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e27); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 124) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e27); } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f19(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseWithClause() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c24) { - s1 = peg$c24; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e30); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f20(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseFusion() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c22) { - s1 = peg$c22; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e28); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s5 = peg$c2; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseExpressionList(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s9 = peg$c3; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s9 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f21(s3, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseAggregation() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 9) === peg$c25) { - s1 = peg$c25; - peg$currPos += 9; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e31); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s3 = peg$c2; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseExpressionList(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s7 = peg$c3; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - s9 = peg$parseUsing(); - if (s9 === peg$FAILED) { - s9 = null; - } - peg$savedPos = s0; - s0 = peg$f22(s5, s9); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseUsing() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c26) { - s1 = peg$c26; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e32); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f23(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseTypeName() { - let s0, s1; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f24(s1); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseString(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f25(s1); - } - s0 = s1; - } - - return s0; - } - - function peg$parseParameterList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseParameter(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c23; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameter(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c23; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseParameter(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f26(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseParameter() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c4; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseIdentifier(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c5) { - s7 = peg$c5; - peg$currPos += 2; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - peg$savedPos = s0; - s0 = peg$f27(s1, s5, s7); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseProvides() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c27) { - s1 = peg$c27; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e33); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseIdentifier(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f28(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBehaviorAnnotation() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 7) === peg$c28) { - s1 = peg$c28; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c29) { - s3 = peg$c29; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e35); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c30) { - s5 = peg$c30; - peg$currPos += 4; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c31) { - s5 = peg$c31; - peg$currPos += 10; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 12) === peg$c32) { - s5 = peg$c32; - peg$currPos += 12; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e38); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 17) === peg$c33) { - s5 = peg$c33; - peg$currPos += 17; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e39); } - } - } - } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f29(s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseFactProperty() { - let s0, s1; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 10) === peg$c31) { - s1 = peg$c31; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f30(); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 11) === peg$c34) { - s1 = peg$c34; - peg$currPos += 11; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e40); } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f31(); - } - s0 = s1; - } - - return s0; - } - - function peg$parseLimit() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c35) { - s1 = peg$c35; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e41); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseInteger(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f32(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBehavior() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 7) === peg$c28) { - s1 = peg$c28; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 123) { - s3 = peg$c2; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - s5 = peg$parseDecayBehavior(); - if (s5 === peg$FAILED) { - s5 = peg$parseBlurBehavior(); - if (s5 === peg$FAILED) { - s5 = peg$parseTTLBehavior(); - } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 125) { - s7 = peg$c3; - peg$currPos++; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f33(s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseDecayBehavior() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c36) { - s1 = peg$c36; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e42); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c37) { - s3 = peg$c37; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e43); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c38) { - s3 = peg$c38; - peg$currPos += 4; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e44); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c39) { - s3 = peg$c39; - peg$currPos += 7; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e45); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c40) { - s3 = peg$c40; - peg$currPos += 6; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e46); } - } - } - } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c41) { - s5 = peg$c41; - peg$currPos += 6; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e47); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c42) { - s5 = peg$c42; - peg$currPos += 5; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e48); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c43) { - s5 = peg$c43; - peg$currPos += 6; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e49); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c44) { - s5 = peg$c44; - peg$currPos += 7; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e50); } - } - } - } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f34(s3, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseBlurBehavior() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c45) { - s1 = peg$c45; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e51); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c46) { - s3 = peg$c46; - peg$currPos += 5; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e52); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c47) { - s3 = peg$c47; - peg$currPos += 8; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e53); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c48) { - s3 = peg$c48; - peg$currPos += 10; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e54); } - } - } - } - if (s3 !== peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse__(); - if (s5 !== peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c49) { - s6 = peg$c49; - peg$currPos += 13; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e55); } - } - if (s6 === peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c50) { - s6 = peg$c50; - peg$currPos += 13; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e56); } - } - if (s6 === peg$FAILED) { - if (input.substr(peg$currPos, 13) === peg$c51) { - s6 = peg$c51; - peg$currPos += 13; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e57); } - } - } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = null; - } - peg$savedPos = s0; - s0 = peg$f35(s3, s4); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseTTLBehavior() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c52) { - s1 = peg$c52; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e58); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseDuration(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f36(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseCacheDirective() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c53) { - s1 = peg$c53; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e59); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c54) { - s3 = peg$c54; - peg$currPos += 5; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e60); } - } - if (s3 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c55) { - s3 = peg$c55; - peg$currPos += 4; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e61); } - } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f37(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLogicalOr() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseLogicalAnd(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c56) { - s5 = peg$c56; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e62); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalAnd(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c56) { - s5 = peg$c56; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e62); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalAnd(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f38(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLogicalAnd() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseComparison(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c57) { - s5 = peg$c57; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e63); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c57) { - s5 = peg$c57; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e63); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f39(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseComparison() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseTemporalComparison(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c58) { - s3 = peg$c58; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e64); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - s5 = peg$parseTypeName(); - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f40(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseTemporalComparison(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c59) { - s5 = peg$c59; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e65); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c60) { - s5 = peg$c60; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e66); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c61) { - s5 = peg$c61; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e67); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c62) { - s5 = peg$c62; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e68); } - } - if (s5 === peg$FAILED) { - s5 = input.charAt(peg$currPos); - if (peg$r0.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e69); } - } - } - } - } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseTemporalComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.substr(peg$currPos, 2) === peg$c59) { - s5 = peg$c59; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e65); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c60) { - s5 = peg$c60; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e66); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c61) { - s5 = peg$c61; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e67); } - } - if (s5 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c62) { - s5 = peg$c62; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e68); } - } - if (s5 === peg$FAILED) { - s5 = input.charAt(peg$currPos); - if (peg$r0.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e69); } - } - } - } - } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseTemporalComparison(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f41(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - return s0; - } - - function peg$parseTemporalComparison() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parseAddition(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (input.substr(peg$currPos, 6) === peg$c12) { - s3 = peg$c12; - peg$currPos += 6; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse__(); - if (s4 !== peg$FAILED) { - s5 = peg$parseDuration(); - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f42(s1, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parseAddition(); - } - - return s0; - } - - function peg$parseAddition() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseMultiplication(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_i(); - s5 = input.charAt(peg$currPos); - if (peg$r1.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e70); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_i(); - s7 = peg$parseMultiplication(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_i(); - s5 = input.charAt(peg$currPos); - if (peg$r1.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e70); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_i(); - s7 = peg$parseMultiplication(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f43(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseMultiplication() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseUnary(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_i(); - s5 = input.charAt(peg$currPos); - if (peg$r2.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e71); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_i(); - s7 = peg$parseUnary(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_i(); - s5 = input.charAt(peg$currPos); - if (peg$r2.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e71); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_i(); - s7 = peg$parseUnary(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f44(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseUnary() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c63) { - s1 = peg$c63; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e72); } - } - if (s1 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c64; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e73); } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseUnary(); - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f45(s1, s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$parsePostfix(); - } - - return s0; - } - - function peg$parsePostfix() { - let s0, s1, s2; - - s0 = peg$currPos; - s1 = peg$parseAttributeAccess(); - if (s1 === peg$FAILED) { - s1 = peg$parsePrimaryTerm(); - } - if (s1 !== peg$FAILED) { - s2 = peg$parseBindingClause(); - if (s2 === peg$FAILED) { - s2 = null; - } - peg$savedPos = s0; - s0 = peg$f46(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseAttributeAccess() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parsePrimaryTerm(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c65; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e74); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseIdentifier(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c65; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e74); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseIdentifier(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f47(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePrimaryTerm() { - let s0, s1, s2, s3, s4, s5; - - peg$silentFails++; - s0 = peg$parseChallengePredicate(); - if (s0 === peg$FAILED) { - s0 = peg$parseLiteral(); - if (s0 === peg$FAILED) { - s0 = peg$parsePredicateCall(); - if (s0 === peg$FAILED) { - s0 = peg$parseVariable(); - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c9; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - s3 = peg$parseLogicalOr(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c10; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f48(s3); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e75); } - } - - return s0; - } - - function peg$parseChallengePredicate() { - let s0, s1, s2, s3, s4, s5, s6, s7, s8; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c8; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseIdentifier(); - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 40) { - s4 = peg$c9; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - s6 = peg$parseArgumentList(); - if (s6 === peg$FAILED) { - s6 = null; - } - s7 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s8 = peg$c10; - peg$currPos++; - } else { - s8 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s8 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f49(s2, s6); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsePredicateCall() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 40) { - s2 = peg$c9; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - s4 = peg$parseArgumentList(); - if (s4 === peg$FAILED) { - s4 = null; - } - s5 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 41) { - s6 = peg$c10; - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s6 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f50(s1, s4); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseVariable() { - let s0, s1; - - s0 = peg$currPos; - s1 = peg$parseIdentifier(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f51(s1); - } - s0 = s1; - - return s0; - } - - function peg$parseArgumentList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseLogicalOr(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c23; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c23; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f52(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseExpressionList() { - let s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseLogicalOr(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c23; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c23; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e29); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - s7 = peg$parseLogicalOr(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f53(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseLiteral() { - let s0; - - s0 = peg$parseString(); - if (s0 === peg$FAILED) { - s0 = peg$parseFloat(); - if (s0 === peg$FAILED) { - s0 = peg$parseInteger(); - if (s0 === peg$FAILED) { - s0 = peg$parseBoolean(); - if (s0 === peg$FAILED) { - s0 = peg$parseDuration(); - } - } - } - } - - return s0; - } - - function peg$parseString() { - let s0, s1, s2, s3, s4, s5; - - peg$silentFails++; - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c66; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r3.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e78); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c67; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e80); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r3.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e78); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c67; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e80); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c66; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e77); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f54(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c68; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r4.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e82); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c67; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e80); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - s5 = input.charAt(peg$currPos); - if (peg$r4.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e82); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s4 = peg$c67; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e80); } - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c68; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e81); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f55(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e76); } - } - - return s0; - } - - function peg$parseFloat() { - let s0, s1, s2, s3, s4, s5; - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s3 = peg$c65; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e74); } - } - if (s3 !== peg$FAILED) { - s4 = []; - s5 = input.charAt(peg$currPos); - if (peg$r5.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - s5 = input.charAt(peg$currPos); - if (peg$r5.test(s5)) { - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f56(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e83); } - } - - return s0; - } - - function peg$parseInteger() { - let s0, s1, s2; - - peg$silentFails++; - s0 = peg$currPos; - s1 = []; - s2 = input.charAt(peg$currPos); - if (peg$r5.test(s2)) { - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - if (s2 !== peg$FAILED) { - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = input.charAt(peg$currPos); - if (peg$r5.test(s2)) { - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - } - } else { - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f57(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e85); } - } - - return s0; - } - - function peg$parseBoolean() { - let s0, s1; - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c69) { - s1 = peg$c69; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e87); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c70) { - s1 = peg$c70; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e88); } - } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f58(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e86); } - } - - return s0; - } - - function peg$parseDuration() { - let s0, s1, s2, s3; - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r5.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e84); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s3 = input.charAt(peg$currPos); - if (peg$r6.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e90); } - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f59(s1); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e89); } - } - - return s0; - } - - function peg$parseIdentifier() { - let s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - s1 = peg$currPos; - peg$silentFails++; - s2 = peg$parseKeyword(); - peg$silentFails--; - if (s2 === peg$FAILED) { - s1 = undefined; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = peg$currPos; - s4 = input.charAt(peg$currPos); - if (peg$r7.test(s4)) { - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e91); } - } - if (s4 !== peg$FAILED) { - s5 = []; - s6 = input.charAt(peg$currPos); - if (peg$r8.test(s6)) { - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e92); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - s6 = input.charAt(peg$currPos); - if (peg$r8.test(s6)) { - peg$currPos++; - } else { - s6 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e92); } - } - } - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f60(s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseKeyword() { - let s0, s1, s2, s3; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 10) === peg$c0) { - s1 = peg$c0; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c1) { - s1 = peg$c1; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c6) { - s1 = peg$c6; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c7) { - s1 = peg$c7; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c13) { - s1 = peg$c13; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c14) { - s1 = peg$c14; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 7) === peg$c28) { - s1 = peg$c28; - peg$currPos += 7; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e34); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c29) { - s1 = peg$c29; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e35); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c53) { - s1 = peg$c53; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e59); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c36) { - s1 = peg$c36; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e42); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c45) { - s1 = peg$c45; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e51); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c52) { - s1 = peg$c52; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e58); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 10) === peg$c31) { - s1 = peg$c31; - peg$currPos += 10; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e37); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 11) === peg$c34) { - s1 = peg$c34; - peg$currPos += 11; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e40); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 12) === peg$c32) { - s1 = peg$c32; - peg$currPos += 12; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e38); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 17) === peg$c33) { - s1 = peg$c33; - peg$currPos += 17; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e39); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c30) { - s1 = peg$c30; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e36); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c35) { - s1 = peg$c35; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e41); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c27) { - s1 = peg$c27; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e33); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c22) { - s1 = peg$c22; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e28); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 9) === peg$c25) { - s1 = peg$c25; - peg$currPos += 9; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e31); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c26) { - s1 = peg$c26; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e32); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c16) { - s1 = peg$c16; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e22); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c17) { - s1 = peg$c17; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e23); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c19) { - s1 = peg$c19; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e25); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c20) { - s1 = peg$c20; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e26); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 8) === peg$c18) { - s1 = peg$c18; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e24); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c24) { - s1 = peg$c24; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e30); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 4) === peg$c69) { - s1 = peg$c69; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e87); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 5) === peg$c70) { - s1 = peg$c70; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e88); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c63) { - s1 = peg$c63; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e72); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c12) { - s1 = peg$c12; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c15) { - s1 = peg$c15; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - if (s1 === peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c58) { - s1 = peg$c58; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e64); } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - peg$silentFails++; - s3 = input.charAt(peg$currPos); - if (peg$r8.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e92); } - } - peg$silentFails--; - if (s3 === peg$FAILED) { - s2 = undefined; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parse_() { - let s0, s1; - - s0 = []; - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - } - - return s0; - } - - function peg$parse_i() { - let s0, s1; - - s0 = []; - s1 = input.charAt(peg$currPos); - if (peg$r9.test(s1)) { - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e93); } - } - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = input.charAt(peg$currPos); - if (peg$r9.test(s1)) { - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e93); } - } - } - - return s0; - } - - function peg$parse__() { - let s0, s1; - - s0 = []; - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - if (s1 !== peg$FAILED) { - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWhiteSpace(); - if (s1 === peg$FAILED) { - s1 = peg$parseComment(); - } - } - } else { - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseWhiteSpace() { - let s0; - - s0 = input.charAt(peg$currPos); - if (peg$r10.test(s0)) { - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e94); } - } - - return s0; - } - - function peg$parseComment() { - let s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c71) { - s1 = peg$c71; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e95); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = input.charAt(peg$currPos); - if (peg$r11.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e96); } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = input.charAt(peg$currPos); - if (peg$r11.test(s3)) { - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e96); } - } - } - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c72) { - s1 = peg$c72; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e97); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - if (input.substr(peg$currPos, 2) === peg$c73) { - s5 = peg$c73; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e98); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - peg$silentFails++; - if (input.substr(peg$currPos, 2) === peg$c73) { - s5 = peg$c73; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e98); } - } - peg$silentFails--; - if (s5 === peg$FAILED) { - s4 = undefined; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - if (input.length > peg$currPos) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e79); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (input.substr(peg$currPos, 2) === peg$c73) { - s3 = peg$c73; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e98); } - } - if (s3 !== peg$FAILED) { - s1 = [s1, s2, s3]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - return s0; - } - - - // The location() function provides line/column info for error reporting. - // The text() function returns the matched text for a rule. - - // Helper function to build a left-associative binary expression tree. - function buildLeftAssoc(head, tail) { - return tail.reduce((result, element) => { - return { - type: "BinaryExpression", - operator: element[1], - left: result, - right: element[3], - location: location() - }; - }, head); - } - - peg$result = peg$startRuleFunction(); - - const peg$success = (peg$result !== peg$FAILED && peg$currPos === input.length); - function peg$throw() { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? peg$getUnicode(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } - if (options.peg$library) { - return /** @type {any} */ ({ - peg$result, - peg$currPos, - peg$FAILED, - peg$maxFailExpected, - peg$maxFailPos, - peg$success, - peg$throw: peg$success ? undefined : peg$throw, - }); - } - if (peg$success) { - return peg$result; - } else { - peg$throw(); - } -} - -const peg$allowedStartRules = [ - "Program" -]; - -export { - peg$allowedStartRules as StartRules, - peg$SyntaxError as SyntaxError, - peg$parse as parse -}; diff --git a/src/ast/parser/PeggyDSLParser.js b/src/ast/parser/PeggyDSLParser.js deleted file mode 100644 index 4dc7deb..0000000 --- a/src/ast/parser/PeggyDSLParser.js +++ /dev/null @@ -1,114 +0,0 @@ -import * as GeneratedParser from './GeneratedParser.js'; - -/** - * Peggy-based DSL Parser - * Uses the generated parser from Peggy grammar - */ -export class PeggyDSLParser { - constructor() { - this.parser = GeneratedParser; - this.errors = []; - } - - /** - * Parse DSL text into AST - * @param {string} dslText - DSL text to parse - * @returns {ProgramNode} Parsed AST - */ - parse(dslText) { - this.errors = []; - - try { - const program = this.parser.parse(dslText); - return program; - } catch (error) { - this.errors.push(`Parse error: ${error.message}`); - - // If the error has location information, add it to the error - if (error.location) { - const location = error.location; - this.errors.push(`Location: line ${location.start.line}, column ${location.start.column}`); - } - - // If the error has expected/found information, add it - if (error.expected && error.found) { - this.errors.push(`Expected: ${error.expected.join(', ')}`); - this.errors.push(`Found: ${error.found}`); - } - - throw new Error(`Parsing failed: ${this.errors.join('; ')}`); - } - } - - /** - * Get parser errors from last parse - * @returns {string[]} Array of parser errors - */ - getErrors() { - return this.errors; - } - - /** - * Validate DSL text without throwing errors - * @param {string} dslText - DSL text to validate - * @returns {Object} Validation result with success status and errors - */ - validate(dslText) { - try { - const program = this.parse(dslText); - return { - success: true, - errors: [], - program: program - }; - } catch (error) { - return { - success: false, - errors: this.errors, - program: null - }; - } - } - - /** - * Parse with options - * @param {string} dslText - DSL text to parse - * @param {Object} options - Parser options - * @returns {ProgramNode} Parsed AST - */ - parseWithOptions(dslText, options = {}) { - this.errors = []; - - try { - const program = this.parser.parse(dslText, options); - return program; - } catch (error) { - this.errors.push(`Parse error: ${error.message}`); - - if (error.location) { - const location = error.location; - this.errors.push(`Location: line ${location.start.line}, column ${location.start.column}`); - } - - if (error.expected && error.found) { - this.errors.push(`Expected: ${error.expected.join(', ')}`); - this.errors.push(`Found: ${error.found}`); - } - - throw new Error(`Parsing failed: ${this.errors.join('; ')}`); - } - } - - /** - * Get parser information - * @returns {Object} Parser information - */ - getParserInfo() { - return { - name: 'PeggyDSLParser', - version: '1.0.0', - generated: true, - grammar: 'dsl.peggy' - }; - } -} diff --git a/src/ast/parser/PeggyWrapper.js b/src/ast/parser/PeggyWrapper.js deleted file mode 100644 index 569019d..0000000 --- a/src/ast/parser/PeggyWrapper.js +++ /dev/null @@ -1,45 +0,0 @@ -// Wrapper for Peggy-generated parser that handles ESM imports correctly -import { - ProgramNode, DefinitionNode, FieldNode, BehaviorNode, FactNode, ParameterNode, - EvidenceNode, EvidenceBodyNode, DirectEvidenceNode, PatternMatchNode, - DefeasibleLogicNode, FusionNode, PredicateNode, ExpressionNode, WithClauseNode, - MeasureNode, MeasureBodyNode, AggregationNode -} from '../nodes/index.js'; - -// Make AST nodes globally available to the generated parser -global.ProgramNode = ProgramNode; -global.DefinitionNode = DefinitionNode; -global.FieldNode = FieldNode; -global.BehaviorNode = BehaviorNode; -global.FactNode = FactNode; -global.ParameterNode = ParameterNode; -global.EvidenceNode = EvidenceNode; -global.EvidenceBodyNode = EvidenceBodyNode; -global.DirectEvidenceNode = DirectEvidenceNode; -global.PatternMatchNode = PatternMatchNode; -global.DefeasibleLogicNode = DefeasibleLogicNode; -global.FusionNode = FusionNode; -global.PredicateNode = PredicateNode; -global.ExpressionNode = ExpressionNode; -global.WithClauseNode = WithClauseNode; -global.MeasureNode = MeasureNode; -global.MeasureBodyNode = MeasureBodyNode; -global.AggregationNode = AggregationNode; - -// Import the generated parser -import { parse } from './GeneratedParser.js'; - -// Create a wrapper class that matches the expected interface -export class PeggyDSLParser { - static parse(text) { - console.log('PeggyDSLParser: Parsing text:', text.substring(0, 100) + '...'); - try { - const result = parse(text); - console.log('PeggyDSLParser: Parse result:', result); - return result; - } catch (error) { - console.error('PeggyDSLParser: Parse error:', error.message); - throw error; - } - } -} diff --git a/src/ast/validation/DSLPrelude.js b/src/ast/validation/DSLPrelude.js deleted file mode 100644 index b74bd79..0000000 --- a/src/ast/validation/DSLPrelude.js +++ /dev/null @@ -1,37 +0,0 @@ -export const DSL_PRELUDE = ` -// Built-in types and relations available in every graph. -// These are intended for request-scoped auth/session evidence (partial graph inputs). - -definition User { - id: string -} - -definition Account { - id: string - tier: string -} - -definition Device { - id: string - device_risk: number - auth_method: string - ip_address: string - user_agent: string -} - -definition AuthSession { - login_time: timestamp - last_login_time: timestamp - mfa_used: boolean - auth_method: string - ip_address: string - user_agent: string - expires_at: timestamp - device_risk: number -} - -fact session_for_user(user: User, session: AuthSession) -fact session_for_account(account: Account, session: AuthSession) -fact session_for_device(device: Device, session: AuthSession) -fact logged_in_as(device: Device, account: Account) -`; diff --git a/src/ast/validation/DSLValidation.js b/src/ast/validation/DSLValidation.js deleted file mode 100644 index 465feee..0000000 --- a/src/ast/validation/DSLValidation.js +++ /dev/null @@ -1,1002 +0,0 @@ -import { parse } from '../parser/GeneratedParser.js'; -import { DSL_PRELUDE } from './DSLPrelude.js'; - -const BUILTIN_TYPES = new Set(['string', 'number', 'boolean', 'timestamp', 'duration', 'object', 'any']); -const BUILTIN_CHALLENGES = new Set([ - 'mfa', - 'webauthn', - 'login', - 'sms', - 'voice', - 'magic_link', - 'email_verified', - 'oauth_session' -]); - -const DEFAULT_EVIDENCE_RETURN = 'boolean'; -const DEFAULT_MEASURE_RETURN = 'any'; - -export function validateDslText(dslText, options = {}) { - const preludeProgram = parsePrelude(options); - let program; - try { - program = parse(dslText); - } catch (error) { - const syntaxError = formatPegError(error, dslText, options.source || 'input'); - return { - success: false, - program: null, - errors: [formatValidationError(syntaxError)], - warnings: [], - errorDetails: [syntaxError] - }; - } - - const errors = []; - const warnings = []; - - const tables = buildSymbolTables(program, preludeProgram); - validateDefinitions(program, tables, errors, warnings, dslText); - validateFacts(program, tables, errors, warnings, dslText); - validateSources(program, tables, errors, warnings, dslText); - validateMeasures(program, tables, errors, warnings, dslText); - validateEvidence(program, tables, errors, warnings, dslText); - - return { - success: errors.length === 0, - program, - errors: errors.map(formatValidationError), - warnings: warnings.map(formatValidationError), - errorDetails: errors, - warningDetails: warnings - }; -} - -function buildSymbolTables(program, preludeProgram) { - const definitions = new Map(); - const facts = new Map(); - const evidence = new Map(); - const measures = new Map(); - const sources = new Map(); - const builtins = { - definitions: new Set(), - facts: new Set(), - evidence: new Set(), - measures: new Set(), - sources: new Set() - }; - - for (const def of preludeProgram?.definitions || []) { - definitions.set(def.name, def); - builtins.definitions.add(def.name); - } - for (const fact of preludeProgram?.facts || []) { - facts.set(fact.name, fact); - builtins.facts.add(fact.name); - } - for (const ev of preludeProgram?.evidence || []) { - evidence.set(ev.name, ev); - builtins.evidence.add(ev.name); - } - for (const measure of preludeProgram?.measures || []) { - measures.set(measure.name, measure); - builtins.measures.add(measure.name); - } - for (const source of preludeProgram?.sources || []) { - sources.set(source.name, source); - builtins.sources.add(source.name); - } - - for (const def of program.definitions || []) { - definitions.set(def.name, def); - } - for (const fact of program.facts || []) { - facts.set(fact.name, fact); - } - for (const ev of program.evidence || []) { - evidence.set(ev.name, ev); - } - for (const measure of program.measures || []) { - measures.set(measure.name, measure); - } - for (const source of program.sources || []) { - sources.set(source.name, source); - } - - return { definitions, facts, evidence, measures, sources, builtins }; -} - -function validateDefinitions(program, tables, errors, warnings, source) { - const seen = new Map(); - for (const def of program.definitions || []) { - if (tables.builtins?.definitions?.has(def.name)) { - errors.push(createError({ - message: `Type '${def.name}' is a built-in and cannot be redefined.`, - rule: 'Built-in types are reserved and cannot be overridden.', - fix: `Rename your type or remove the duplicate definition for '${def.name}'.`, - location: findLocation(source, `definition ${def.name}`), - context: formatContext(source, findLocation(source, def.name)) - })); - } - if (seen.has(def.name)) { - errors.push(createError({ - message: `Duplicate type definition '${def.name}'.`, - rule: 'Each type name must be unique within a program.', - fix: 'Rename one of the type definitions to a unique name.', - location: findLocation(source, `definition ${def.name}`), - context: formatContext(source, findLocation(source, def.name)) - })); - } - seen.set(def.name, def); - - for (const field of def.fields || []) { - if (!isTypeKnown(field.fieldType, tables)) { - errors.push(createError({ - message: `Unknown field type '${field.fieldType}' in '${def.name}.${field.name}'.`, - rule: 'Field types must be built-in or declared as a definition.', - fix: `Add a type definition for '${field.fieldType}' or correct the field type.`, - location: findLocation(source, field.fieldType), - context: formatContext(source, findLocation(source, def.name)) - })); - } - } - } -} - -function validateFacts(program, tables, errors, warnings, source) { - for (const fact of program.facts || []) { - if (tables.builtins?.facts?.has(fact.name)) { - errors.push(createError({ - message: `Fact '${fact.name}' is a built-in and cannot be redefined.`, - rule: 'Built-in facts are reserved and cannot be overridden.', - fix: `Rename your fact or remove the duplicate definition for '${fact.name}'.`, - location: findLocation(source, `fact ${fact.name}`), - context: formatContext(source, findLocation(source, fact.name)) - })); - } - const arity = fact.params ? fact.params.length : 0; - if (!fact.params || arity === 0) { - warnings.push(createError({ - message: `Fact '${fact.name}' declares no parameters.`, - rule: 'Facts should declare parameters to capture relation signatures.', - fix: `Add parameters to '${fact.name}', e.g. (${fact.name}(user: User, doc: Document)).`, - location: findLocation(source, `fact ${fact.name}`), - context: formatContext(source, findLocation(source, fact.name)) - })); - } - - const paramNames = new Set(); - for (const param of fact.params || []) { - if (paramNames.has(param.name)) { - errors.push(createError({ - message: `Duplicate parameter '${param.name}' in fact '${fact.name}'.`, - rule: 'Each parameter name must be unique within a fact signature.', - fix: 'Rename the parameter to a unique name.', - location: findLocation(source, param.name), - context: formatContext(source, findLocation(source, fact.name)) - })); - } - paramNames.add(param.name); - - if (!isTypeKnown(param.paramType, tables)) { - errors.push(createError({ - message: `Unknown parameter type '${param.paramType}' in fact '${fact.name}'.`, - rule: 'Parameter types must be built-in or declared as a definition.', - fix: `Add a type definition for '${param.paramType}' or correct the parameter type.`, - location: findLocation(source, param.paramType), - context: formatContext(source, findLocation(source, fact.name)) - })); - } - } - } -} - -function validateSources(program, tables, errors, warnings, source) { - for (const src of program.sources || []) { - if (tables.builtins?.sources?.has(src.name)) { - errors.push(createError({ - message: `Source '${src.name}' is a built-in and cannot be redefined.`, - rule: 'Built-in sources are reserved and cannot be overridden.', - fix: `Rename your source or remove the duplicate definition for '${src.name}'.`, - location: findLocation(source, `source ${src.name}`), - context: formatContext(source, findLocation(source, src.name)) - })); - } - - const returnType = src.provides || null; - if (returnType && !isTypeKnown(returnType, tables)) { - errors.push(createError({ - message: `Unknown return type '${returnType}' for source '${src.name}'.`, - rule: 'Source PROVIDES types must be built-in or declared as a definition.', - fix: `Add a type definition for '${returnType}' or correct the PROVIDES clause.`, - location: findLocation(source, returnType), - context: formatContext(source, findLocation(source, src.name)) - })); - } - - if (src.within && !isValidDuration(src.within)) { - errors.push(createError({ - message: `Invalid duration '${src.within?.value || ''}' in within constraint for source '${src.name}'.`, - rule: 'Within constraints must be duration literals (e.g. 10m, 5h, 1d).', - fix: `Use a duration literal like '10m' in the within constraint for '${src.name}'.`, - location: findLocation(source, 'within'), - context: formatContext(source, findLocation(source, src.name)) - })); - } - - const paramNames = new Set(); - for (const param of src.params || []) { - if (paramNames.has(param.name)) { - errors.push(createError({ - message: `Duplicate parameter '${param.name}' in source '${src.name}'.`, - rule: 'Each parameter name must be unique within a source signature.', - fix: 'Rename the parameter to a unique name.', - location: findLocation(source, param.name), - context: formatContext(source, findLocation(source, src.name)) - })); - } - paramNames.add(param.name); - - if (!isTypeKnown(param.paramType, tables)) { - errors.push(createError({ - message: `Unknown parameter type '${param.paramType}' in source '${src.name}'.`, - rule: 'Parameter types must be built-in or declared as a definition.', - fix: `Add a type definition for '${param.paramType}' or correct the parameter type.`, - location: findLocation(source, param.paramType), - context: formatContext(source, findLocation(source, src.name)) - })); - } - } - } -} - -function isValidDuration(within) { - if (!within || typeof within.value !== 'string') return false; - return /^\d+(h|d|w|m)$/.test(within.value); -} - -function validateMeasures(program, tables, errors, warnings, source) { - for (const measure of program.measures || []) { - if (tables.builtins?.measures?.has(measure.name)) { - errors.push(createError({ - message: `Measure '${measure.name}' is a built-in and cannot be redefined.`, - rule: 'Built-in measures are reserved and cannot be overridden.', - fix: `Rename your measure or remove the duplicate definition for '${measure.name}'.`, - location: findLocation(source, `measure ${measure.name}`), - context: formatContext(source, findLocation(source, measure.name)) - })); - } - const returnType = measure.provides || DEFAULT_MEASURE_RETURN; - if (returnType !== DEFAULT_MEASURE_RETURN && !isTypeKnown(returnType, tables)) { - errors.push(createError({ - message: `Unknown return type '${returnType}' for measure '${measure.name}'.`, - rule: 'Measure return types must be built-in or declared as a definition.', - fix: `Add a type definition for '${returnType}' or correct the PROVIDES clause.`, - location: findLocation(source, returnType), - context: formatContext(source, findLocation(source, measure.name)) - })); - } - - const paramScope = buildParamScope(measure.params, tables, errors, source, `measure ${measure.name}`); - if (measure.body) { - validateMeasureBody(measure.body, paramScope, tables, errors, warnings, source, measure); - } - } -} - -function validateEvidence(program, tables, errors, warnings, source) { - for (const ev of program.evidence || []) { - if (tables.builtins?.evidence?.has(ev.name)) { - errors.push(createError({ - message: `Evidence '${ev.name}' is a built-in and cannot be redefined.`, - rule: 'Built-in evidence names are reserved and cannot be overridden.', - fix: `Rename your evidence or remove the duplicate definition for '${ev.name}'.`, - location: findLocation(source, `evidence ${ev.name}`), - context: formatContext(source, findLocation(source, ev.name)) - })); - } - const returnType = ev.provides || DEFAULT_EVIDENCE_RETURN; - if (returnType !== DEFAULT_EVIDENCE_RETURN && !isTypeKnown(returnType, tables)) { - errors.push(createError({ - message: `Unknown return type '${returnType}' for evidence '${ev.name}'.`, - rule: 'Evidence return types must be built-in or declared as a definition.', - fix: `Add a type definition for '${returnType}' or correct the PROVIDES clause.`, - location: findLocation(source, returnType), - context: formatContext(source, findLocation(source, ev.name)) - })); - } - - const paramScope = buildParamScope(ev.params, tables, errors, source, `evidence ${ev.name}`); - if (ev.body) { - validateEvidenceBody(ev.body, paramScope, tables, errors, warnings, source, ev); - } - } -} - -function validateEvidenceBody(body, scope, tables, errors, warnings, source, parent) { - for (const stmt of body.statements || []) { - switch (stmt.type) { - case 'DefeasibleLogic': - validateBooleanExpression(stmt.condition, scope, tables, errors, warnings, source, parent); - if (stmt.defeater) { - validateBooleanExpression(stmt.defeater, scope, tables, errors, warnings, source, parent); - } - break; - case 'Fusion': - for (const expr of stmt.expressions || []) { - validateBooleanExpression(expr, scope, tables, errors, warnings, source, parent); - } - break; - case 'CollectionProcessing': - validateCollectionProcessing(stmt, scope, tables, errors, warnings, source, parent); - break; - case 'PatternMatch': - validatePatternMatch(stmt, scope, tables, errors, warnings, source, parent); - break; - default: - validateBooleanExpression(stmt, scope, tables, errors, warnings, source, parent); - break; - } - } -} - -function validateMeasureBody(body, scope, tables, errors, warnings, source, measure) { - for (const stmt of body.statements || []) { - if (stmt.type === 'Fusion') { - for (const expr of stmt.expressions || []) { - inferExpressionType(expr, scope, tables, errors, warnings, source, measure); - } - } else if (stmt.type === 'Aggregation') { - for (const expr of stmt.expressions || []) { - inferExpressionType(expr, scope, tables, errors, warnings, source, measure); - } - } else { - inferExpressionType(stmt, scope, tables, errors, warnings, source, measure); - } - } - - if (body.returnStatement && body.returnStatement.expression) { - const returnType = measure.provides || DEFAULT_MEASURE_RETURN; - const inferred = inferExpressionType(body.returnStatement.expression, scope, tables, errors, warnings, source, measure); - if (returnType !== DEFAULT_MEASURE_RETURN && inferred && inferred.type) { - if (!isAssignable(inferred.type, returnType)) { - errors.push(createError({ - message: `Return type mismatch in measure '${measure.name}': expected '${returnType}', got '${inferred.type}'.`, - rule: 'Measure return expressions must match the PROVIDES type.', - fix: 'Update the return expression or adjust the PROVIDES type.', - location: findLocation(source, measure.name), - context: formatContext(source, findLocation(source, measure.name)) - })); - } - } - } -} - -function validateCollectionProcessing(stmt, scope, tables, errors, warnings, source, parent) { - const measureType = inferExpressionType(stmt.measure, scope, tables, errors, warnings, source, parent); - if (measureType && measureType.type && !measureType.isArray) { - errors.push(createError({ - message: 'Collection processing requires a measure that returns an array.', - rule: 'Use |var| only with measures that return array types.', - fix: 'Change the measure to return an array (Type[]) or use a direct predicate instead.', - location: findLocation(source, stmt.variable), - context: formatContext(source, findLocation(source, stmt.variable)) - })); - } - - const nextScope = new Map(scope); - if (measureType && measureType.elementType) { - nextScope.set(stmt.variable, { type: measureType.elementType, isArray: false }); - } else { - nextScope.set(stmt.variable, { type: 'any', isArray: false }); - } - validateEvidenceBody(stmt.body, nextScope, tables, errors, warnings, source, parent); -} - -function validatePatternMatch(stmt, scope, tables, errors, warnings, source, parent) { - const predicate = stmt.predicate; - if (!predicate || !predicate.name) return; - - const signature = resolvePredicateSignature(predicate.name, tables); - if (!signature) { - errors.push(createError({ - message: `Unknown predicate '${predicate.name}'.`, - rule: 'Predicates must reference defined facts, evidence, or measures.', - fix: `Define '${predicate.name}' as a fact/evidence/measure or correct the name.`, - location: findLocation(source, predicate.name), - context: formatContext(source, findLocation(source, predicate.name)) - })); - return; - } - - const nextScope = new Map(scope); - for (let i = 0; i < (predicate.args || []).length; i++) { - const arg = predicate.args[i]; - const expected = signature.params[i]; - if (!expected) continue; - if (arg && arg.type === 'Wildcard') { - nextScope.set(arg.name, { type: expected.type, isArray: expected.isArray }); - continue; - } - const inferred = inferExpressionType(arg, scope, tables, errors, warnings, source, parent); - if (inferred && inferred.type && expected.type) { - if (!isAssignable(inferred.type, expected.type, inferred.isArray, expected.isArray)) { - errors.push(createError({ - message: `Type mismatch for '${predicate.name}' argument ${i + 1}: expected '${formatType(expected)}', got '${formatType(inferred)}'.`, - rule: 'Predicate arguments must match declared parameter types.', - fix: 'Update the argument or adjust the predicate signature.', - location: findLocation(source, predicate.name), - context: formatContext(source, findLocation(source, predicate.name)) - })); - } - } - } - - if (stmt.binding) { - nextScope.set(stmt.binding, { type: 'relation', isArray: false, relation: predicate.name }); - } - - validateEvidenceBody(stmt.body, nextScope, tables, errors, warnings, source, parent); - - if (stmt.withClause) { - validateBooleanExpression(stmt.withClause.condition, nextScope, tables, errors, warnings, source, parent); - } -} - -function validateBooleanExpression(expr, scope, tables, errors, warnings, source, parent) { - const inferred = inferExpressionType(expr, scope, tables, errors, warnings, source, parent); - if (!inferred || !inferred.type) return; - // Challenge / injectable-source predicate calls are proof requirements, - // not value expressions — they are valid evidence-body statements. - if (inferred.type !== 'boolean' && inferred.type !== 'challenge_proof') { - errors.push(createError({ - message: `Expected a boolean expression, got '${inferred.type}'.`, - rule: 'Evidence statements must evaluate to boolean or possibilistic truth values.', - fix: 'Use a predicate, comparison, or logical expression that returns boolean.', - location: expr?.location || findLocation(source, inferred.name || ''), - context: formatContext(source, expr?.location || findLocation(source, inferred.name || '')) - })); - } -} - -function inferExpressionType(expr, scope, tables, errors, warnings, source, parent) { - if (!expr) return null; - - switch (expr.type) { - case 'Literal': - return inferLiteralType(expr); - case 'Variable': - return resolveVariableType(expr, scope, errors, source); - case 'PredicateCall': - return resolvePredicateCallType(expr, scope, tables, errors, warnings, source, parent); - case 'AttributeAccess': - return resolveAttributeType(expr, scope, tables, errors, warnings, source, parent); - case 'BindingAccess': - return inferExpressionType(expr.expression, scope, tables, errors, warnings, source, parent); - case 'UnaryExpression': - return { type: 'boolean', isArray: false }; - case 'BinaryExpression': - return resolveBinaryExpressionType(expr, scope, tables, errors, warnings, source, parent); - default: - return { type: 'any', isArray: false }; - } -} - -function resolveBinaryExpressionType(expr, scope, tables, errors, warnings, source, parent) { - const left = inferExpressionType(expr.left, scope, tables, errors, warnings, source, parent); - let scopedForRight = scope; - const guard = extractTypeGuard(expr.left, scope, tables, errors, warnings, source, parent); - if (expr.operator === '&&' && guard) { - scopedForRight = new Map(scope); - scopedForRight.set(guard.targetPath, { type: guard.typeName, isArray: false }); - } - const right = inferExpressionType(expr.right, scopedForRight, tables, errors, warnings, source, parent); - const operator = expr.operator; - - if (operator === 'is') { - const typeName = resolveTypeName(expr.right); - if (!typeName || !isTypeKnown(typeName, tables)) { - errors.push(createError({ - message: 'Type guard requires a known type name on the right-hand side.', - rule: 'Use "value is TypeName" with a declared type.', - fix: 'Ensure the right-hand side is a valid type name.', - location: expr.location || findLocation(source, 'is'), - context: formatContext(source, expr.location || findLocation(source, 'is')) - })); - } - return { type: 'boolean', isArray: false }; - } - - if (['+', '-', '*', '/'].includes(operator)) { - if (!isNumberType(left) || !isNumberType(right)) { - errors.push(createError({ - message: `Arithmetic operator '${operator}' requires numeric operands.`, - rule: 'Arithmetic expressions must use numbers.', - fix: 'Cast or convert operands to numbers before applying arithmetic operators.', - location: expr.location || findLocation(source, operator), - context: formatContext(source, expr.location || findLocation(source, operator)) - })); - } - return { type: 'number', isArray: false }; - } - - if (['==', '!=', '>=', '<=', '>', '<', 'within'].includes(operator)) { - if (operator === 'within') { - if (!isTimestampType(left) || !isDurationType(right)) { - errors.push(createError({ - message: 'Temporal comparisons require a timestamp on the left and duration on the right.', - rule: 'Use "within" with timestamp values and duration literals.', - fix: 'Ensure the left expression is a timestamp and the right is a duration (e.g., 1h).', - location: expr.location || findLocation(source, 'within'), - context: formatContext(source, expr.location || findLocation(source, 'within')) - })); - } - } else if (!areComparableTypes(left, right)) { - errors.push(createError({ - message: `Comparison '${operator}' uses incompatible types '${formatType(left)}' and '${formatType(right)}'.`, - rule: 'Comparisons require compatible operand types.', - fix: 'Align the types on both sides of the comparison.', - location: expr.location || findLocation(source, operator), - context: formatContext(source, expr.location || findLocation(source, operator)) - })); - } - return { type: 'boolean', isArray: false }; - } - - if (['&&', '||'].includes(operator)) { - return { type: 'boolean', isArray: false }; - } - - return { type: 'any', isArray: false }; -} - -function resolvePredicateCallType(expr, scope, tables, errors, warnings, source, parent) { - if (expr.name === 'is_type') { - const guard = extractTypeGuard(expr, scope, tables, errors, warnings, source, parent); - if (!guard) { - errors.push(createError({ - message: 'is_type requires a value expression and a known type name.', - rule: 'Type guards must be written as is_type(value, TypeName).', - fix: 'Pass a value expression and a declared type name.', - location: findLocation(source, expr.name), - context: formatContext(source, findLocation(source, expr.name)) - })); - } - return { type: 'boolean', isArray: false }; - } - - if (expr.challenge) { - if (!Array.isArray(expr.args) || expr.args.length === 0) { - errors.push(createError({ - message: `Challenge predicate '${expr.name}' must specify a subject (e.g., !${expr.name}(user)).`, - rule: 'Challenge predicates require an explicit subject bound to the current session or user.', - fix: `Add an argument: !${expr.name}(user) or !${expr.name}(session).`, - location: findLocation(source, expr.name), - context: formatContext(source, findLocation(source, expr.name)) - })); - return { type: 'any', isArray: false }; - } - if (BUILTIN_CHALLENGES.has(expr.name)) { - return { type: 'challenge_proof', isArray: false, challenge: true }; - } - const ev = tables.evidence.get(expr.name); - if (ev && ev.challenge) { - return { type: 'challenge_proof', isArray: false, challenge: true }; - } - if (ev && !ev.challenge) { - errors.push(createError({ - message: `Evidence '${expr.name}' is not declared as a challenge evidence.`, - rule: 'Only challenge evidence can be referenced with a ! prefix.', - fix: `Declare '${expr.name}' as 'evidence !${expr.name}(...)' or remove the ! prefix.`, - location: findLocation(source, expr.name), - context: formatContext(source, findLocation(source, expr.name)) - })); - return { type: 'any', isArray: false }; - } - // Injectable sources and injectable facts are valid challenge-style - // references (witness requirements), even though they are not evidence. - const src = tables.sources.get(expr.name); - if (src) { - return { type: 'challenge_proof', isArray: false, challenge: true }; - } - const injectableFact = tables.facts.get(expr.name); - if (injectableFact && injectableFact.injectable) { - return { type: 'challenge_proof', isArray: false, challenge: true }; - } - errors.push(createError({ - message: `Unknown challenge predicate '${expr.name}'.`, - rule: 'Challenge predicates must be predefined or declared as challenge evidence.', - fix: `Define 'evidence !${expr.name}(...)' or use a predefined challenge predicate.`, - location: findLocation(source, expr.name), - context: formatContext(source, findLocation(source, expr.name)) - })); - return { type: 'any', isArray: false }; - } - - const signature = resolvePredicateSignature(expr.name, tables); - if (!signature) { - errors.push(createError({ - message: `Unknown predicate '${expr.name}'.`, - rule: 'Predicates must reference defined facts, evidence, or measures.', - fix: `Define '${expr.name}' as a fact/evidence/measure or correct the name.`, - location: findLocation(source, expr.name), - context: formatContext(source, findLocation(source, expr.name)) - })); - return { type: 'any', isArray: false }; - } - - const expectedCount = signature.params.length; - const actualCount = expr.args ? expr.args.length : 0; - if (expectedCount !== actualCount) { - errors.push(createError({ - message: `Predicate '${expr.name}' expects ${expectedCount} arguments, got ${actualCount}.`, - rule: 'Predicate calls must match the declared parameter count.', - fix: 'Add or remove arguments to match the predicate signature.', - location: findLocation(source, expr.name), - context: formatContext(source, findLocation(source, expr.name)) - })); - } - - for (let i = 0; i < Math.min(expectedCount, actualCount); i++) { - const expected = signature.params[i]; - const arg = expr.args[i]; - if (arg && arg.type === 'Wildcard') { - continue; - } - const inferred = inferExpressionType(arg, scope, tables, errors, warnings, source, parent); - if (inferred && expected) { - if (!isAssignable(inferred.type, expected.type, inferred.isArray, expected.isArray)) { - errors.push(createError({ - message: `Type mismatch for '${expr.name}' argument ${i + 1}: expected '${formatType(expected)}', got '${formatType(inferred)}'.`, - rule: 'Predicate arguments must match declared parameter types.', - fix: 'Update the argument or adjust the predicate signature.', - location: findLocation(source, expr.name), - context: formatContext(source, findLocation(source, expr.name)) - })); - } - } - } - - return signature.returnType; -} - -function resolveAttributeType(expr, scope, tables, errors, warnings, source, parent) { - const override = getScopeOverride(expr.object, scope); - const objectType = override || inferExpressionType(expr.object, scope, tables, errors, warnings, source, parent); - if (!objectType || !objectType.type) { - return { type: 'any', isArray: false }; - } - - if (objectType.challenge) { - const attr = expr.attribute; - if (attr === 'issued_at' || attr === 'issuedAt' || attr === 'expires_at' || attr === 'expiresAt') { - return { type: 'timestamp', isArray: false }; - } - errors.push(createError({ - message: `Unknown challenge proof field '${attr}'.`, - rule: 'Challenge proofs only expose issued_at and expires_at fields.', - fix: `Use ${objectType.challenge ? 'issued_at' : 'expires_at'} on the challenge proof.`, - location: expr.location || findLocation(source, attr), - context: formatContext(source, expr.location || findLocation(source, attr)) - })); - return { type: 'any', isArray: false }; - } - - if (objectType.type === 'relation') { - warnings.push(createError({ - message: `Attribute access '${expr.attribute}' cannot be validated on relation bindings yet.`, - rule: 'Relation attribute schemas are not declared in the current DSL grammar.', - fix: 'Add a relation attribute schema once supported, or validate this in application code.', - location: expr.location || findLocation(source, expr.attribute), - context: formatContext(source, expr.location || findLocation(source, expr.attribute)) - })); - return { type: 'any', isArray: false }; - } - - const def = tables.definitions.get(objectType.type); - if (!def) { - errors.push(createError({ - message: `Cannot access attribute '${expr.attribute}' on unknown type '${objectType.type}'.`, - rule: 'Attribute access requires a typed node definition.', - fix: `Define type '${objectType.type}' with the desired fields.`, - location: expr.location || findLocation(source, expr.attribute), - context: formatContext(source, expr.location || findLocation(source, expr.attribute)) - })); - return { type: 'any', isArray: false }; - } - - const field = (def.fields || []).find(f => f.name === expr.attribute); - if (!field) { - errors.push(createError({ - message: `Unknown field '${expr.attribute}' on type '${def.name}'.`, - rule: 'Attribute access must reference a declared field.', - fix: `Add field '${expr.attribute}' to type '${def.name}' or correct the attribute name.`, - location: expr.location || findLocation(source, expr.attribute), - context: formatContext(source, expr.location || findLocation(source, expr.attribute)) - })); - return { type: 'any', isArray: false }; - } - - return { - type: field.fieldType, - isArray: !!field.isArray - }; -} - -function extractTypeGuard(expr, scope, tables, errors, warnings, source, parent) { - if (expr && expr.type === 'BinaryExpression' && expr.operator === 'is') { - const targetPath = getExpressionPath(expr.left); - const typeName = resolveTypeName(expr.right); - if (targetPath && typeName && isTypeKnown(typeName, tables)) { - return { targetPath, typeName }; - } - return null; - } - const guardExpr = expr && expr.type === 'PredicateCall' ? expr : null; - if (!guardExpr || guardExpr.name !== 'is_type') return null; - const args = guardExpr.args || []; - if (args.length !== 2) return null; - const target = args[0]; - const typeArg = args[1]; - const targetPath = getExpressionPath(target); - if (!targetPath) return null; - const typeName = resolveTypeName(typeArg); - if (!typeName || !isTypeKnown(typeName, tables)) return null; - return { targetPath, typeName }; -} - -function resolveTypeName(expr) { - if (!expr) return null; - if (expr.type === 'TypeName') return expr.name; - if (expr.type === 'Variable') return expr.name; - if (expr.type === 'Literal' && typeof expr.value === 'string') return expr.value; - return null; -} - -function getExpressionPath(expr) { - if (!expr) return null; - if (expr.type === 'Variable') return expr.name; - if (expr.type === 'AttributeAccess') { - const base = getExpressionPath(expr.object); - if (!base || !expr.attribute) return null; - return `${base}.${expr.attribute}`; - } - return null; -} - -function getScopeOverride(expr, scope) { - const path = getExpressionPath(expr); - if (!path) return null; - const entry = scope.get(path); - if (!entry) return null; - return { type: entry.type, isArray: entry.isArray || false }; -} - -function resolveVariableType(expr, scope, errors, source) { - const entry = scope.get(expr.name); - if (!entry) { - if (isChallengePredicateName(expr.name)) { - errors.push(createError({ - message: `Challenge predicate '${expr.name}' must be prefixed with '!'.`, - rule: 'Challenge predicates are only valid as ! in Evidence DSL expressions.', - fix: `Rewrite '${expr.name}' as '!${expr.name}'.`, - location: findLocation(source, expr.name), - context: formatContext(source, findLocation(source, expr.name)) - })); - return { type: 'any', isArray: false, name: expr.name }; - } - errors.push(createError({ - message: `Unknown variable '${expr.name}'.`, - rule: 'Variables must be declared in the current scope or bound by a pattern.', - fix: 'Add the variable to the parameter list or bind it with a wildcard/pattern.', - location: findLocation(source, expr.name), - context: formatContext(source, findLocation(source, expr.name)) - })); - return { type: 'any', isArray: false, name: expr.name }; - } - return { type: entry.type, isArray: entry.isArray || false, name: expr.name }; -} - -function isChallengePredicateName(name) { - return BUILTIN_CHALLENGES.has(name); -} - -function buildParamScope(params, tables, errors, source, contextLabel) { - const scope = new Map(); - for (const param of params || []) { - if (!isTypeKnown(param.paramType, tables)) { - errors.push(createError({ - message: `Unknown parameter type '${param.paramType}' in ${contextLabel}.`, - rule: 'Parameter types must be built-in or declared as a definition.', - fix: `Add a type definition for '${param.paramType}' or correct the parameter type.`, - location: findLocation(source, param.paramType), - context: formatContext(source, findLocation(source, contextLabel)) - })); - } - scope.set(param.name, { type: param.paramType, isArray: !!param.isArray }); - } - return scope; -} - -function resolvePredicateSignature(name, tables) { - if (tables.facts.has(name)) { - const fact = tables.facts.get(name); - return { - params: (fact.params || []).map(param => ({ - type: param.paramType, - isArray: !!param.isArray - })), - returnType: { type: 'boolean', isArray: false } - }; - } - if (tables.evidence.has(name)) { - const ev = tables.evidence.get(name); - return { - params: (ev.params || []).map(param => ({ - type: param.paramType, - isArray: !!param.isArray - })), - returnType: { type: ev.provides || DEFAULT_EVIDENCE_RETURN, isArray: false } - }; - } - if (tables.measures.has(name)) { - const measure = tables.measures.get(name); - const returnType = measure.provides || DEFAULT_MEASURE_RETURN; - return { - params: (measure.params || []).map(param => ({ - type: param.paramType, - isArray: !!param.isArray - })), - returnType: { type: returnType, isArray: false } - }; - } - if (tables.sources.has(name)) { - const source = tables.sources.get(name); - return { - params: (source.params || []).map(param => ({ - type: param.paramType, - isArray: !!param.isArray - })), - returnType: { type: source.provides || 'boolean', isArray: false }, - injectable: !!source.injectable, - within: source.within || null - }; - } - return null; -} - -function inferLiteralType(expr) { - if (typeof expr.value === 'boolean') return { type: 'boolean', isArray: false }; - if (typeof expr.value === 'number') return { type: 'number', isArray: false }; - if (expr.unit) return { type: 'duration', isArray: false }; - if (typeof expr.value === 'string') return { type: 'string', isArray: false }; - return { type: 'any', isArray: false }; -} - -function isTypeKnown(type, tables) { - if (!type) return false; - if (BUILTIN_TYPES.has(type)) return true; - return tables.definitions.has(type); -} - -function isAssignable(actualType, expectedType, actualIsArray = false, expectedIsArray = false) { - if (!expectedType || expectedType === 'any') return true; - if (actualType === 'any') return true; - if (actualIsArray !== expectedIsArray) return false; - return actualType === expectedType; -} - -function areComparableTypes(left, right) { - if (!left || !right) return true; - if (left.type === 'any' || right.type === 'any') return true; - if (left.isArray || right.isArray) return false; - return left.type === right.type; -} - -function isNumberType(entry) { - if (!entry) return true; - return entry.type === 'number' || entry.type === 'any'; -} - -function isTimestampType(entry) { - if (!entry) return true; - return entry.type === 'timestamp' || entry.type === 'any'; -} - -function isDurationType(entry) { - if (!entry) return true; - return entry.type === 'duration' || entry.type === 'any'; -} - -function formatType(entry) { - if (!entry) return 'unknown'; - const base = entry.type || 'unknown'; - return entry.isArray ? `${base}[]` : base; -} - -function createError({ message, rule, fix, location, context, severity = 'error' }) { - return { message, rule, fix, location, context, severity }; -} - -function formatValidationError(error) { - const parts = []; - if (error.location && error.location.start) { - parts.push(`[${error.location.start.line}:${error.location.start.column}]`); - } - parts.push(error.message); - if (error.rule) parts.push(`Rule: ${error.rule}`); - if (error.fix) parts.push(`Fix: ${error.fix}`); - if (error.context) parts.push(`Context: ${error.context}`); - return parts.join(' '); -} - -function formatPegError(error, sourceText, sourceName) { - const expected = (error.expected || []).map(exp => exp.description || exp.text || exp.type || String(exp)); - const found = error.found === null ? 'end of input' : String(error.found); - const location = error.location || null; - const expectedStr = expected.length > 3 ? `${expected.slice(0, 3).join(', ')}, ...` : expected.join(' or '); - - let message = `Syntax error: unexpected ${found}`; - let fix = expectedStr ? `Expected ${expectedStr}.` : 'Check the DSL syntax.'; - let rule = 'Statements must follow the Evidence DSL grammar.'; - - if (expected.includes('"}"') || expected.includes('}')) { - message = 'Missing closing brace.'; - fix = 'Add a closing "}" to end the block.'; - rule = 'Blocks must be closed with "}".'; - } else if (expected.includes('")"') || expected.includes(')')) { - message = 'Missing closing parenthesis.'; - fix = 'Add a closing ")" to end the parameter list.'; - rule = 'Parameter lists must be closed with ")".'; - } else if (expected.includes('":"') || expected.includes(':')) { - message = 'Missing colon after identifier.'; - fix = 'Add ":" between a name and its type.'; - rule = 'Types must be declared using name: Type syntax.'; - } - - return createError({ - message, - rule, - fix, - location, - context: formatContext(sourceText, location), - severity: 'error', - expected: expectedStr, - found, - source: sourceName - }); -} - -function parsePrelude(options = {}) { - if (options.includePrelude === false) return null; - try { - return parse(DSL_PRELUDE); - } catch (error) { - return null; - } -} - -function formatContext(sourceText, location) { - if (!sourceText) return null; - if (!location || !location.start) return null; - const lines = sourceText.split('\n'); - const line = lines[location.start.line - 1]; - if (!line) return null; - const pointer = ' '.repeat(Math.max(0, location.start.column - 1)) + '^'; - return `${line.trimEnd()}\n${pointer}`; -} - -function findLocation(sourceText, needle) { - if (!sourceText || !needle) return null; - const lines = sourceText.split('\n'); - for (let i = 0; i < lines.length; i++) { - const col = lines[i].indexOf(needle); - if (col !== -1) { - return { - start: { line: i + 1, column: col + 1 }, - end: { line: i + 1, column: col + needle.length } - }; - } - } - return null; -} diff --git a/src/utils/ip-utils-fast.js b/src/utils/ip-utils-fast.js deleted file mode 100644 index 485764c..0000000 --- a/src/utils/ip-utils-fast.js +++ /dev/null @@ -1,165 +0,0 @@ -/** - * Optimized IP Address Utilities - * - * High-performance versions for hot paths - */ - -// CIDR cache for repeated lookups -const cidrCache = new Map(); -const CIDR_CACHE_SIZE = 1000; - -/** - * Fast IPv4 check - less strict but much faster - * Only validates format, not strict numeric ranges - */ -export function isIPv4Fast(ip) { - if (typeof ip !== 'string') return false; - - // Quick length check (min: 7 for "0.0.0.0", max: 15 for "255.255.255.255") - if (ip.length < 7 || ip.length > 15) return false; - - let dots = 0; - for (let i = 0; i < ip.length; i++) { - const c = ip.charCodeAt(i); - if (c === 46) { // '.' - dots++; - } else if (c < 48 || c > 57) { // not 0-9 - return false; - } - } - return dots === 3; -} - -/** - * Ultra-fast IP to integer conversion - * Direct character parsing, no string splitting - */ -export function ipToIntFast(ip) { - let result = 0; - let octet = 0; - let shift = 24; - - for (let i = 0; i < ip.length; i++) { - const c = ip.charCodeAt(i); - if (c === 46) { // '.' - result |= (octet << shift); - octet = 0; - shift -= 8; - } else { - octet = octet * 10 + (c - 48); - } - } - - return (result | octet) >>> 0; -} - -/** - * Fast CIDR parsing with caching - */ -export function parseCidrCached(cidr) { - // Check cache first - let cached = cidrCache.get(cidr); - if (cached) return cached; - - // Parse and cache - const slashIdx = cidr.indexOf('/'); - if (slashIdx === -1) return null; - - const ip = cidr.slice(0, slashIdx); - const prefix = parseInt(cidr.slice(slashIdx + 1), 10); - const mask = -1 << (32 - prefix); - - cached = { - network: ipToIntFast(ip), - mask, - prefix - }; - - // Simple LRU - clear if too big - if (cidrCache.size >= CIDR_CACHE_SIZE) { - cidrCache.clear(); - } - cidrCache.set(cidr, cached); - - return cached; -} - -/** - * Ultra-fast IP in CIDR check - * Uses caching and optimized parsing - */ -export function isIpInCidrFast(ip, cidr) { - const cached = parseCidrCached(cidr); - if (!cached) return false; - - const ipInt = ipToIntFast(ip); - return (ipInt & cached.mask) === (cached.network & cached.mask); -} - -/** - * Fast private IP check using bit manipulation - */ -export function isPrivateIpFast(ip) { - const ipInt = ipToIntFast(ip); - - // 10.0.0.0/8: 0x0A000000 to 0x0AFFFFFF - if ((ipInt >>> 24) === 10) return true; - - // 172.16.0.0/12: 0xAC100000 to 0xAC1FFFFF - const high16 = ipInt >>> 16; - if (high16 >= 0xAC10 && high16 <= 0xAC1F) return true; - - // 192.168.0.0/16: 0xC0A80000 to 0xC0A8FFFF - if (high16 === 0xC0A8) return true; - - // 127.0.0.0/8: 0x7F000000 to 0x7FFFFFFF - if ((ipInt >>> 24) === 127) return true; - - // 169.254.0.0/16: 0xA9FE0000 to 0xA9FEFFFF - if (high16 === 0xA9FE) return true; - - return false; -} - -/** - * Optimized built-in function evaluator - * Direct dispatch without object lookups - */ -export function evaluateBuiltInFast(name, args) { - switch (name) { - case 'ip_in_cidr': - return isIpInCidrFast(args[0], args[1]); - case 'ip_is_private': - return isPrivateIpFast(args[0]); - case 'ip_is_loopback': - return (ipToIntFast(args[0]) >>> 24) === 127; - case 'ip_version': - return isIPv4Fast(args[0]) ? 4 : (args[0].includes(':') ? 6 : null); - case 'ip_equals': - return args[0] === args[1]; - case 'contains': - return String(args[0]).includes(String(args[1])); - case 'starts_with': - return String(args[0]).startsWith(String(args[1])); - case 'ends_with': - return String(args[0]).endsWith(String(args[1])); - case 'equals': - return args[0] === args[1]; - case 'greater_than': - return args[0] > args[1]; - case 'less_than': - return args[0] < args[1]; - case 'in_range': - return args[0] >= args[1] && args[0] <= args[2]; - case 'hour_of_day': - return new Date(args[0]).getHours(); - case 'day_of_week': - return new Date(args[0]).getDay(); - default: - throw new Error(`Unknown: ${name}`); - } -} - -// Re-export original functions for compatibility -export { isIPv4, isIPv6, isLoopbackIp, getIpVersion, normalizeIp } from './ip-utils.js'; -export { isIpInCidr, isPrivateIp } from './ip-utils.js'; diff --git a/src/utils/ip-utils.js b/src/utils/ip-utils.js deleted file mode 100644 index c9ebb0b..0000000 --- a/src/utils/ip-utils.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * IP Address Utilities - */ - -import { createRequire } from 'node:module'; - -/** - * Check if string is IPv4 - */ -export function isIPv4(ip) { - if (typeof ip !== 'string') return false; - const parts = ip.split('.'); - if (parts.length !== 4) return false; - - return parts.every(part => { - const num = parseInt(part, 10); - return !isNaN(num) && num >= 0 && num <= 255 && part === String(num); - }); -} - -/** - * Check if string is IPv6 - */ -export function isIPv6(ip) { - if (typeof ip !== 'string') return false; - // Simple check - contains colons and valid hex - return ip.includes(':') && /^[0-9a-fA-F:]+$/.test(ip); -} - -/** - * Check if IP is in private range (RFC 1918) - */ -export function isPrivateIp(ip) { - if (!isIPv4(ip)) return false; - - const parts = ip.split('.').map(Number); - const [a, b, c, d] = parts; - - // 10.0.0.0/8 - if (a === 10) return true; - - // 172.16.0.0/12 - if (a === 172 && b >= 16 && b <= 31) return true; - - // 192.168.0.0/16 - if (a === 192 && b === 168) return true; - - // 127.0.0.0/8 (loopback) - if (a === 127) return true; - - // 169.254.0.0/16 (link-local) - if (a === 169 && b === 254) return true; - - return false; -} - -/** - * Check if IP is loopback - */ -export function isLoopbackIp(ip) { - if (!isIPv4(ip)) return false; - return ip.startsWith('127.'); -} - -/** - * Convert IP to integer for range comparison - */ -export function ipToInt(ip) { - return ip.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet, 10), 0) >>> 0; -} - -/** - * Parse CIDR notation - */ -export function parseCidr(cidr) { - const [ip, prefix] = cidr.split('/'); - const mask = -1 << (32 - parseInt(prefix, 10)); - return { ip: ipToInt(ip), mask }; -} - -/** - * Check if IP is in CIDR range - */ -export function isIpInCidr(ip, cidr) { - if (!isIPv4(ip)) return false; - - try { - const ipInt = ipToInt(ip); - const { ip: networkInt, mask } = parseCidr(cidr); - - return (ipInt & mask) === (networkInt & mask); - } catch (err) { - return false; - } -} - -/** - * Check if two IPs are equal - */ -export function ipEquals(ip1, ip2) { - return ip1 === ip2; -} - -/** - * Get IP version (4 or 6) - */ -export function getIpVersion(ip) { - if (isIPv4(ip)) return 4; - if (isIPv6(ip)) return 6; - return null; -} - -/** - * Normalize IP (remove leading zeros, etc.) - */ -export function normalizeIp(ip) { - if (!isIPv4(ip)) return ip; - - return ip - .split('.') - .map(part => parseInt(part, 10).toString()) - .join('.'); -} diff --git a/tests/ast/DSLCompiler.test.js b/tests/ast/DSLCompiler.test.js deleted file mode 100644 index 0f8d50d..0000000 --- a/tests/ast/DSLCompiler.test.js +++ /dev/null @@ -1,265 +0,0 @@ -import { describe, test } from 'node:test'; -import assert from 'node:assert/strict'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; -import { parse } from '../../src/ast/parser/GeneratedParser.js'; -import { RuleGenerator } from '../../src/ast/generator/RuleGenerator.js'; - -function createMockArbiter() { - const relationConfigs = new Map(); - return { - relationConfigs, - setRelationConfig(relation, config) { - relationConfigs.set(relation, config); - } - }; -} - -describe('DSL Compiler', () => { - const arbiter = createMockArbiter(); - const compiler = new DSLCompiler(arbiter); - - test('Basic parsing', () => { - const dsl = ` - definition Employee { - role: string - isActive: boolean - } - - fact hasRole(user: Employee, role: string) - - evidence canRead(user: Employee, doc: Account) { - hasRole(user, 'admin') - } - `; - - const result = compiler.compile(dsl, 'test-basic'); - assert.ok(result.success, 'Basic parsing should succeed'); - assert.ok(result.program !== null, 'Program should be created'); - assert.ok(result.generatedRules.size > 0, 'Rules should be generated'); - }); - - test('Basic compilation', () => { - const dsl = ` - definition Employee { - role: string - isActive: boolean - } - - fact hasRole(user: Employee, role: string) CACHE eager - - evidence canRead(user: Employee, doc: Account) { - hasRole(user, 'admin') - } - `; - - const result = compiler.compile(dsl, 'test-compilation'); - assert.ok(result.success, 'Basic compilation should succeed'); - assert.ok(result.generatedRules.has('canRead'), 'canRead rule should be generated'); - - const canReadConfig = result.generatedRules.get('canRead'); - assert.ok(canReadConfig.type === 'direct', 'canRead should be direct rule'); - assert.ok(canReadConfig.relation === 'hasRole', 'canRead should use hasRole relation'); - }); - - test('Complex DSL compilation', () => { - const dsl = ` - definition Employee { - role: string - isActive: boolean - clearance: string BEHAVES { - blurring adaptive confidence_95 - } CACHE eager - } - - fact hasRole(user: Employee, role: string) CACHE eager - fact isMember(user: Employee, group: Device) transitive CACHE lazy - fact owns(user: Employee, doc: Account) CACHE eager - - evidence canRead(user: Employee, doc: Account) { - owns(user, doc) - hasRole(user, 'admin') - } - - evidence canAccessCritical(user: Employee, resource: AuthSession) { - fusion min { - hasRole(user, 'admin'), - hasRole(user, 'superadmin') - } - - fusion max { - hasRole(user, 'admin'), - hasRole(user, 'secret') - } - } - `; - - const result = compiler.compile(dsl, 'test-complex'); - assert.ok(result.success, 'Complex DSL compilation should succeed'); - assert.ok(result.generatedRules.has('canRead'), 'canRead rule should be generated'); - assert.ok(result.generatedRules.has('canAccessCritical'), 'canAccessCritical rule should be generated'); - - const canReadConfig = result.generatedRules.get('canRead'); - assert.ok(canReadConfig.type === 'logical', 'canRead should be logical rule'); - }); - - test('Error handling', () => { - const invalidDSL = ` - definition Employee { - role: string - // Missing closing brace - - fact hasRole(user: Employee, role: string) - // Missing semicolon - - evidence canRead(user: Employee, doc: Account) { - // Invalid syntax - invalid syntax here - } - `; - - const result = compiler.compile(invalidDSL, 'test-error'); - assert.ok(!result.success, 'Invalid DSL should fail'); - assert.ok(result.errors.length > 0, 'Should have error messages'); - }); - - test('Program management', () => { - const dsl1 = ` - definition Employee { - role: string - isActive: boolean - } - - fact hasRole(user: Employee, role: string) - evidence canRead(user: Employee, doc: Account) { - hasRole(user, 'admin') - } - `; - - const dsl2 = ` - definition Employee { - role: string - isActive: boolean - } - - fact hasBalance(user: Employee, amount: number) - evidence canWithdraw(user: Employee, amount: number) { - hasBalance(user, amount) - } - `; - - const result1 = compiler.compile(dsl1, 'test-auth'); - assert.ok(result1.success, 'First program should compile'); - - const programs = { 'auth': dsl1, 'finance': dsl2 }; - const result2 = compiler.compileMultiple(programs); - assert.ok(result2.success, 'Multiple programs should compile'); - - const authProgram = compiler.getCompiledProgram('test-auth'); - assert.ok(authProgram !== null, 'Should retrieve compiled program'); - - const removed = compiler.removeCompiledProgram('test-auth'); - assert.ok(removed, 'Should remove program'); - - compiler.clearCompiledPrograms(); - const allPrograms = compiler.getAllCompiledPrograms(); - assert.ok(allPrograms.size === 0, 'Should clear all programs'); - }); - - test('Validation', () => { - const validDSL = ` - definition Employee { - role: string - isActive: boolean - } - - fact hasRole(user: Employee, role: string) - - evidence canRead(user: Employee, doc: Account) { - hasRole(user, 'admin') - } - `; - - const invalidDSL = ` - definition Employee { - role: string - // Missing closing brace - - fact hasRole(user: Employee, role: string) - // Missing semicolon - `; - - const validResult = compiler.validate(validDSL); - assert.ok(validResult.success, 'Valid DSL should pass validation'); - - const invalidResult = compiler.validate(invalidDSL); - assert.ok(!invalidResult.success, 'Invalid DSL should fail validation'); - assert.ok(invalidResult.errors.length > 0, 'Should have validation errors'); - }); - - test('Rule generation', () => { - const dsl = ` - definition Employee { - role: string - isActive: boolean - } - - fact hasRole(user: Employee, role: string) CACHE eager - fact isMember(user: Employee, group: Device) transitive CACHE lazy - - evidence canRead(user: Employee, doc: Account) { - hasRole(user, 'admin') - } - - evidence canAccess(user: Employee, doc: Account) { - hasRole(user, 'reader') - } - `; - - const result = compiler.compile(dsl, 'test-rules'); - assert.ok(result.success, 'Rule generation should succeed'); - - const canReadConfig = result.generatedRules.get('canRead'); - assert.ok(canReadConfig.type === 'direct', 'canRead should be direct rule'); - - const canAccessConfig = result.generatedRules.get('canAccess'); - assert.ok(canAccessConfig.type === 'direct', 'canAccess should be direct rule'); - }); - - test('Multiple programs', () => { - const programs = { - 'auth': ` - definition Employee { - role: string - isActive: boolean - } - - fact hasRole(user: Employee, role: string) - evidence canRead(user: Employee, doc: Account) { - hasRole(user, 'admin') - } - `, - 'finance': ` - definition Employee { - role: string - isActive: boolean - } - - fact hasBalance(user: Employee, amount: number) - evidence canWithdraw(user: Employee, amount: number) { - hasBalance(user, amount) - } - `, - 'invalid': ` - // Invalid syntax - invalid syntax here - ` - }; - - const result = compiler.compileMultiple(programs); - assert.ok(!result.success, 'Should fail due to invalid program'); - assert.ok(result.errors.length > 0, 'Should have errors'); - assert.ok(result.results.auth.success, 'Auth program should succeed'); - assert.ok(result.results.finance.success, 'Finance program should succeed'); - assert.ok(!result.results.invalid.success, 'Invalid program should fail'); - }); -}); diff --git a/tests/ast/DefinitionTests.js b/tests/ast/DefinitionTests.js deleted file mode 100644 index 4113a63..0000000 --- a/tests/ast/DefinitionTests.js +++ /dev/null @@ -1,283 +0,0 @@ -import { describe, test } from 'node:test'; -import assert from 'node:assert/strict'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; - -function createMockArbiter() { - const relationConfigs = new Map(); - return { - relationConfigs, - setRelationConfig(relation, config) { - relationConfigs.set(relation, config); - } - }; -} - -describe('Type Definitions', () => { - const arbiter = createMockArbiter(); - const compiler = new DSLCompiler(arbiter); - - test('Basic definitions', () => { - const testCases = [ - { - input: `definition User { role: string }`, - description: 'Simple definition with one field' - }, - { - input: `definition User { - role: string - isActive: boolean - }`, - description: 'Definition with multiple fields' - }, - { - input: `definition Group { - name: string - description: string - created: timestamp - }`, - description: 'Definition with different field types' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-basic-def-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - assert.ok(result.program.definitions.length > 0, 'Should have definitions'); - }); - }); - - test('Field types', () => { - const testCases = [ - { type: 'string', description: 'String field type' }, - { type: 'number', description: 'Number field type' }, - { type: 'boolean', description: 'Boolean field type' }, - { type: 'timestamp', description: 'Timestamp field type' }, - { type: 'User', description: 'Custom type field' }, - { type: 'Permission', description: 'Another custom type field' } - ]; - - testCases.forEach(({ type, description }) => { - const dsl = `definition Test { field: ${type} }`; - const result = compiler.compile(dsl, `test-field-type-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Array types', () => { - const testCases = [ - { type: 'string[]', description: 'String array' }, - { type: 'number[]', description: 'Number array' }, - { type: 'boolean[]', description: 'Boolean array' }, - { type: 'Permission[]', description: 'Custom type array' }, - { type: 'User[]', description: 'User array' } - ]; - - testCases.forEach(({ type, description }) => { - const dsl = `definition Test { items: ${type} }`; - const result = compiler.compile(dsl, `test-array-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Behaviors', () => { - const testCases = [ - { - input: `definition User { - balance: number BEHAVES { decaying down hourly } - }`, - description: 'Decay behavior - down hourly' - }, - { - input: `definition User { - reputation: number BEHAVES { decaying up daily } - }`, - description: 'Decay behavior - up daily' - }, - { - input: `definition User { - score: number BEHAVES { decaying neutral weekly } - }`, - description: 'Decay behavior - neutral weekly' - }, - { - input: `definition User { - stability: number BEHAVES { decaying stable monthly } - }`, - description: 'Decay behavior - stable monthly' - }, - { - input: `definition User { - confidence: number BEHAVES { blurring fixed } - }`, - description: 'Blur behavior - fixed' - }, - { - input: `definition User { - accuracy: number BEHAVES { blurring adaptive } - }`, - description: 'Blur behavior - adaptive' - }, - { - input: `definition User { - precision: number BEHAVES { blurring confidence confidence_90 } - }`, - description: 'Blur behavior - confidence with level' - }, - { - input: `definition User { - session: string BEHAVES { ttl 1h } - }`, - description: 'TTL behavior - hours' - }, - { - input: `definition User { - token: string BEHAVES { ttl 24h } - }`, - description: 'TTL behavior - 24 hours' - }, - { - input: `definition User { - cache: string BEHAVES { ttl 7d } - }`, - description: 'TTL behavior - days' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-behavior-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Caching', () => { - const testCases = [ - { - input: `definition User { - role: string CACHE eager - }`, - description: 'Eager caching' - }, - { - input: `definition User { - score: number CACHE lazy - }`, - description: 'Lazy caching' - }, - { - input: `definition User { - balance: number BEHAVES { decaying down hourly } CACHE eager - }`, - description: 'Behavior with eager caching' - }, - { - input: `definition User { - reputation: number BEHAVES { blurring adaptive } CACHE lazy - }`, - description: 'Behavior with lazy caching' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-cache-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Complex definitions', () => { - const testCases = [ - { - input: `definition User { - role: string - isActive: boolean - lastActive: timestamp BEHAVES { - decaying down hourly - } CACHE lazy - isSuspended: boolean - balance: number BEHAVES { - decaying down hourly - } CACHE eager - score: number BEHAVES { - blurring adaptive confidence_95 - } CACHE lazy - session: string BEHAVES { - ttl 24h - } CACHE eager - }`, - description: 'Complex definition with multiple behaviors and caching' - }, - { - input: `definition Group { - name: string - permissions: Permission[] - members: User[] - created: timestamp BEHAVES { - decaying stable monthly - } CACHE lazy - isPublic: boolean CACHE eager - }`, - description: 'Definition with arrays and mixed behaviors' - }, - { - input: `definition Document { - level: string - owner: User - tags: string[] - content: string BEHAVES { - blurring fixed - } CACHE lazy - accessCount: number BEHAVES { - decaying up daily - } CACHE eager - expiresAt: timestamp BEHAVES { - ttl 30d - } CACHE eager - }`, - description: 'Definition with all behavior types' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-complex-def-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - assert.ok(result.program.definitions.length > 0, 'Should have definitions'); - }); - }); - - test('Definition error handling', () => { - const testCases = [ - { - input: `definition User { role: string`, - description: 'Missing closing brace should fail' - }, - { - input: `definition User { role: }`, - description: 'Missing field type should fail' - }, - { - input: `definition User { : string }`, - description: 'Missing field name should fail' - }, - { - input: `definition User { role: string BEHAVES { }`, - description: 'Incomplete behavior should fail' - }, - { - input: `definition User { role: string CACHE }`, - description: 'Incomplete cache directive should fail' - }, - { - input: `definition User { role: string BEHAVES { invalid } }`, - description: 'Invalid behavior should fail' - } - ]; - - testCases.forEach(({ input, description }) => { - try { - const result = compiler.compile(input, `test-def-error-${Date.now()}`); - assert.ok(!result.success, `${description} should fail to parse`); - } catch { - // Expected to fail - } - }); - }); -}); diff --git a/tests/ast/EvidenceTests.js b/tests/ast/EvidenceTests.js deleted file mode 100644 index 6f3067a..0000000 --- a/tests/ast/EvidenceTests.js +++ /dev/null @@ -1,374 +0,0 @@ -import { describe, test } from 'node:test'; -import assert from 'node:assert/strict'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; - -function createMockArbiter() { - const relationConfigs = new Map(); - return { - relationConfigs, - setRelationConfig(relation, config) { - relationConfigs.set(relation, config); - } - }; -} - -describe('Evidence Rules', () => { - const arbiter = createMockArbiter(); - const compiler = new DSLCompiler(arbiter); - - test('Basic evidence', () => { - const testCases = [ - { - input: `evidence canRead(user: User, doc: Document) { - hasRole(user, 'admin') - }`, - description: 'Simple evidence with function call' - }, - { - input: `evidence canAccess(user: User, resource: Resource) { - user.isActive - }`, - description: 'Evidence with attribute access' - }, - { - input: `evidence canModify(user: User, doc: Document) { - user.isActive - hasRole(user, 'admin') - }`, - description: 'Evidence with multiple conditions' - }, - { - input: `evidence canDelete(user: User, doc: Document) { - owns(user, doc) - user.isActive - }`, - description: 'Evidence with ownership and status' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-basic-evidence-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - assert.ok(result.program.evidence.length > 0, 'Should have evidence'); - }); - }); - - test('Defeasible logic', () => { - const testCases = [ - { - input: `evidence canAccess(user: User, resource: Resource) { - ALWAYS user.isActive - }`, - description: 'ALWAYS rule - strict requirement' - }, - { - input: `evidence canAccess(user: User, resource: Resource) { - WHEN hasRole(user, 'admin') - }`, - description: 'WHEN rule - defeasible condition' - }, - { - input: `evidence canAccess(user: User, resource: Resource) { - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - }`, - description: 'WHEN/UNLESS rule - defeasible with defeater' - }, - { - input: `evidence canAccess(user: User, resource: Resource) { - REQUIRES hasClearance(user, resource.level) - }`, - description: 'REQUIRES rule - inverse defeater' - }, - { - input: `evidence canAccessCritical(user: User, resource: Resource) { - ALWAYS user.isActive - - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - - REQUIRES hasClearance(user, resource.level) - }`, - description: 'Complex defeasible logic with all rule types' - }, - { - input: `evidence canAccessSensitive(user: User, doc: Document) { - ALWAYS user.isActive - - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - - REQUIRES hasClearance(user, doc.level) - - fusion majority { - user.isTrusted - user.hasRecentActivity - } - }`, - description: 'Defeasible logic with fusion' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-defeasible-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Pattern matching', () => { - const testCases = [ - { - input: `evidence canRead(user: User, doc: Document) { - isMember(user, *group) { - canRead(group, doc) - } - }`, - description: 'Basic pattern matching with wildcard' - }, - { - input: `evidence canRead(user: User, doc: Document) { - isMember(user, *group) { - canRead(group, doc) - } limit 5 - }`, - description: 'Pattern matching with limit' - }, - { - input: `evidence canRead(user: User, doc: Document) { - similar(doc, *similar) |similarity| { - canRead(user, similar) - } with similarity > 0.7 - }`, - description: 'Pattern matching with binding and condition' - }, - { - input: `evidence canRead(user: User, doc: Document) { - similar(doc, *similar) |similarity| { - canRead(user, similar) - } with similarity > 0.7 limit 5 - }`, - description: 'Pattern matching with binding, condition, and limit' - }, - { - input: `evidence canRead(user: User, doc: Document) { - isMember(user, *group) { - isMember(group, *parentGroup) { - canRead(parentGroup, doc) - } limit 2 - } limit 3 - }`, - description: 'Nested pattern matching' - }, - { - input: `evidence canRead(user: User, doc: Document) { - isFriend(user, *friend) { - isMember(friend, *group) { - canRead(group, doc) - } limit 1 - } limit 5 - }`, - description: 'Multi-hop pattern matching' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-pattern-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Fusion', () => { - const testCases = [ - { - input: `evidence canAccess(user: User, resource: Resource) { - fusion min { - hasClearance(user, resource.level) - user.isActive - } - }`, - description: 'Min fusion - all conditions must be true' - }, - { - input: `evidence canAccess(user: User, resource: Resource) { - fusion max { - hasRole(user, 'admin') - hasRole(user, 'superuser') - } - }`, - description: 'Max fusion - any condition can be true' - }, - { - input: `evidence canAccess(user: User, resource: Resource) { - fusion majority { - hasClearance(user, 'secret') - user.isTrusted - user.hasRecentActivity - } - }`, - description: 'Majority fusion - most conditions must be true' - }, - { - input: `evidence canAccessCritical(user: User, resource: Resource) { - fusion min { - hasClearance(user, resource.level) - user.isActive - NOT user.isBlacklisted - } - - fusion max { - hasRole(user, 'admin') - fusion majority { - hasClearance(user, 'secret') - user.isTrusted - user.lastActive within 1hr - } - } - }`, - description: 'Nested fusion with different strategies' - }, - { - input: `evidence canAccess(user: User, resource: Resource) { - fusion average { - user.reputation - user.activityScore - user.verificationLevel - } - }`, - description: 'Average fusion for numeric values' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-fusion-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Complex evidence', () => { - const testCases = [ - { - input: `evidence canRead(user: User, doc: Document) { - owns(user, doc) - - isMember(user, *group) { - canRead(group, doc) - } limit 5 - - parentOf(user, *parent) { - canRead(parent, doc) - } limit 3 - - similar(doc, *similar) |similarity| { - canRead(user, similar) - } with similarity > 0.7 limit 5 - - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - }`, - description: 'Complex evidence with all features' - }, - { - input: `evidence canAccessCritical(user: User, resource: Resource) { - ALWAYS user.isActive - - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - - REQUIRES hasClearance(user, resource.level) - - fusion min { - hasClearance(user, resource.level) - user.isActive - NOT user.isBlacklisted - } - - fusion max { - hasRole(user, 'admin') - fusion majority { - hasClearance(user, 'secret') - user.isTrusted - user.lastActive within 1hr - } - } - }`, - description: 'Critical access with all rule types and fusion' - }, - { - input: `evidence canModify(user: User, doc: Document) { - owns(user, doc) - - isMember(user, *group) { - canModify(group, doc) - } limit 3 - - similar(doc, *similar) |similarity| { - canModify(user, similar) - similar.isEditable - } with similarity > 0.8 limit 2 - - fusion majority { - user.isTrusted - user.hasRecentActivity - doc.isPublic - } - }`, - description: 'Modification access with similarity and fusion' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-complex-evidence-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Evidence error handling', () => { - const testCases = [ - { - input: `evidence canRead(user: User, doc: Document) { - hasRole(user, 'admin' - }`, - description: 'Missing closing parenthesis should fail' - }, - { - input: `evidence canRead(user: User, doc: Document) { - WHEN hasRole(user, 'admin') UNLESS - }`, - description: 'Incomplete UNLESS condition should fail' - }, - { - input: `evidence canRead(user: User, doc: Document) { - fusion min { - hasRole(user, 'admin') - }`, - description: 'Incomplete fusion should fail' - }, - { - input: `evidence canRead(user: User, doc: Document) { - isMember(user, *group) { - canRead(group, doc) - } with - }`, - description: 'Incomplete with clause should fail' - }, - { - input: `evidence canRead(user: User, doc: Document) { - isMember(user, *group) { - canRead(group, doc) - } limit - }`, - description: 'Incomplete limit should fail' - }, - { - input: `evidence canRead(user: User, doc: Document) { - invalid syntax here - }`, - description: 'Invalid syntax should fail' - } - ]; - - testCases.forEach(({ input, description }) => { - try { - const result = compiler.compile(input, `test-evidence-error-${Date.now()}`); - assert.ok(!result.success, `${description} should fail to parse`); - } catch { - // Expected to fail - } - }); - }); -}); diff --git a/tests/ast/ExpressionTests.js b/tests/ast/ExpressionTests.js deleted file mode 100644 index 29a52b3..0000000 --- a/tests/ast/ExpressionTests.js +++ /dev/null @@ -1,233 +0,0 @@ -import { describe, test } from 'node:test'; -import assert from 'node:assert/strict'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; - -function createMockArbiter() { - const relationConfigs = new Map(); - return { - relationConfigs, - setRelationConfig(relation, config) { - relationConfigs.set(relation, config); - } - }; -} - -describe('Expression Parsing', () => { - const arbiter = createMockArbiter(); - const compiler = new DSLCompiler(arbiter); - - test('Arithmetic operator precedence', () => { - const testCases = [ - { - input: '1 + 2 * 3', - expected: 'Should evaluate as 1 + (2 * 3) = 7', - description: 'Multiplication before addition' - }, - { - input: '10 - 3 * 2', - expected: 'Should evaluate as 10 - (3 * 2) = 4', - description: 'Multiplication before subtraction' - }, - { - input: '8 / 2 * 4', - expected: 'Should evaluate as (8 / 2) * 4 = 16', - description: 'Left-associative division and multiplication' - }, - { - input: '2 + 3 * 4 - 5', - expected: 'Should evaluate as 2 + (3 * 4) - 5 = 9', - description: 'Mixed arithmetic with correct precedence' - }, - { - input: '(1 + 2) * 3', - expected: 'Should evaluate as (1 + 2) * 3 = 9', - description: 'Parentheses override precedence' - } - ]; - - testCases.forEach(({ input, expected, description }) => { - const dsl = `evidence test() { ${input} }`; - const result = compiler.compile(dsl, `test-arithmetic-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Logical operator precedence', () => { - const testCases = [ - { - input: 'true && false || true', - expected: 'Should evaluate as (true && false) || true = true', - description: 'AND before OR' - }, - { - input: 'false || true && false', - expected: 'Should evaluate as false || (true && false) = false', - description: 'AND before OR (alternative)' - }, - { - input: 'NOT true && false', - expected: 'Should evaluate as (NOT true) && false = false', - description: 'NOT before AND' - }, - { - input: 'true && NOT false', - expected: 'Should evaluate as true && (NOT false) = true', - description: 'NOT before AND (alternative)' - }, - { - input: '(true || false) && true', - expected: 'Should evaluate as (true || false) && true = true', - description: 'Parentheses override logical precedence' - } - ]; - - testCases.forEach(({ input, expected, description }) => { - const dsl = `evidence test() { ${input} }`; - const result = compiler.compile(dsl, `test-logical-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Comparison operators', () => { - const testCases = [ - { input: '1 == 1', description: 'Equality comparison' }, - { input: '1 != 2', description: 'Inequality comparison' }, - { input: '5 > 3', description: 'Greater than' }, - { input: '3 < 5', description: 'Less than' }, - { input: '4 >= 4', description: 'Greater than or equal' }, - { input: '4 <= 4', description: 'Less than or equal' }, - { input: '1 == 1 && 2 > 1', description: 'Comparison with logical operators' }, - { input: '1 + 2 == 3', description: 'Arithmetic in comparison' } - ]; - - testCases.forEach(({ input, description }) => { - const dsl = `evidence test() { ${input} }`; - const result = compiler.compile(dsl, `test-comparison-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Temporal expressions', () => { - const testCases = [ - { input: 'user.lastActive within 1h', description: 'Temporal within expression' }, - { input: 'user.lastLogin within 24h', description: 'Temporal within with hours' }, - { input: 'user.createdAt within 7d', description: 'Temporal within with days' }, - { input: 'user.lastActivity within 1h && user.isActive', description: 'Temporal with logical operators' } - ]; - - testCases.forEach(({ input, description }) => { - const dsl = `evidence test() { ${input} }`; - const result = compiler.compile(dsl, `test-temporal-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Unary operators', () => { - const testCases = [ - { input: 'NOT true', description: 'NOT operator' }, - { input: '!false', description: 'Alternative NOT operator' }, - { input: 'NOT (true && false)', description: 'NOT with parenthesized expression' }, - { input: 'NOT user.isSuspended', description: 'NOT with attribute access' } - ]; - - testCases.forEach(({ input, description }) => { - const dsl = `evidence test() { ${input} }`; - const result = compiler.compile(dsl, `test-unary-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Attribute access', () => { - const testCases = [ - { input: 'user.role', description: 'Simple attribute access' }, - { input: 'user.profile.name', description: 'Nested attribute access' }, - { input: 'user.permissions[0]', description: 'Array access' }, - { input: 'user.role.permissions[0]', description: 'Nested attribute with array access' }, - { input: 'user.isActive && user.role == "admin"', description: 'Attribute access in logical expression' } - ]; - - testCases.forEach(({ input, description }) => { - const dsl = `evidence test() { ${input} }`; - const result = compiler.compile(dsl, `test-attribute-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Function calls', () => { - const testCases = [ - { input: 'hasRole(user, "admin")', description: 'Simple function call' }, - { input: 'isMember(user, group)', description: 'Function call with variables' }, - { input: 'hasPermission(user, resource, "read")', description: 'Function call with multiple arguments' }, - { input: 'hasRole(user, "admin") && isActive(user)', description: 'Multiple function calls' }, - { input: 'hasRole(user, user.role)', description: 'Function call with attribute access' } - ]; - - testCases.forEach(({ input, description }) => { - const dsl = `evidence test() { ${input} }`; - const result = compiler.compile(dsl, `test-function-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Complex expressions', () => { - const testCases = [ - { - input: 'user.isActive && (hasRole(user, "admin") || hasPermission(user, resource, "read"))', - description: 'Complex logical expression with function calls' - }, - { - input: 'user.balance > 100 && user.isActive && NOT user.isSuspended', - description: 'Multiple conditions with NOT' - }, - { - input: 'user.lastActive within 1h && (user.role == "admin" || user.hasEmergencyAccess)', - description: 'Temporal with logical conditions' - }, - { - input: 'hasRole(user, "admin") && user.isActive && NOT (user.isSuspended || user.isBlacklisted)', - description: 'Complex negation with multiple conditions' - }, - { - input: 'user.score > 0.8 && user.isTrusted && user.lastActivity within 24h', - description: 'Multiple attribute conditions with temporal' - } - ]; - - testCases.forEach(({ input, description }) => { - const dsl = `evidence test() { ${input} }`; - const result = compiler.compile(dsl, `test-complex-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Expression error handling', () => { - const testCases = [ - { - input: 'user.role ==', - description: 'Incomplete comparison should fail' - }, - { - input: 'user.role &&', - description: 'Incomplete logical expression should fail' - }, - { - input: 'hasRole(user,)', - description: 'Function call with missing argument should fail' - }, - { - input: 'user.role == "admin" &&', - description: 'Incomplete logical expression should fail' - } - ]; - - testCases.forEach(({ input, description }) => { - try { - const dsl = `evidence test() { ${input} }`; - const result = compiler.compile(dsl, `test-error-${Date.now()}`); - assert.ok(!result.success, `${description} should fail to parse`); - } catch { - // Expected to fail - } - }); - }); -}); diff --git a/tests/ast/FactTests.js b/tests/ast/FactTests.js deleted file mode 100644 index 457844e..0000000 --- a/tests/ast/FactTests.js +++ /dev/null @@ -1,232 +0,0 @@ -import { describe, test } from 'node:test'; -import assert from 'node:assert/strict'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; - -function createMockArbiter() { - const relationConfigs = new Map(); - return { - relationConfigs, - setRelationConfig(relation, config) { - relationConfigs.set(relation, config); - } - }; -} - -describe('Fact Declarations', () => { - const arbiter = createMockArbiter(); - const compiler = new DSLCompiler(arbiter); - - test('Basic facts', () => { - const testCases = [ - { - input: `fact hasRole(user: User, role: string)`, - description: 'Simple fact with two parameters' - }, - { - input: `fact isMember(user: User, group: Group)`, - description: 'Fact with custom types' - }, - { - input: `fact owns(user: User, doc: Document)`, - description: 'Fact with multiple custom types' - }, - { - input: `fact isActive(user: User)`, - description: 'Fact with single parameter' - }, - { - input: `fact hasPermission(user: User, resource: Resource, action: string)`, - description: 'Fact with three parameters' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-basic-fact-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - assert.ok(result.program.facts.length > 0, 'Should have facts'); - }); - }); - - test('Fact properties', () => { - const testCases = [ - { - input: `fact isMember(user: User, group: Group) transitive`, - description: 'Transitive fact' - }, - { - input: `fact isFriend(user: User, friend: User) symmetrical`, - description: 'Symmetrical fact' - }, - { - input: `fact isMember(user: User, group: Group) transitive symmetrical`, - description: 'Fact with multiple properties' - }, - { - input: `fact isColleague(user: User, colleague: User) symmetrical`, - description: 'Symmetrical relationship fact' - }, - { - input: `fact isParentOf(parent: User, child: User) transitive`, - description: 'Transitive hierarchical fact' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-fact-property-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Fact caching', () => { - const testCases = [ - { - input: `fact hasRole(user: User, role: string) CACHE eager`, - description: 'Eager cached fact' - }, - { - input: `fact isMember(user: User, group: Group) CACHE lazy`, - description: 'Lazy cached fact' - }, - { - input: `fact isMember(user: User, group: Group) transitive CACHE eager`, - description: 'Transitive fact with eager caching' - }, - { - input: `fact isFriend(user: User, friend: User) symmetrical CACHE lazy`, - description: 'Symmetrical fact with lazy caching' - }, - { - input: `fact hasPermission(user: User, resource: Resource, action: string) CACHE eager`, - description: 'Multi-parameter fact with eager caching' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-fact-cache-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Fact limits', () => { - const testCases = [ - { - input: `fact isMember(user: User, group: Group) limit 10`, - description: 'Fact with simple limit' - }, - { - input: `fact isFriend(user: User, friend: User) limit 100`, - description: 'Fact with higher limit' - }, - { - input: `fact isMember(user: User, group: Group) transitive limit 5`, - description: 'Transitive fact with limit' - }, - { - input: `fact isFriend(user: User, friend: User) symmetrical limit 50`, - description: 'Symmetrical fact with limit' - }, - { - input: `fact isMember(user: User, group: Group) transitive CACHE lazy limit 3`, - description: 'Fact with properties, caching, and limit' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-fact-limit-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Parameter types', () => { - const testCases = [ - { type: 'string', description: 'String parameter' }, - { type: 'number', description: 'Number parameter' }, - { type: 'boolean', description: 'Boolean parameter' }, - { type: 'timestamp', description: 'Timestamp parameter' }, - { type: 'User', description: 'Custom type parameter' }, - { type: 'Group', description: 'Another custom type parameter' }, - { type: 'Permission[]', description: 'Array type parameter' } - ]; - - testCases.forEach(({ type, description }) => { - const dsl = `fact test(param: ${type})`; - const result = compiler.compile(dsl, `test-param-type-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Complex facts', () => { - const testCases = [ - { - input: `fact hasRole(user: User, role: string) CACHE eager - fact isMember(user: User, group: Group) transitive CACHE lazy limit 10 - fact isFriend(user: User, friend: User) symmetrical CACHE eager limit 100 - fact owns(user: User, doc: Document) CACHE eager - fact isSuspended(user: User) CACHE lazy`, - description: 'Multiple facts with different configurations' - }, - { - input: `fact hasPermission(user: User, resource: Resource, action: string) CACHE eager - fact isAdmin(user: User) CACHE eager - fact isOwner(user: User, resource: Resource) CACHE eager - fact hasAccess(user: User, resource: Resource, level: string) CACHE lazy`, - description: 'Permission-related facts' - }, - { - input: `fact isMember(user: User, group: Group) transitive CACHE lazy limit 5 - fact isFriend(user: User, friend: User) symmetrical CACHE eager limit 50 - fact isColleague(user: User, colleague: User) symmetrical CACHE lazy limit 20 - fact isParentOf(parent: User, child: User) transitive CACHE eager limit 3`, - description: 'Relationship facts with various properties' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-complex-facts-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - assert.ok(result.program.facts.length > 0, 'Should have facts'); - }); - }); - - test('Fact error handling', () => { - const testCases = [ - { - input: `fact hasRole(user: User, role: string`, - description: 'Missing closing parenthesis should fail' - }, - { - input: `fact hasRole(user: User, )`, - description: 'Missing parameter name should fail' - }, - { - input: `fact hasRole(user: User, role: )`, - description: 'Missing parameter type should fail' - }, - { - input: `fact hasRole(, role: string)`, - description: 'Missing parameter name should fail' - }, - { - input: `fact hasRole(user: User, role: string) CACHE`, - description: 'Incomplete cache directive should fail' - }, - { - input: `fact hasRole(user: User, role: string) limit`, - description: 'Incomplete limit should fail' - }, - { - input: `fact hasRole(user: User, role: string) invalid`, - description: 'Invalid property should fail' - } - ]; - - testCases.forEach(({ input, description }) => { - try { - const result = compiler.compile(input, `test-fact-error-${Date.now()}`); - assert.ok(!result.success, `${description} should fail to parse`); - } catch { - // Expected to fail - } - }); - }); -}); diff --git a/tests/ast/IntegrationTests.js b/tests/ast/IntegrationTests.js deleted file mode 100644 index 3e89768..0000000 --- a/tests/ast/IntegrationTests.js +++ /dev/null @@ -1,534 +0,0 @@ -import { describe, test } from 'node:test'; -import assert from 'node:assert/strict'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; - -function createMockArbiter() { - const relationConfigs = new Map(); - return { - relationConfigs, - setRelationConfig(relation, config) { - relationConfigs.set(relation, config); - } - }; -} - -describe('Integration Tests', () => { - const arbiter = createMockArbiter(); - const compiler = new DSLCompiler(arbiter); - - test('Complete authorization system', () => { - const completeSystem = ` - // Type definitions with complex behaviors - definition User { - role: string - isActive: boolean - lastActive: timestamp BEHAVES { - decaying down hourly - } CACHE lazy - isSuspended: boolean - balance: number BEHAVES { - decaying down hourly - } CACHE eager - score: number BEHAVES { - blurring adaptive confidence_95 - } CACHE lazy - session: string BEHAVES { - ttl 24h - } CACHE eager - clearance: string BEHAVES { - blurring fixed - } CACHE eager - reputation: number BEHAVES { - decaying up daily - } CACHE lazy - } - - definition Group { - name: string - permissions: Permission[] - level: string - isPublic: boolean CACHE eager - created: timestamp BEHAVES { - decaying stable monthly - } CACHE lazy - } - - definition Document { - level: string - owner: User - tags: string[] - content: string BEHAVES { - blurring fixed - } CACHE lazy - accessCount: number BEHAVES { - decaying up daily - } CACHE eager - expiresAt: timestamp BEHAVES { - ttl 30d - } CACHE eager - isPublic: boolean CACHE eager - } - - definition Resource { - level: string - owner: User - permissions: Permission[] - isPublic: boolean CACHE eager - accessCount: number BEHAVES { - decaying up daily - } CACHE eager - } - - // Facts with various properties and caching - fact hasRole(user: User, role: string) CACHE eager - fact isMember(user: User, group: Group) transitive CACHE lazy limit 10 - fact isFriend(user: User, friend: User) symmetrical CACHE eager limit 100 - fact owns(user: User, doc: Document) CACHE eager - fact isSuspended(user: User) CACHE lazy - fact hasPermission(user: User, resource: Resource, action: string) CACHE eager - fact isAdmin(user: User) CACHE eager - fact isOwner(user: User, resource: Resource) CACHE eager - fact hasAccess(user: User, resource: Resource, level: string) CACHE lazy - fact isColleague(user: User, colleague: User) symmetrical CACHE lazy limit 50 - fact isParentOf(parent: User, child: User) transitive CACHE eager limit 3 - - // Evidence rules with complex logic - evidence canRead(user: User, doc: Document) { - owns(user, doc) - - isMember(user, *group) { - canRead(group, doc) - } limit 5 - - parentOf(user, *parent) { - canRead(parent, doc) - } limit 3 - - similar(doc, *similar) |similarity| { - canRead(user, similar) - } with similarity > 0.7 limit 5 - - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - } - - evidence canWrite(user: User, doc: Document) { - owns(user, doc) - - isMember(user, *group) { - canWrite(group, doc) - } limit 3 - - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - - REQUIRES user.isActive - } - - evidence canDelete(user: User, doc: Document) { - owns(user, doc) - - ALWAYS user.isActive - - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - - REQUIRES user.isActive - } - - evidence canAccessCritical(user: User, resource: Resource) { - fusion min { - hasClearance(user, resource.level) - user.isActive - NOT user.isBlacklisted - } - - fusion max { - hasRole(user, 'admin') - fusion majority { - hasClearance(user, 'secret') - user.isTrusted - user.lastActive within 1hr - } - } - } - - evidence canAccessSensitive(user: User, doc: Document) { - ALWAYS user.isActive - - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - - REQUIRES hasClearance(user, doc.level) - - fusion majority { - user.isTrusted - user.hasRecentActivity - } - } - - // Measures for computed values - measure userRole(user: User) { - user.role - } PROVIDES string - - measure userPermissions(user: User) { - fusion max { - user.role.permissions - user.group.permissions - } - } PROVIDES Permission[] - - measure effectiveClearance(user: User) { - fusion majority { - user.clearance - user.role.clearance - user.group.clearance - } - } PROVIDES string - - measure userTrustScore(user: User) { - fusion average { - user.reputation - user.activityScore - user.verificationLevel - } - } PROVIDES number - - measure userBalance(user: User) { - user.balance - } PROVIDES number - - measure userScore(user: User) { - user.score - } PROVIDES number - `; - - const result = compiler.compile(completeSystem, 'test-complete-system'); - assert.ok(result.success, 'Complete authorization system should compile successfully'); - assert.ok(result.program.definitions.length >= 4, 'Should have multiple definitions'); - assert.ok(result.program.facts.length >= 10, 'Should have multiple facts'); - assert.ok(result.program.evidence.length >= 5, 'Should have multiple evidence rules'); - assert.ok(result.program.measures.length >= 6, 'Should have multiple measures'); - }); - - test('Multi-domain system', () => { - const multiDomain = ` - // Authentication domain - definition User { - role: string - isActive: boolean - lastActive: timestamp BEHAVES { decaying down hourly } CACHE lazy - session: string BEHAVES { ttl 24h } CACHE eager - } - - fact hasRole(user: User, role: string) CACHE eager - fact isActive(user: User) CACHE eager - - evidence canAuthenticate(user: User) { - user.isActive - user.session within 24h - } - - // Authorization domain - definition Resource { - level: string - owner: User - permissions: Permission[] - } - - fact owns(user: User, resource: Resource) CACHE eager - fact hasPermission(user: User, resource: Resource, action: string) CACHE eager - - evidence canAccess(user: User, resource: Resource) { - owns(user, resource) - hasPermission(user, resource, 'read') - } - - // Finance domain - definition Account { - balance: number BEHAVES { decaying down hourly } CACHE eager - owner: User - isActive: boolean CACHE eager - } - - fact hasAccount(user: User, account: Account) CACHE eager - fact hasBalance(user: User, amount: number) CACHE eager - - evidence canWithdraw(user: User, amount: number) { - hasBalance(user, amount) - user.isActive - } - - // Social domain - definition Group { - name: string - members: User[] - isPublic: boolean CACHE eager - } - - fact isMember(user: User, group: Group) transitive CACHE lazy limit 10 - fact isFriend(user: User, friend: User) symmetrical CACHE eager limit 100 - - evidence canAccessGroup(user: User, group: Group) { - isMember(user, group) - group.isPublic - } - `; - - const result = compiler.compile(multiDomain, 'test-multi-domain'); - assert.ok(result.success, 'Multi-domain system should compile successfully'); - assert.ok(result.program.definitions.length >= 4, 'Should have multiple domain definitions'); - assert.ok(result.program.facts.length >= 8, 'Should have multiple domain facts'); - assert.ok(result.program.evidence.length >= 4, 'Should have multiple domain evidence rules'); - }); - - test('Hierarchical access', () => { - const hierarchicalSystem = ` - definition User { - role: string - level: string - isActive: boolean - clearance: string - } - - definition Organization { - name: string - level: string - parent: Organization - } - - fact isMember(user: User, org: Organization) transitive CACHE lazy limit 5 - fact isParentOf(parent: Organization, child: Organization) transitive CACHE eager limit 3 - fact hasRole(user: User, role: string) CACHE eager - fact hasClearance(user: User, level: string) CACHE eager - - evidence canAccessOrg(user: User, org: Organization) { - isMember(user, org) - - isParentOf(org, *parentOrg) { - canAccessOrg(user, parentOrg) - } limit 3 - - WHEN hasRole(user, 'admin') UNLESS user.isSuspended - } - - evidence canAccessResource(user: User, resource: Resource) { - isMember(user, *org) { - canAccessResource(org, resource) - } limit 5 - - parentOf(user, *parent) { - canAccessResource(parent, resource) - } limit 2 - } - `; - - const result = compiler.compile(hierarchicalSystem, 'test-hierarchical'); - assert.ok(result.success, 'Hierarchical access system should compile successfully'); - }); - - test('Similarity-based access', () => { - const similaritySystem = ` - definition User { - profile: string - interests: string[] - isActive: boolean - } - - definition Document { - content: string - tags: string[] - isPublic: boolean - owner: User - } - - fact isFriend(user: User, friend: User) symmetrical CACHE eager limit 100 - fact hasInterest(user: User, interest: string) CACHE lazy - fact hasTag(doc: Document, tag: string) CACHE lazy - - evidence canRead(user: User, doc: Document) { - owns(user, doc) - - similar(doc, *similar) |similarity| { - canRead(user, similar) - similar.isPublic - } with similarity > 0.7 limit 10 - - isFriend(user, *friend) { - canRead(friend, doc) - } limit 5 - - fusion majority { - user.interests - doc.tags - } - } - - evidence canRecommend(user: User, doc: Document) { - similar(user, *similarUser) |similarity| { - canRead(similarUser, doc) - } with similarity > 0.8 limit 20 - - fusion average { - user.profile - doc.content - } - } - `; - - const result = compiler.compile(similaritySystem, 'test-similarity'); - assert.ok(result.success, 'Similarity-based access system should compile successfully'); - }); - - test('Temporal access', () => { - const temporalSystem = ` - definition User { - lastActive: timestamp BEHAVES { decaying down hourly } CACHE lazy - session: string BEHAVES { ttl 24h } CACHE eager - isActive: boolean - } - - definition Event { - startTime: timestamp - endTime: timestamp - isPublic: boolean - } - - fact hasAccess(user: User, event: Event) CACHE lazy - fact isParticipant(user: User, event: Event) CACHE eager - - evidence canAccessEvent(user: User, event: Event) { - user.lastActive within 1h - - isParticipant(user, event) - - WHEN event.isPublic UNLESS user.isSuspended - - fusion min { - user.session within 24h - user.isActive - } - } - - evidence canAccessHistorical(user: User, event: Event) { - user.lastActive within 24h - - fusion majority { - user.isActive - user.session within 24h - event.isPublic - } - } - `; - - const result = compiler.compile(temporalSystem, 'test-temporal'); - assert.ok(result.success, 'Temporal access system should compile successfully'); - }); - - test('Complex behaviors', () => { - const behaviorSystem = ` - definition User { - balance: number BEHAVES { decaying down hourly } CACHE eager - score: number BEHAVES { blurring adaptive confidence_95 } CACHE lazy - session: string BEHAVES { ttl 24h } CACHE eager - reputation: number BEHAVES { decaying up daily } CACHE lazy - clearance: string BEHAVES { blurring fixed } CACHE eager - lastActive: timestamp BEHAVES { decaying down hourly } CACHE lazy - } - - definition Document { - content: string BEHAVES { blurring fixed } CACHE lazy - accessCount: number BEHAVES { decaying up daily } CACHE eager - expiresAt: timestamp BEHAVES { ttl 30d } CACHE eager - isPublic: boolean CACHE eager - } - - fact hasBalance(user: User, amount: number) CACHE eager - fact hasScore(user: User, score: number) CACHE lazy - fact hasReputation(user: User, reputation: number) CACHE lazy - - evidence canAccessDocument(user: User, doc: Document) { - user.balance > 0 - - user.score > 0.5 - - user.reputation > 0.3 - - doc.accessCount < 1000 - - fusion majority { - user.isActive - user.lastActive within 1h - doc.isPublic - } - } - - measure userEffectiveScore(user: User) { - fusion average { - user.score - user.reputation - user.balance - } - } PROVIDES number - - measure documentPopularity(doc: Document) { - doc.accessCount - } PROVIDES number - `; - - const result = compiler.compile(behaviorSystem, 'test-behaviors'); - assert.ok(result.success, 'Complex behaviors system should compile successfully'); - }); - - test('Performance scenarios', () => { - const performanceSystem = ` - definition User { - role: string - isActive: boolean - permissions: Permission[] CACHE eager - } - - definition Resource { - level: string - owner: User - permissions: Permission[] CACHE eager - } - - // High-frequency facts with limits - fact isMember(user: User, group: Group) transitive CACHE lazy limit 5 - fact isFriend(user: User, friend: User) symmetrical CACHE eager limit 50 - fact hasPermission(user: User, resource: Resource, action: string) CACHE eager - fact owns(user: User, resource: Resource) CACHE eager - - // Optimized evidence rules - evidence canAccess(user: User, resource: Resource) { - owns(user, resource) - - isMember(user, *group) { - canAccess(group, resource) - } limit 3 - - WHEN hasPermission(user, resource, 'read') - } - - evidence canModify(user: User, resource: Resource) { - owns(user, resource) - - isMember(user, *group) { - canModify(group, resource) - } limit 2 - - WHEN hasPermission(user, resource, 'write') - } - - // Efficient measures - measure userEffectivePermissions(user: User) { - user.permissions - } PROVIDES Permission[] - - measure resourceAccessLevel(resource: Resource) { - resource.level - } PROVIDES string - `; - - const result = compiler.compile(performanceSystem, 'test-performance'); - assert.ok(result.success, 'Performance scenarios should compile successfully'); - }); -}); diff --git a/tests/ast/MeasureTests.js b/tests/ast/MeasureTests.js deleted file mode 100644 index 9488b6f..0000000 --- a/tests/ast/MeasureTests.js +++ /dev/null @@ -1,306 +0,0 @@ -import { describe, test } from 'node:test'; -import assert from 'node:assert/strict'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; - -function createMockArbiter() { - const relationConfigs = new Map(); - return { - relationConfigs, - setRelationConfig(relation, config) { - relationConfigs.set(relation, config); - } - }; -} - -describe('Measure Definitions', () => { - const arbiter = createMockArbiter(); - const compiler = new DSLCompiler(arbiter); - - test('Basic measures', () => { - const testCases = [ - { - input: `measure userRole(user: User) { - user.role - } PROVIDES string`, - description: 'Simple measure with attribute access' - }, - { - input: `measure userBalance(user: User) { - user.balance - } PROVIDES number`, - description: 'Measure accessing numeric attribute' - }, - { - input: `measure isUserActive(user: User) { - user.isActive - } PROVIDES boolean`, - description: 'Measure accessing boolean attribute' - }, - { - input: `measure userPermissions(user: User) { - user.permissions - } PROVIDES Permission[]`, - description: 'Measure accessing array attribute' - }, - { - input: `measure userScore(user: User) { - user.score - } PROVIDES number`, - description: 'Measure with behavior-inherited attribute' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-basic-measure-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - assert.ok(result.program.measures.length > 0, 'Should have measures'); - }); - }); - - test('Measure return types', () => { - const testCases = [ - { type: 'string', description: 'String return type' }, - { type: 'number', description: 'Number return type' }, - { type: 'boolean', description: 'Boolean return type' }, - { type: 'timestamp', description: 'Timestamp return type' }, - { type: 'Permission[]', description: 'Array return type' }, - { type: 'User', description: 'Custom type return' }, - { type: 'Group[]', description: 'Custom array return type' } - ]; - - testCases.forEach(({ type, description }) => { - const dsl = `measure test() { true } PROVIDES ${type}`; - const result = compiler.compile(dsl, `test-measure-return-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Measure aggregation', () => { - const testCases = [ - { - input: `measure userPermissions(user: User) { - aggregate { - user.role.permissions - user.group.permissions - } USING majority - } PROVIDES Permission[]`, - description: 'Aggregation with majority strategy' - }, - { - input: `measure userClearance(user: User) { - aggregate { - user.clearance - user.role.clearance - user.group.clearance - } USING max - } PROVIDES string`, - description: 'Aggregation with max strategy' - }, - { - input: `measure userScore(user: User) { - aggregate { - user.reputation - user.activityScore - user.verificationLevel - } USING average - } PROVIDES number`, - description: 'Aggregation with average strategy' - }, - { - input: `measure userTrust(user: User) { - aggregate { - user.reputation - user.activityScore - user.verificationLevel - user.socialProof - } USING min - } PROVIDES number`, - description: 'Aggregation with min strategy' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-measure-aggregation-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Measure fusion', () => { - const testCases = [ - { - input: `measure effectiveClearance(user: User) { - fusion max { - user.clearance - user.role.clearance - user.group.clearance - } - } PROVIDES string`, - description: 'Fusion with max strategy' - }, - { - input: `measure userPermissions(user: User) { - fusion min { - user.role.permissions - user.group.permissions - } - } PROVIDES Permission[]`, - description: 'Fusion with min strategy' - }, - { - input: `measure userScore(user: User) { - fusion majority { - user.reputation - user.activityScore - user.verificationLevel - } - } PROVIDES number`, - description: 'Fusion with majority strategy' - }, - { - input: `measure userTrust(user: User) { - fusion average { - user.reputation - user.activityScore - user.verificationLevel - user.socialProof - } - } PROVIDES number`, - description: 'Fusion with average strategy' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-measure-fusion-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Complex measures', () => { - const testCases = [ - { - input: `measure userEffectivePermissions(user: User) { - aggregate { - user.role.permissions - user.group.permissions - user.directPermissions - } USING majority - } PROVIDES Permission[]`, - description: 'Complex aggregation with multiple sources' - }, - { - input: `measure userTrustScore(user: User) { - fusion average { - user.reputation - user.activityScore - user.verificationLevel - user.socialProof - user.peerRatings - } - } PROVIDES number`, - description: 'Complex fusion with multiple metrics' - }, - { - input: `measure userAccessLevel(user: User) { - fusion max { - user.clearance - user.role.clearance - user.group.clearance - user.temporaryClearance - } - } PROVIDES string`, - description: 'Complex clearance calculation' - }, - { - input: `measure userSimilarity(user1: User, user2: User) { - similar(user1, user2) |similarity| { - similarity - } with similarity > 0.5 - } PROVIDES number`, - description: 'Similarity measure with pattern matching' - }, - { - input: `measure userEffectiveRole(user: User) { - fusion majority { - user.role - user.temporaryRole - user.actingRole - } - } PROVIDES string`, - description: 'Role determination with multiple sources' - } - ]; - - testCases.forEach(({ input, description }) => { - const result = compiler.compile(input, `test-complex-measure-${Date.now()}`); - assert.ok(result.success, `${description} should parse successfully`); - }); - }); - - test('Measure error handling', () => { - const testCases = [ - { - input: `measure userRole(user: User) { - user.role - }`, - description: 'Missing PROVIDES clause should fail', - expectSuccess: false - }, - { - input: `measure userRole(user: User) { - user.role - } PROVIDES`, - description: 'Incomplete PROVIDES clause should fail', - expectSuccess: false - }, - { - input: `measure userRole(user: User) { - user.role - } PROVIDES string`, - description: 'Valid measure should succeed', - expectSuccess: true - }, - { - input: `measure userPermissions(user: User) { - aggregate { - user.role.permissions - user.group.permissions - } USING - } PROVIDES Permission[]`, - description: 'Incomplete USING clause should fail', - expectSuccess: false - }, - { - input: `measure userScore(user: User) { - fusion { - user.reputation - user.activityScore - } - } PROVIDES number`, - description: 'Missing fusion strategy should fail', - expectSuccess: false - }, - { - input: `measure userRole(user: User) { - invalid syntax here - } PROVIDES string`, - description: 'Invalid syntax should fail', - expectSuccess: false - } - ]; - - testCases.forEach(({ input, description, expectSuccess }) => { - try { - const result = compiler.compile(input, `test-measure-error-${Date.now()}`); - if (expectSuccess) { - assert.ok(result.success, `${description} should parse successfully`); - } else { - assert.ok(!result.success, `${description} should fail to parse`); - } - } catch { - if (!expectSuccess) { - // Expected to fail - } - } - }); - }); -}); diff --git a/tests/ast/PeggyParser.test.js b/tests/ast/PeggyParser.test.js deleted file mode 100644 index 7a89cdf..0000000 --- a/tests/ast/PeggyParser.test.js +++ /dev/null @@ -1,101 +0,0 @@ -import { describe, test } from 'node:test'; -import assert from 'node:assert/strict'; -import { PeggyDSLParser } from '../../src/ast/parser/PeggyDSLParser.js'; - -describe('Peggy DSL Parser', () => { - const parser = new PeggyDSLParser(); - - test('Basic parsing', () => { - const dsl = ` - definition User { - role: string - isActive: boolean - } - - fact hasRole(user: User, role: string) - - evidence canRead(user: User, doc: Document) { - hasRole(user, 'admin') - } - `; - - const program = parser.parse(dsl); - assert.ok(program !== null, 'Program should be created'); - assert.ok(program.definitions.length === 1, 'Should have 1 definition'); - assert.ok(program.facts.length === 1, 'Should have 1 fact'); - assert.ok(program.evidence.length === 1, 'Should have 1 evidence'); - }); - - test('Complex DSL parsing', () => { - const dsl = ` - definition User { - role: string - isActive: boolean - clearance: string BEHAVES { - blurring adaptive confidence_95 - } CACHE eager - } - - fact hasRole(user: User, role: string) CACHE eager - fact isMember(user: User, group: Group) transitive CACHE lazy - - evidence canRead(user: User, doc: Document) { - hasRole(user, 'admin') - - isMember(user, *group) { - canRead(group, doc) - } limit 5 - - WHEN hasRole(user, 'admin') UNLESS isSuspended(user) - } - `; - - const program = parser.parse(dsl); - assert.ok(program !== null, 'Program should be created'); - assert.ok(program.definitions.length === 1, 'Should have 1 definition'); - assert.ok(program.facts.length === 2, 'Should have 2 facts'); - assert.ok(program.evidence.length === 1, 'Should have 1 evidence'); - }); - - test('Error handling', () => { - const invalidDSL = ` - definition User { - role: string - // Missing closing brace - - fact hasRole(user: User, role: string) - // Missing semicolon - `; - - assert.throws( - () => parser.parse(invalidDSL), - /Parsing failed/, - 'Should have parsing error message' - ); - }); - - test('Validation', () => { - const validDSL = ` - definition User { - role: string - isActive: boolean - } - - fact hasRole(user: User, role: string) - `; - - const invalidDSL = ` - definition User { - role: string - // Missing closing brace - `; - - const validResult = parser.validate(validDSL); - assert.ok(validResult.success, 'Valid DSL should pass validation'); - assert.ok(validResult.program !== null, 'Valid DSL should return program'); - - const invalidResult = parser.validate(invalidDSL); - assert.ok(!invalidResult.success, 'Invalid DSL should fail validation'); - assert.ok(invalidResult.errors.length > 0, 'Should have validation errors'); - }); -}); diff --git a/tests/ast/README.md b/tests/ast/README.md deleted file mode 100644 index d5c4f63..0000000 --- a/tests/ast/README.md +++ /dev/null @@ -1,249 +0,0 @@ -# Evidence DSL Test Suite - -## Overview - -This comprehensive test suite follows a **structural linguistic approach** to validate the Evidence DSL (Domain Specific Language) for authorization policies. The tests are organized incrementally from basic language primitives to complex integration scenarios. - -## Test Structure - -### 1. Structural Linguistic Tests (`StructuralLinguisticTests.js`) -**Level: Comprehensive** -- **Lexical Primitives**: Identifiers, literals, keywords, whitespace -- **Basic Expressions**: Arithmetic, logical, comparison, temporal -- **Type System**: Definitions, fields, behaviors, caching -- **Fact System**: Declarations, properties, caching, limits -- **Evidence System**: Rules, defeasible logic, pattern matching -- **Measure System**: Aggregation, fusion, return types -- **Complex Integration**: Multi-feature combinations - -### 2. Expression Tests (`ExpressionTests.js`) -**Level: Focused** -- Arithmetic operator precedence -- Logical operator precedence -- Comparison operators -- Temporal expressions -- Unary operators -- Attribute access -- Function calls -- Complex expressions -- Error handling - -### 3. Definition Tests (`DefinitionTests.js`) -**Level: Focused** -- Basic type definitions -- Field types (string, number, boolean, timestamp, custom) -- Array types -- Behaviors (decay, blur, TTL) -- Caching (eager, lazy) -- Complex definitions -- Error handling - -### 4. Fact Tests (`FactTests.js`) -**Level: Focused** -- Basic fact declarations -- Fact properties (transitive, symmetrical) -- Fact caching -- Fact limits -- Parameter types -- Complex facts -- Error handling - -### 5. Evidence Tests (`EvidenceTests.js`) -**Level: Focused** -- Basic evidence rules -- Defeasible logic (ALWAYS, WHEN/UNLESS, REQUIRES) -- Pattern matching with wildcards -- Fusion strategies (min, max, majority, average) -- Complex evidence composition -- Error handling - -### 6. Measure Tests (`MeasureTests.js`) -**Level: Focused** -- Basic measure definitions -- Return types -- Aggregation with different strategies -- Fusion with different strategies -- Complex measures -- Error handling - -### 7. Integration Tests (`IntegrationTests.js`) -**Level: Integration** -- Complete authorization systems -- Multi-domain systems -- Hierarchical access patterns -- Similarity-based access -- Temporal access patterns -- Complex behaviors -- Performance scenarios - -## Test Runner (`TestRunner.js`) - -The test runner orchestrates all test suites and provides: -- **Comprehensive Testing**: Run all test suites -- **Selective Testing**: Run specific test suites -- **Level-based Testing**: Run tests by complexity level -- **Detailed Reporting**: Summary and detailed results -- **Coverage Analysis**: Language feature coverage - -## Usage - -### Run All Tests -```javascript -import { runAllTests } from '../../../../../lib/src/ast/tests/tests/TestRunner.js'; - -const results = runAllTests(arbiter); -console.log(`Tests: ${results.passed}/${results.total} passed`); -``` - -### Run Specific Test Suites -```javascript -import { runSpecificTests } from '../../../../../lib/src/ast/tests/tests/TestRunner.js'; - -const results = runSpecificTests(arbiter, [ - 'Expression Tests', - 'Definition Tests' -]); -``` - -### Run Tests by Level -```javascript -import { runTestsByLevel } from '../../../../../lib/src/ast/tests/tests/TestRunner.js'; - -// Run only focused tests -const results = runTestsByLevel(arbiter, 'focused'); - -// Run only integration tests -const results = runTestsByLevel(arbiter, 'integration'); -``` - -## Language Feature Coverage - -### ✅ Lexical Primitives -- Identifiers (simple, with underscores, with numbers) -- Literals (string, number, boolean, duration) -- Keywords (reserved words) -- Whitespace and comments - -### ✅ Expression System -- Arithmetic operators (+, -, *, /) with precedence -- Logical operators (&&, ||, NOT) with precedence -- Comparison operators (==, !=, >, <, >=, <=) -- Temporal expressions (within) -- Unary operators (NOT, !) -- Attribute access (object.attribute) -- Function calls (predicate(args)) - -### ✅ Type System -- Type definitions with fields -- Field types (string, number, boolean, timestamp, custom) -- Array types (Type[]) -- Behaviors (decay, blur, TTL) -- Caching directives (eager, lazy) - -### ✅ Fact System -- Fact declarations with parameters -- Fact properties (transitive, symmetrical) -- Caching directives -- Limits for performance -- Parameter types - -### ✅ Evidence System -- Basic evidence rules -- Defeasible logic (ALWAYS, WHEN/UNLESS, REQUIRES) -- Pattern matching with wildcards (*) -- Binding clauses (|variable|) -- With clauses (with condition) -- Limits for pattern matching -- Fusion strategies (min, max, majority, average) - -### ✅ Measure System -- Measure definitions -- Return type specifications (PROVIDES) -- Aggregation with strategies (USING) -- Fusion with strategies -- Complex value computation - -### ✅ Integration Features -- Multi-domain systems -- Hierarchical access patterns -- Similarity-based access -- Temporal access patterns -- Complex behavior combinations -- Performance optimization scenarios - -## Test Philosophy - -### Structural Linguistic Approach -The tests follow a structural linguistic methodology: - -1. **Phonological Level**: Basic lexical elements (identifiers, literals) -2. **Morphological Level**: Word formation (operators, keywords) -3. **Syntactic Level**: Grammar rules (expressions, statements) -4. **Semantic Level**: Meaning (types, behaviors, logic) -5. **Pragmatic Level**: Usage (integration, real-world scenarios) - -### Incremental Complexity -Tests progress from simple to complex: -- **Level 1**: Lexical primitives -- **Level 2**: Basic expressions -- **Level 3**: Type system -- **Level 4**: Fact system -- **Level 5**: Evidence system -- **Level 6**: Measure system -- **Level 7**: Complex integration - -### Comprehensive Coverage -Each language feature is tested for: -- **Valid cases**: Correct syntax and semantics -- **Invalid cases**: Error handling and recovery -- **Edge cases**: Boundary conditions -- **Integration**: Multi-feature combinations - -## Running Tests - -### Prerequisites -- Node.js environment -- Arbiter instance for testing -- All dependencies installed - -### Basic Usage -```bash -# Run all tests -npm test - -# Run specific test file -node src/ast/tests/StructuralLinguisticTests.js - -# Run with specific arbiter -node -e " -import { runAllTests } from '../../../../../lib/src/ast/tests/src/ast/tests/TestRunner.js'; -const results = runAllTests(arbiter); -console.log(results); -" -``` - -### Test Output -The test runner provides: -- **Progress indicators**: Real-time test execution -- **Detailed results**: Pass/fail status for each test -- **Error reporting**: Specific error messages for failures -- **Performance metrics**: Execution time for each suite -- **Coverage analysis**: Language feature coverage - -## Contributing - -When adding new tests: -1. Follow the structural linguistic approach -2. Test both valid and invalid cases -3. Include error handling tests -4. Document test purpose and expected behavior -5. Maintain incremental complexity -6. Update coverage documentation - -## Test Maintenance - -- **Regular Updates**: Keep tests current with language changes -- **Performance Monitoring**: Track test execution time -- **Coverage Analysis**: Ensure comprehensive feature coverage -- **Error Handling**: Validate error messages and recovery -- **Integration Testing**: Test real-world scenarios diff --git a/tests/engine/builtin-functions.test.js b/tests/engine/builtin-functions.test.js index 956e195..3a73ee1 100644 --- a/tests/engine/builtin-functions.test.js +++ b/tests/engine/builtin-functions.test.js @@ -11,7 +11,7 @@ import { evaluateBuiltIn, getFunctionSignature, BUILT_IN_FUNCTIONS -} from '../../src/ast/interpreter/BuiltInFunctions.js'; +} from '@arbiter/evidence-dsl/interpreter/BuiltInFunctions'; describe('Built-in Functions Registry', () => { it('should identify built-in functions', () => { diff --git a/tests/engine/dsl-challenge-predicate.test.js b/tests/engine/dsl-challenge-predicate.test.js index 2b97c24..c3e02ee 100644 --- a/tests/engine/dsl-challenge-predicate.test.js +++ b/tests/engine/dsl-challenge-predicate.test.js @@ -1,6 +1,6 @@ import { describe, test } from 'node:test'; import assert from 'node:assert/strict'; -import { validateDslText } from '../../src/ast/validation/DSLValidation.js'; +import { validateDslText } from '@arbiter/evidence-dsl/validation/DSLValidation'; describe('DSL injectable predicates (* prefix)', () => { test('allows injectable predicates with * prefix in evidence bodies', () => { diff --git a/tests/engine/dsl-type-guards.test.js b/tests/engine/dsl-type-guards.test.js index dc2afd9..013b6ad 100644 --- a/tests/engine/dsl-type-guards.test.js +++ b/tests/engine/dsl-type-guards.test.js @@ -1,6 +1,6 @@ import { describe, test } from 'node:test'; import assert from 'node:assert/strict'; -import { validateDslText } from '../../src/ast/validation/DSLValidation.js'; +import { validateDslText } from '@arbiter/evidence-dsl/validation/DSLValidation'; describe('DSL type guards', () => { test('infix is guard narrows for attribute access', () => { diff --git a/tests/rigor/dsl-compiler.test.js b/tests/rigor/dsl-compiler.test.js index 7699712..bdc3da3 100644 --- a/tests/rigor/dsl-compiler.test.js +++ b/tests/rigor/dsl-compiler.test.js @@ -23,7 +23,7 @@ import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; import { rigor } from '@rigor/core'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; +import { DSLCompiler } from '@arbiter/evidence-dsl/DSLCompiler'; // Built-in types from lib/src/ast/validation/DSLPrelude.js are reserved (User, Account, // Device, AuthSession). Use non-reserved names so the validator accepts the DSL. @@ -215,8 +215,8 @@ describe('DSLCompiler → engine rule mapping (rigor)', () => { // multi_hop shape uses a plain variable binding instead. We bypass the // validator by directly exercising the parser→generator path: parse // only, then run the generator against the parsed AST. - const { parse } = await import('../../src/ast/parser/DSLParser.js'); - const { RuleGenerator } = await import('../../src/ast/generator/RuleGenerator.js'); + const { parse } = await import('@arbiter/evidence-dsl/parser/DSLParser'); + const { RuleGenerator } = await import('@arbiter/evidence-dsl/generator/RuleGenerator'); const dsl = `${DEFINITIONS}${FACTS}\nevidence canReach(a: Person, b: Person) { friend_of(a, f) { friend_of(f, b) } limit 5 }\n`; const program = parse(dsl); const generator = new RuleGenerator(arbiter); diff --git a/tests/rigor/dsl-mutation-parity.test.js b/tests/rigor/dsl-mutation-parity.test.js index e936207..0220efa 100644 --- a/tests/rigor/dsl-mutation-parity.test.js +++ b/tests/rigor/dsl-mutation-parity.test.js @@ -17,7 +17,7 @@ import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; import { rigor } from '@rigor/core'; import { Arbiter } from '../../src/index.js'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; +import { DSLCompiler } from '@arbiter/evidence-dsl/DSLCompiler'; const EPS = 1e-9; const POS = [0, 0.25, 0.5, 0.75, 1]; diff --git a/tests/rigor/zanzibar-defeasible-dsl-comparator.test.js b/tests/rigor/zanzibar-defeasible-dsl-comparator.test.js index dfc9fa8..e1d227b 100644 --- a/tests/rigor/zanzibar-defeasible-dsl-comparator.test.js +++ b/tests/rigor/zanzibar-defeasible-dsl-comparator.test.js @@ -20,7 +20,7 @@ import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; import { rigor } from '@rigor/core'; import { Arbiter } from '../../src/index.js'; -import { DSLCompiler } from '../../src/ast/DSLCompiler.js'; +import { DSLCompiler } from '@arbiter/evidence-dsl/DSLCompiler'; const EPS = 1e-9; const POSSIBILITIES = [0, 0.25, 0.5, 0.75, 1]; diff --git a/tests/rules/dsl-injectable-predicate.test.js b/tests/rules/dsl-injectable-predicate.test.js index 9847e8b..2e7ba53 100644 --- a/tests/rules/dsl-injectable-predicate.test.js +++ b/tests/rules/dsl-injectable-predicate.test.js @@ -1,6 +1,6 @@ import { describe, test } from 'node:test'; import assert from 'node:assert/strict'; -import { validateDslText } from '../../src/ast/validation/DSLValidation.js'; +import { validateDslText } from '@arbiter/evidence-dsl/validation/DSLValidation'; describe.skip('DSL injectable predicates (* prefix)', () => { test('allows injectable predicates with * prefix in evidence bodies', () => { diff --git a/tests/rules/pipe-e-filter-e2e.test.js b/tests/rules/pipe-e-filter-e2e.test.js index 92d2ffe..1a90fdd 100644 --- a/tests/rules/pipe-e-filter-e2e.test.js +++ b/tests/rules/pipe-e-filter-e2e.test.js @@ -1,5 +1,5 @@ -import { parse } from '../../src/ast/parser/GeneratedParser.js'; -import { RuleGenerator } from '../../src/ast/generator/RuleGenerator.js'; +import { parse } from '@arbiter/evidence-dsl/parser/GeneratedParser'; +import { RuleGenerator } from '@arbiter/evidence-dsl/generator/RuleGenerator'; import { Arbiter } from '../../src/core/Arbiter.js'; const dsl = [