Skip to content

Commit 0efeba2

Browse files
Eric Prud'hommeauxclaude
andcommitted
+ ShEx 2.1: new ShExC parser, ShExJ-shaped AST, spec validator
Replace the ShEx1-era .ssx parser and RulePattern AST with a ShEx 2.1 implementation that passes all 1729 applicable shexSpec/shexTest cases (schemas, negativeSyntax, negativeStructure and validation manifests, including the EXTENDS/ABSTRACT hierarchy tests). Parser: lib/ShExCParser.ypp ports the productions of shex.js's ShExJison.jison (the reference ShExC grammar) to this repo's bison conventions; the scanner gains REGEXP, REPEAT_RANGE, CODE, ATPNAME and LANG_STRING tokens plus /* */ comments. Conflict-free LALR. AST + validation: lib/ShExSchema.{hpp,cpp} mirror ShExJ (shape expressions, triple expressions, node constraint components, value sets with stems/ranges/exclusions). The validator follows jena-shex: predicate-based pre-matching, eager recursive valueExpr filtering, iteration over matchings accepted by interval computation on the SORBE form of each triple expression, CLOSED/EXTRA handling, cyclic-schema assumptions, and EXTENDS splits with supertype constraint checks. Structure checks enforce defined references, triple-constraint-crossing cycles, no negation (or EXTRA'd constraint) in reference cycles, and shape/tripleExpr label separation. Semantic actions: the http://shex.io/extensions/Test/ language is interpreted (its fail(...) aborts); other languages are no-ops. tests/test_ShEx.cpp walks the shexTest manifests (fetched by tests/fetch-test-suites.sh) and registers each entry as a test case, mapping the suite's web URLs to the local checkout and resolving focus/shape blank nodes by source label. test_ShEx moves into CI's blocking bucket. AtomFactory now preserves the lexical form of xsd:boolean literals and interns them by it ("TRUE"^^xsd:boolean is not "true"^^xsd:boolean), which the ShEx ValidLexicalForm tests require. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent edc063a commit 0efeba2

20 files changed

Lines changed: 3701 additions & 1865 deletions

‎.github/workflows/ci.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,17 @@ jobs:
4141
- name: Run test suites
4242
run: >
4343
ctest --test-dir build --output-on-failure --timeout 600
44-
-E 'test_(SPARQL|SPARQL11|QueryMap|ShEx)$'
44+
-E 'test_(SPARQL|SPARQL11|QueryMap)$'
4545
4646
# These suites carry known pre-existing failures:
4747
# - test_SPARQL11: md5/sha* builtins are unimplemented (8 cases)
4848
# - test_SPARQL: function_library expects CSV <foo> parsed as an IRI,
4949
# a csv-regex branch deliberately disabled upstream (~2013)
50-
# - test_QueryMap, test_ShEx: heap-layout-dependent nondeterminism in
51-
# the query rewriter / ShEx normalizer makes single cases flaky
50+
# - test_QueryMap: heap-layout-dependent nondeterminism in the query
51+
# rewriter makes single cases flaky
5252
# Run them for visibility without gating the build.
5353
- name: Run suites with known pre-existing failures (non-blocking)
5454
continue-on-error: true
5555
run: >
5656
ctest --test-dir build --output-on-failure --timeout 600
57-
-R 'test_(SPARQL|SPARQL11|QueryMap|ShEx)$'
57+
-R 'test_(SPARQL|SPARQL11|QueryMap)$'

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ tests/RDFXMLTests/
3333
tests/sparql11-test-suite/
3434
bin/parseAndFree
3535
bin/dm-materialize
36+
tests/shexTest/

‎README‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ you'll need these packages:
3838
On macOS: brew install cmake boost bison flex expat
3939
(cmake prefers Homebrew's bison/flex over the older /usr/bin ones.)
4040

41+
# ShEx
42+
43+
lib/ShExCParser.ypp and lib/ShExSchema.{hpp,cpp} implement ShEx 2.1
44+
(ShExC syntax including IMPORT, ABSTRACT and EXTENDS; validation by
45+
interval-based matching over SORBE-normalized triple expressions, after
46+
jena-shex). tests/test_ShEx.cpp runs the shexSpec/shexTest suite
47+
(schemas, negativeSyntax, negativeStructure and validation manifests);
48+
tests/fetch-test-suites.sh clones the test data.
49+
4150
# More info
4251

4352
To learn more about SWObjects, checkout some tutorials given at SWAT4LS in 2010 and 2011:

‎lib/SWObjects.cpp‎

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2240,18 +2240,9 @@ void RecursiveExpressor::valuesClause (const ValuesClause* const, const ResultSe
22402240
} else if (p_URI == TTerm::URI_xsd_dateTime) {
22412241
return getDateTimeRDFLiteral(p_String.c_str());
22422242
} else if (p_URI == TTerm::URI_xsd_boolean) {
2243-
if (p_String == "0" || p_String == "false")
2244-
return getBooleanRDFLiteral("false", 0);
2245-
bool b;
2246-
#ifdef LIBC_PARSES_BOOL
2247-
is >> b;
2248-
#else
2249-
b = true;
2250-
#endif
2251-
// std::stringstream canonical;
2252-
// canonical << std::boolalpha << b;
2253-
// return getNumericRDFLiteral(canonical.str().c_str(), b);
2254-
return getBooleanRDFLiteral(p_String.c_str(), b);
2243+
// Preserve the lexical form; the value is true for the two true
2244+
// lexical representations.
2245+
return getBooleanRDFLiteral(p_String, p_String == "1" || p_String == "true");
22552246
}
22562247

22572248
std::stringstream buf;
@@ -2496,7 +2487,9 @@ void RecursiveExpressor::valuesClause (const ValuesClause* const, const ResultSe
24962487

24972488
const BooleanRDFLiteral* AtomFactory::getBooleanRDFLiteral (std::string p_String, bool p_value) {
24982489
std::stringstream buf;
2499-
buf << "\"" << (p_value ? "true" : "false") << "\"^^<http://www.w3.org/2001/XMLSchema#boolean>";
2490+
// key on the lexical form: "TRUE"^^xsd:boolean and "true"^^xsd:boolean
2491+
// are distinct RDF terms
2492+
buf << "\"" << p_String << "\"^^<http://www.w3.org/2001/XMLSchema#boolean>";
25002493
std::string key(buf.str());
25012494
RDFLiteralMap::const_iterator vi = rdfLiterals_static.find(key);
25022495
if (vi == rdfLiterals_static.end()) {

‎lib/ShExCParser.bnf‎

Lines changed: 0 additions & 122 deletions
This file was deleted.

0 commit comments

Comments
 (0)