refactor: convert grammar predicate detection to spec table
Replace 21-item hardcoded isKeywordThatCanBePredicate array with isPredicateName() from PredicateSpec (+ 'size' special case for fluent API FOL bodies). Replace 24-item parseRelation relationKinds array with collectSpatialPredicateNames() from spec. Error message now also auto-derives from the spec. 595 SDK + 57 E2E tests pass.
This commit is contained in:
@@ -27,6 +27,8 @@ import type {
|
|||||||
ToleranceLiteralNode,
|
ToleranceLiteralNode,
|
||||||
} from 'imhotep-core'
|
} from 'imhotep-core'
|
||||||
|
|
||||||
|
import { isPredicateName, collectSpatialPredicateNames } from 'imhotep-core'
|
||||||
|
|
||||||
import type { Token } from './lexer.js'
|
import type { Token } from './lexer.js'
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -658,16 +660,9 @@ export class GrammarParser {
|
|||||||
|
|
||||||
private isKeywordThatCanBePredicate(): boolean {
|
private isKeywordThatCanBePredicate(): boolean {
|
||||||
const kind = this.currentToken().kind
|
const kind = this.currentToken().kind
|
||||||
const predicateKinds: Token['kind'][] = [
|
// 'size' is a fluent API keyword for size assertions in FOL bodies;
|
||||||
'leftOf', 'rightOf', 'above', 'below',
|
// all other predicate names derive from the spec table.
|
||||||
'alignedWith', 'leftAlignedWith', 'rightAlignedWith', 'topAlignedWith', 'bottomAlignedWith',
|
return isPredicateName(kind) || kind === 'size'
|
||||||
'centeredWithin', 'inside', 'contains', 'overlaps', 'intersects', 'touches', 'separatedFrom', 'hasGap',
|
|
||||||
// Spatial aliases
|
|
||||||
'beside', 'nextTo', 'adjacent', 'touching', 'near', 'under', 'within',
|
|
||||||
// Size predicates that can appear in FOL formula bodies
|
|
||||||
'width', 'height', 'size', 'between',
|
|
||||||
]
|
|
||||||
return predicateKinds.includes(kind)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@@ -1142,13 +1137,7 @@ export class GrammarParser {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const relationKinds: Array<Token['kind']> = [
|
const relationKinds = collectSpatialPredicateNames() as Array<Token['kind']>
|
||||||
'leftOf', 'rightOf', 'above', 'below',
|
|
||||||
'alignedWith', 'leftAlignedWith', 'rightAlignedWith', 'topAlignedWith', 'bottomAlignedWith',
|
|
||||||
'centeredWithin', 'inside', 'contains', 'overlaps', 'intersects', 'touches', 'separatedFrom', 'hasGap',
|
|
||||||
// Spatial aliases
|
|
||||||
'beside', 'nextTo', 'adjacent', 'touching', 'near', 'under', 'within',
|
|
||||||
]
|
|
||||||
|
|
||||||
for (const kind of relationKinds) {
|
for (const kind of relationKinds) {
|
||||||
if (this.match(kind)) {
|
if (this.match(kind)) {
|
||||||
@@ -1156,7 +1145,7 @@ export class GrammarParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw this.error(`Expected relation (leftOf, rightOf, above, below, alignedWith, centeredWithin, inside, contains, overlaps, intersects, touches, separatedFrom, hasGap, beside, nextTo, adjacent, touching, near, under, within)`)
|
throw this.error(`Expected relation (${relationKinds.join(', ')})`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user