Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions shacl-compact-syntax/grammar/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# delete targets that caused an error
.DELETE_ON_ERROR:

# make as many targets as you can
# .IGNORE:

ebnf-convert = java -jar c:/prog/bin/ebnf-convert.war
rr = java -jar c:/prog/bin/rr.war

HTML = shaclc-ANTLR.html shaclc-JavaCC.html shaclc-Jison.html shaclc-XText.html

# MD = shaclc-ANTLR.md shaclc-JavaCC.md shaclc-Jison.md shaclc-XText.md
# Neither embedded PNG nor SVG is rendered by Github markdown

all: $(HTML) # $(MD)

%.html: %.ebnf
$(rr) $^ > $@

%.md: %.ebnf
$(rr) -md -png $^ > $@

shaclc-ANTLR.ebnf : shaclc-ANTLR.g4
$(ebnf-convert) $^ > $@

shaclc-JavaCC.ebnf: shaclc-JavaCC.jj
$(ebnf-convert) $^ > $@

shaclc-Jison.ebnf : shaclc-Jison.jison
$(ebnf-convert) $^ > $@

shaclc-XText.ebnf : shaclc-XText.xtext
$(ebnf-convert) $^ > $@

31 changes: 31 additions & 0 deletions shacl-compact-syntax/grammar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Unifying SHACL-C Grammars
(Task: https://github.com/w3c/shacl/issues/37#issuecomment-1997655429 )

As a first task of the SHACL Compact Syntax sub-WG, we look at proposed SHACL-C grammars:
Comment thread
VladimirAlexiev marked this conversation as resolved.
Outdated

- [ANTLR](shaclc-ANTLR.g4) (was part of TopQuadrant SHACL, also in the [grammar-section](https://w3c.github.io/shacl/shacl-compact-syntax/#grammar-section) of the candidate spec) by @HolgerKnublauch
- [JavaCC](https://github.com/apache/jena/blob/main/jena-shacl/shaclc/shaclc.jj) (part of Jena) by @afs
- [XText](https://gitlab.com/allotrope-open-source/shape-editor/-/blob/master/src/com.osthus.shapes.shaclc.parent/com.osthus.shapes.shaclc/src/com/osthus/shapes/shaclc/SHACLC.xtext) (part of Allotrope-open-source) by @tw-osthus
- [Jison](https://github.com/jeswr/shaclcjs/blob/main/lib/shaclc.jison) (part of shacl.js) by @jeswr

We use two tools to understand them and try to unify them:
- https://github.com/GuntherRademacher/ebnf-convert to convert them to W3C-style EBNF, which is also needed for official publication.
- https://github.com/GuntherRademacher/rr to produce "rail-road" diagrams, which make it easier to understand the grammars.

Problems:
- DONE: Unicode escapes in XText: https://github.com/GuntherRademacher/ebnf-convert/issues/8 .
This was fixed 22-Mar-2024: build from source and use `build/distributions/ebnf-convert-0.68-SNAPSHOT-java11.zip/ebnf-convert.war`
- DONE: fixed problems in Jison: https://github.com/w3c/shacl/issues/48 .

`rr` can make railroad diagrams in HTML or Markdown.
- The Markdown uses embedded images (eg `data:image/png;base64`), which are not rendered by Github (neither PNG nor SVG)
- We could ask `rr` to put the images outside, but I think that's too much trouble
- So instead, we use HTML where the images are embedded as SVG and render properly

# Candidate SHACL-C Grammars

- [shacl-ANTLR.g4](shacl-ANTLR.g4) -> [shacl-ANTLR.ebnf](shacl-ANTLR.ebnf) -> [shaclc-ANTLR.html](https://rawgit2.com/shacl/master/shacl-compact-syntax/grammar/shaclc-ANTLR.html) (or [in branch](https://rawgit2.com/VladimirAlexiev/shacl/shaclc-grammars/shacl-compact-syntax/grammar/shaclc-ANTLR.html))
- [shacl-JavaCC.jj](shacl-JavaCC.jj) -> [shacl-JavaCC.ebnf](shacl-JavaCC.ebnf) -> [shaclc-JavaCC.html](https://rawgit2.com/shacl/master/shacl-compact-syntax/grammar/shaclc-JavaCC.html) (or [in branch](https://rawgit2.com/VladimirAlexiev/shacl/shaclc-grammars/shacl-compact-syntax/grammar/shaclc-JavaCC.html))
- [shacl-XText.xtext](shacl-XText.xtext) -> [shacl-XText.ebnf](shacl-XText.ebnf) -> [shaclc-XText.html](https://rawgit2.com/shacl/master/shacl-compact-syntax/grammar/shaclc-XText.html) (or [in branch](https://rawgit2.com/VladimirAlexiev/shacl/shaclc-grammars/shacl-compact-syntax/grammar/shaclc-XText.html))
- [shacl-Jison.jison](shacl-Jison.jison) -> [shacl-Jison.ebnf](shacl-Jison.ebnf) -> [shaclc-Jison.html](https://rawgit2.com/shacl/master/shacl-compact-syntax/grammar/shaclc-Jison.html) (or [in branch](https://rawgit2.com/VladimirAlexiev/shacl/shaclc-grammars/shacl-compact-syntax/grammar/shaclc-Jison.html))

203 changes: 203 additions & 0 deletions shacl-compact-syntax/grammar/shaclc-ANTLR.ebnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/* converted on Mon Mar 18, 2024, 18:17 (UTC+02) by antlr_4-to-w3c v0.67 which is Copyright (c) 2011-2024 by Gunther Rademacher <grd@gmx.net> */

shaclDoc ::= directive* ( nodeShape | shapeClass )* EOF
directive
::= baseDecl
| importsDecl
| prefixDecl
baseDecl ::= 'BASE' IRIREF
importsDecl
::= 'IMPORTS' IRIREF
prefixDecl
::= 'PREFIX' PNAME_NS IRIREF
shapeClass
::= 'shapeClass' iri nodeShapeBody
nodeShape
::= 'shape' iri targetClass? nodeShapeBody
nodeShapeBody
::= '{' constraint* '}'
targetClass
::= '->' iri+
constraint
::= ( nodeOr+ | propertyShape ) '.'
nodeOr ::= nodeNot ( '|' nodeNot )*
nodeNot ::= '!'? nodeValue
nodeValue
::= nodeParam '=' iriOrLiteralOrArray
propertyShape
::= path ( propertyCount | propertyOr )*
propertyOr
::= propertyNot ( '|' propertyNot )*
propertyNot
::= '!'? propertyAtom
propertyAtom
::= propertyType
| nodeKind
| shapeRef
| propertyValue
| nodeShapeBody
propertyCount
::= '[' propertyMinCount '..' propertyMaxCount ']'
propertyMinCount
::= INTEGER
propertyMaxCount
::= INTEGER
| '*'
propertyType
::= iri
nodeKind ::= 'BlankNode'
| 'IRI'
| 'Literal'
| 'BlankNodeOrIRI'
| 'BlankNodeOrLiteral'
| 'IRIOrLiteral'
shapeRef ::= ATPNAME_LN
| ATPNAME_NS
| '@' IRIREF
propertyValue
::= propertyParam '=' iriOrLiteralOrArray
path ::= pathAlternative
pathAlternative
::= pathSequence ( '|' pathSequence )*
pathSequence
::= pathEltOrInverse ( '/' pathEltOrInverse )*
pathElt ::= pathPrimary pathMod?
pathEltOrInverse
::= '^'? pathElt
pathMod ::= '?'
| '*'
| '+'
pathPrimary
::= iri
| '(' path ')'
iriOrLiteralOrArray
::= iriOrLiteral
| array
iriOrLiteral
::= iri
| literal
iri ::= IRIREF
| prefixedName
prefixedName
::= PNAME_LN
| PNAME_NS
literal ::= rdfLiteral
| numericLiteral
| booleanLiteral
booleanLiteral
::= 'true'
| 'false'
numericLiteral
::= INTEGER
| DECIMAL
| DOUBLE
rdfLiteral
::= string ( LANGTAG | '^^' datatype )?
datatype ::= iri
string ::= STRING_LITERAL_LONG1
| STRING_LITERAL_LONG2
| STRING_LITERAL1
| STRING_LITERAL2
array ::= '[' iriOrLiteral* ']'
nodeParam
::= 'targetNode'
| 'targetObjectsOf'
| 'targetSubjectsOf'
| 'deactivated'
| 'severity'
| 'message'
| 'class'
| 'datatype'
| 'nodeKind'
| 'minExclusive'
| 'minInclusive'
| 'maxExclusive'
| 'maxInclusive'
| 'minLength'
| 'maxLength'
| 'pattern'
| 'flags'
| 'languageIn'
| 'equals'
| 'disjoint'
| 'closed'
| 'ignoredProperties'
| 'hasValue'
| 'in'
propertyParam
::= 'deactivated'
| 'severity'
| 'message'
| 'class'
| 'datatype'
| 'nodeKind'
| 'minExclusive'
| 'minInclusive'
| 'maxExclusive'
| 'maxInclusive'
| 'minLength'
| 'maxLength'
| 'pattern'
| 'flags'
| 'languageIn'
| 'uniqueLang'
| 'equals'
| 'disjoint'
| 'lessThan'
| 'lessThanOrEquals'
| 'qualifiedValueShape'
| 'qualifiedMinCount'
| 'qualifiedMaxCount'
| 'qualifiedValueShapesDisjoint'
| 'closed'
| 'ignoredProperties'
| 'hasValue'
| 'in'
_ ::= PASS
| COMMENT
/* ws: definition */

<?TOKENS?>

PASS ::= [ #x9#xd#xa]+
COMMENT ::= '#' [^#xd#xa]*
IRIREF ::= '<' ( [^=<>"{}|^`\#x0000-#x0020] | UCHAR )* '>'
PNAME_NS ::= PN_PREFIX? ':'
PNAME_LN ::= PNAME_NS PN_LOCAL
ATPNAME_NS
::= '@' PN_PREFIX? ':'
ATPNAME_LN
::= '@' PNAME_NS PN_LOCAL
LANGTAG ::= '@' [a-zA-Z]+ ( '-' [a-zA-Z0-9]+ )*
INTEGER ::= [+#x2D]? [0-9]+
DECIMAL ::= [+#x2D]? [0-9]* '.' [0-9]+
DOUBLE ::= [+#x2D]? ( [0-9]+ '.' | '.'? [0-9] ) [0-9]* EXPONENT
EXPONENT ::= [eE] [+#x2D]? [0-9]+
STRING_LITERAL1
::= "'" ( [^#x0027#x005C#x000A#x000D] | ECHAR | UCHAR )* "'"
STRING_LITERAL2
::= '"' ( [^#x0022#x005C#x000A#x000D] | ECHAR | UCHAR )* '"'
STRING_LITERAL_LONG1
::= "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR | UCHAR ) )* "'''"
STRING_LITERAL_LONG2
::= '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR | UCHAR ) )* '"""'
UCHAR ::= ( '\u' | '\U' HEX HEX HEX HEX ) HEX HEX HEX HEX
ECHAR ::= '\' [tbnrf\"']
WS ::= [#x0020#x0009#x000D#x000A]
PN_CHARS_BASE
::= [A-Za-z#x00C0-#x00D6#x00D8-#x00F6#x00F8-#x02FF#x0370-#x037D#x037F-#x1FFF#x200C-#x200D#x2070-#x218F#x2C00-#x2FEF#x3001-#xD7FF#xF900-#xFDCF#xFDF0-#xFFFD]
PN_CHARS_U
::= PN_CHARS_BASE
| '_'
PN_CHARS ::= PN_CHARS_U
| [-0-9#x00B7#x0300-#x036F#x203F-#x2040]
PN_PREFIX
::= PN_CHARS_BASE ( ( PN_CHARS | '.' )* PN_CHARS )?
PN_LOCAL ::= ( PN_CHARS_U | [:0-9] | PLX ) ( ( PN_CHARS | '.' | ':' | PLX )* ( PN_CHARS | ':' | PLX ) )?
PLX ::= PERCENT
| PN_LOCAL_ESC
PERCENT ::= '%' HEX HEX
HEX ::= [0-9A-Fa-f]
PN_LOCAL_ESC
::= '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )
EOF ::= $
Loading