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,
|
||||
} from 'imhotep-core'
|
||||
|
||||
import { isPredicateName, collectSpatialPredicateNames } from 'imhotep-core'
|
||||
|
||||
import type { Token } from './lexer.js'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -658,16 +660,9 @@ export class GrammarParser {
|
||||
|
||||
private isKeywordThatCanBePredicate(): boolean {
|
||||
const kind = this.currentToken().kind
|
||||
const predicateKinds: 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',
|
||||
// Size predicates that can appear in FOL formula bodies
|
||||
'width', 'height', 'size', 'between',
|
||||
]
|
||||
return predicateKinds.includes(kind)
|
||||
// 'size' is a fluent API keyword for size assertions in FOL bodies;
|
||||
// all other predicate names derive from the spec table.
|
||||
return isPredicateName(kind) || kind === 'size'
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -1142,13 +1137,7 @@ export class GrammarParser {
|
||||
)
|
||||
}
|
||||
|
||||
const relationKinds: 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',
|
||||
]
|
||||
const relationKinds = collectSpatialPredicateNames() as Array<Token['kind']>
|
||||
|
||||
for (const kind of relationKinds) {
|
||||
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