Skip to content

Commit

Permalink
macOS happy?
Browse files Browse the repository at this point in the history
  • Loading branch information
jitsedesmet committed Jan 17, 2025
1 parent 39be54e commit ccf4f31
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 172 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ jobs:
path: |
.rdf-test-suite-cache
key: rdftestsuite-${{ hashFiles('yarn.lock') }}
- run: node --max-old-space-size=500 ./node_modules/rdf-test-suite/bin/Runner.js engines/engine-sparql-1-1/spec/parser.cjs http://w3c.github.io/rdf-tests/sparql/sparql11/manifest-all.ttl -c ./.rdf-test-suite-cache/
- run: node --max-old-space-size=2000 ./node_modules/rdf-test-suite/bin/Runner.js engines/engine-sparql-1-1/spec/parser.cjs http://w3c.github.io/rdf-tests/sparql/sparql11/manifest-all.ttl -c ./.rdf-test-suite-cache/
91 changes: 18 additions & 73 deletions packages/core/lib/grammar-builder/parserBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class Builder<Names extends string, RuleDefs extends RuleDefMap<Names>> {
/**
* Add a rule to the grammar. If the rule already exists, but the implementation differs, an error will be thrown.
*/
public addRuleRedundant<U extends string, RET, ARGS extends undefined[]>(rule: RuleDef<U, RET, ARGS>):
public addRuleRedundant<U extends string, RET, ARGS extends unknown[]>(rule: RuleDef<U, RET, ARGS>):
Builder<Names | U, {[K in Names | U]: K extends U ? RuleDef<K, RET, ARGS> : ( K extends Names ? (RuleDefs[K] extends RuleDef<K> ? RuleDefs[K] : never ) : never) }> {
const self = <Builder<Names | U, {[K in Names | U]: K extends U ? RuleDef<K, RET, ARGS> : ( K extends Names ? (RuleDefs[K] extends RuleDef<K> ? RuleDefs[K] : never ) : never) }>>
<unknown> this;
Expand Down Expand Up @@ -156,7 +156,7 @@ export class Builder<Names extends string, RuleDefs extends RuleDefMap<Names>> {
const selfSufficientParser: Partial<ParserFromRules<Names, RuleDefs>> = {};
// eslint-disable-next-line ts/no-unnecessary-type-assertion
for (const rule of <RuleDef<Names>[]> Object.values(this.rules)) {
selfSufficientParser[rule.name] = <any> ((input: string, ...args: unknown[]) => {
selfSufficientParser[rule.name] = <any> ((input: string, arg: unknown) => {
// Transform input in accordance to 19.2
input = input.replaceAll(
/\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{8})/gu,
Expand All @@ -183,7 +183,7 @@ export class Builder<Names extends string, RuleDefs extends RuleDefMap<Names>> {

parser.reset();
parser.input = lexResult.tokens;
const result = parser[rule.name](...args);
const result = parser[rule.name](arg);
if (parser.errors.length > 0) {
// Console.log(lexResult.tokens);
throw new Error(`Parse error on line ${parser.errors.map(x => x.token.startLine).join(', ')}
Expand Down Expand Up @@ -251,6 +251,11 @@ ${parser.errors.map(x => `${x.token.startLine}: ${x.message}`).join('\n')}`);
}

private getSelfRef(): CstDef {
const subRuleImpl = (subrule: typeof this.SUBRULE): CstDef['SUBRULE'] => {
return ((cstDef, ...args) => {
return subrule(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
}) satisfies CstDef['SUBRULE'];
}
return {
CONSUME: (tokenType, option) => this.CONSUME(tokenType, option),
CONSUME1: (tokenType, option) => this.CONSUME1(tokenType, option),
Expand Down Expand Up @@ -330,76 +335,16 @@ ${parser.errors.map(x => `${x.token.startLine}: ${x.message}`).join('\n')}`);
throw error;
}
},
SUBRULE: (cstDef, ...args) => {
try {
return this.SUBRULE(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE1: (cstDef, ...args) => {
try {
return this.SUBRULE1(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE2: (cstDef, ...args) => {
try {
return this.SUBRULE2(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE3: (cstDef, ...args) => {
try {
return this.SUBRULE3(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE4: (cstDef, ...args) => {
try {
return this.SUBRULE4(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE5: (cstDef, ...args) => {
try {
return this.SUBRULE5(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE6: (cstDef, ...args) => {
try {
return this.SUBRULE6(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE7: (cstDef, ...args) => {
try {
return this.SUBRULE7(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE8: (cstDef, ...args) => {
try {
return this.SUBRULE8(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE9: (cstDef, ...args) => {
try {
return this.SUBRULE9(<any> this[<keyof (typeof this)> cstDef.name], <any> { ARGS: args });
} catch (error: unknown) {
throw error;
}
},
SUBRULE: subRuleImpl((rule, args) => this.SUBRULE(rule, args)),
SUBRULE1: subRuleImpl((rule, args) => this.SUBRULE1(rule, args)),
SUBRULE2: subRuleImpl((rule, args) => this.SUBRULE2(rule, args)),
SUBRULE3: subRuleImpl((rule, args) => this.SUBRULE3(rule, args)),
SUBRULE4: subRuleImpl((rule, args) => this.SUBRULE4(rule, args)),
SUBRULE5: subRuleImpl((rule, args) => this.SUBRULE5(rule, args)),
SUBRULE6: subRuleImpl((rule, args) => this.SUBRULE6(rule, args)),
SUBRULE7: subRuleImpl((rule, args) => this.SUBRULE7(rule, args)),
SUBRULE8: subRuleImpl((rule, args) => this.SUBRULE8(rule, args)),
SUBRULE9: subRuleImpl((rule, args) => this.SUBRULE9(rule, args)),
};
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/core/lib/grammar-builder/ruleDefTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ export type RuleDef<
ParamType extends unknown[] = unknown[],
> = {
name: NameType;
impl: (def: ImplArgs) => (...args: ArrayElementsUndefinable<ParamType>) => ReturnType;
impl: (def: ImplArgs) => (...args: ArrayMagicWork<ParamType>) => ReturnType;
};

export type RuleDefReturn<T> = T extends RuleDef<any, infer Ret, any> ? Ret : never;

type ArrayElementsUndefinable<ArrayType extends any[]> =
ArrayType extends [infer First, ...infer Rest] ? [First | undefined, ...ArrayElementsUndefinable<Rest>] : [];
type ArrayMagicWork<ArrayType extends unknown[]> =
ArrayType extends [infer First, ...infer Rest] ? [First, ...ArrayMagicWork<Rest>] : [];

export interface ImplArgs extends CstDef {
cache: WeakMap<RuleDef, unknown>;
Expand Down
3 changes: 0 additions & 3 deletions packages/rules-sparql-1-1/lib/Sparql11types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ export type Triple = {
object: Term;
};

export type TripleCreatorS = (part: Pick<Triple, 'subject'>) => Triple;
export type TripleCreatorSP = (part: Pick<Triple, 'subject' | 'predicate'>) => Triple;

export interface IGraphNode {
node: ITriplesNode['node'] | Term;
triples: Triple[];
Expand Down
84 changes: 41 additions & 43 deletions packages/rules-sparql-1-1/lib/grammar/tripleBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import { var_, varOrTerm, verb } from './general';
import { canCreateBlankNodes } from './literals';
import { path } from './propertyPaths';
import type {
BgpPattern,
BgpPattern, BlankTerm,
IGraphNode,
IriTerm,
ITriplesNode,
PropertyPath,
Triple,
TripleCreatorS,
TripleCreatorSP,
VariableTerm,
} from '../Sparql11types';

Expand Down Expand Up @@ -45,18 +43,15 @@ function triplesSameSubjectImpl<T extends string>(name: T, allowPaths: boolean):
{
ALT: () => {
const subject = SUBRULE(varOrTerm);
const propNotEmpty = SUBRULE(allowPaths ? propertyListPathNotEmpty : propertyListNotEmpty);

return ACTION(() =>
propNotEmpty.map(partial => partial({ subject })));
return SUBRULE(allowPaths ? propertyListPathNotEmpty : propertyListNotEmpty, subject);
},
},
{
ALT: () => {
const subjectNode = SUBRULE(allowPaths ? triplesNodePath : triplesNode);
const restNode = SUBRULE(allowPaths ? propertyListPath : propertyList);
const restNode = SUBRULE(allowPaths ? propertyListPath : propertyList, subjectNode.node);
return ACTION(() => [
...restNode.map(partial => partial({ subject: subjectNode.node })),
...restNode,
...subjectNode.triples,
]);
},
Expand All @@ -71,11 +66,11 @@ export const triplesSameSubjectPath = triplesSameSubjectImpl('triplesSameSubject
* [[76]](https://www.w3.org/TR/sparql11-query/#rPropertyList)
* [[82]](https://www.w3.org/TR/sparql11-query/#rPropertyListPath)
*/
function propertyListImpl<T extends string>(name: T, allowPaths: boolean): RuleDef<T, TripleCreatorS[]> {
function propertyListImpl<T extends string>(name: T, allowPaths: boolean): RuleDef<T, Triple[], [Triple['subject']]> {
return {
name,
impl: ({ SUBRULE, OPTION }) => () =>
OPTION(() => SUBRULE(allowPaths ? propertyListPathNotEmpty : propertyListNotEmpty)) ?? [],
impl: ({ SUBRULE, OPTION }) => (subject) =>
OPTION(() => SUBRULE(allowPaths ? propertyListPathNotEmpty : propertyListNotEmpty, subject)) ?? [],
};
}
export const propertyList = propertyListImpl('propertyList', false);
Expand All @@ -90,11 +85,11 @@ export const propertyListPath = propertyListImpl('propertyListPath', true);
function propertyListNotEmptyImplementation<T extends string>(
name: T,
allowPaths: boolean,
): RuleDef<T, TripleCreatorS[]> {
): RuleDef<T, Triple[], [Triple['subject']]> {
return {
name,
impl: ({ ACTION, CONSUME, MANY, SUBRULE1, SUBRULE2, OPTION, OR1, OR2, context }) => () => {
const result: TripleCreatorS[] = [];
impl: ({ ACTION, CONSUME, MANY, SUBRULE1, SUBRULE2, OPTION, OR1, OR2, context }) => (subject) => {
const result: Triple[] = [];
const resultAppendage: typeof result = [];

// Generates predicate and objectList
Expand All @@ -104,19 +99,22 @@ function propertyListNotEmptyImplementation<T extends string>(
{ ALT: () => SUBRULE1(verbSimple) },
]) :
SUBRULE1(verb);
const firstObjects = SUBRULE1(allowPaths ? objectListPath : objectList);
let filterSubject: IriTerm;
const firstObjects = SUBRULE1(
allowPaths ? objectListPath : objectList,
ACTION(() => filterSubject = context.dataFactory.namedNode('internal:filterSubject')),
firstProperty
);
ACTION(() => {
// TODO: this filter is only here to be compliant with sparqlJS and is quite arbitrary.
// For the first predicate,
// additionally generated triples (like from collections) are shoved to the back of the result.
const filterSubject = context.dataFactory.namedNode('internal:filterSubject');
for (const cObject of firstObjects) {
const triple = cObject({ subject: filterSubject, predicate: firstProperty });
const generator: TripleCreatorS = rest => cObject({ ...rest, predicate: firstProperty });
for (const triple of firstObjects) {
if (triple.subject === filterSubject) {
result.push(generator);
result.push({
subject: subject,
predicate: triple.predicate,
object: triple.object,
});
} else {
resultAppendage.push(generator);
resultAppendage.push(triple);
}
}
});
Expand All @@ -131,13 +129,10 @@ function propertyListNotEmptyImplementation<T extends string>(
]) :
SUBRULE2(verb);
// https://www.w3.org/2013/sparql-errata#errata-query-3
const objects = SUBRULE2(allowPaths ? objectListPath : objectList);
const objects = SUBRULE2(allowPaths ? objectListPath : objectList, subject, predicate);

ACTION(() => {
result.push(
...objects
.map(object => (partS: Pick<Triple, 'subject'>) => object({ ...partS, predicate })),
);
result.push(...objects);
});
});
});
Expand Down Expand Up @@ -168,14 +163,14 @@ export const verbSimple: RuleDef<'verbSimple', VariableTerm> = <const> {
* [[79]](https://www.w3.org/TR/sparql11-query/#rObjectList)
* [[86]](https://www.w3.org/TR/sparql11-query/#rObjectListPath)
*/
function objectListImpl<T extends string>(name: T, allowPaths: boolean): RuleDef<T, TripleCreatorSP[]> {
function objectListImpl<T extends string>(name: T, allowPaths: boolean): RuleDef<T, Triple[], [Triple['subject'], Triple['predicate']]> {
return {
name,
impl: ({ ACTION, SUBRULE, AT_LEAST_ONE_SEP }) => () => {
const objects: TripleCreatorSP[] = [];
impl: ({ ACTION, SUBRULE, AT_LEAST_ONE_SEP }) => (subject, predicate) => {
const objects: Triple[] = [];
AT_LEAST_ONE_SEP({
DEF: () => {
const objectTriples = SUBRULE(allowPaths ? objectPath : object);
const objectTriples = SUBRULE(allowPaths ? objectPath : object, subject, predicate);
ACTION(() => objects.push(...objectTriples));
},
SEP: l.symbols.comma,
Expand All @@ -187,15 +182,15 @@ function objectListImpl<T extends string>(name: T, allowPaths: boolean): RuleDef
export const objectList = objectListImpl('objectList', false);
export const objectListPath = objectListImpl('objectListPath', true);

function objectImpl<T extends string>(name: T, allowPaths: boolean): RuleDef<T, TripleCreatorSP[]> {
function objectImpl<T extends string>(name: T, allowPaths: boolean): RuleDef<T, Triple[], [Triple['subject'], Triple['predicate']]> {
return {
name,
impl: ({ ACTION, SUBRULE }) => () => {
impl: ({ ACTION, SUBRULE }) => (subject, predicate) => {
const node = SUBRULE(allowPaths ? graphNodePath : graphNode);
return ACTION(() => [
part => ({ ...part, object: node.node }),
...node.triples.map(val => () => val),
] satisfies TripleCreatorSP[]);
{ subject, predicate, object: node.node },
...node.triples,
]);
},
};
}
Expand Down Expand Up @@ -235,14 +230,17 @@ function blankNodePropertyListImpl<T extends string>(name: T, allowPaths: boolea
name,
impl: ({ ACTION, SUBRULE, CONSUME, context }) => () => {
CONSUME(l.symbols.LSquare);
const propList = SUBRULE(allowPaths ? propertyListPathNotEmpty : propertyListNotEmpty);
let blankNode: BlankTerm;
const propList = SUBRULE(
allowPaths ? propertyListPathNotEmpty : propertyListNotEmpty,
ACTION(() => blankNode = context.dataFactory.blankNode()),
);
CONSUME(l.symbols.RSquare);

return ACTION(() => {
const subject = context.dataFactory.blankNode();
return {
node: subject,
triples: propList.map(part => part({ subject })),
node: blankNode,
triples: propList,
};
});
},
Expand Down
10 changes: 8 additions & 2 deletions packages/rules-sparql-1-1/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import type {GroupPattern, Pattern, PropertyPath, Term, VariableTerm} from "./Sparql11types";
import type {
GroupPattern,
Pattern,
PropertyPath,
Term,
VariableTerm
} from "./Sparql11types";

export function deGroupSingle(group: GroupPattern): Pattern {
return group.patterns.length === 1 ? group.patterns[0] : group;
}

export function isVariable(term: Term | PropertyPath): term is VariableTerm {
return 'termType' in term && term.termType === 'Variable';
}
}
Loading

0 comments on commit ccf4f31

Please sign in to comment.