Graphs and TriG-Star

Technologies

Resource Description Framework

Ontologies

Turtle

A Turtle document allows writing down an RDF graph in a compact textual form. An RDF graph is made up of triples consisting of a subject, predicate and object.

Comments may be given after a ‘#’ that is not part of another lexical token and continue to the end of the line.

2.1 Simple Triples
The simplest triple statement is a sequence of (subject, predicate, object) terms, separated by whitespace and terminated by ‘.‘ after each triple.

2.2 Predicate Lists
Often the same subject will be referenced by a number of predicates. The predicateObjectList production matches a series of predicates and objects, separated by ‘;‘, following a subject. This expresses a series of RDF Triples with that subject and each predicate and object allocated to one triple. Thus, the ‘;’ symbol is used to repeat the subject of triples that vary only in predicate and object RDF terms.

2.3 Object Lists
As with predicates often objects are repeated with the same subject and predicate. The objectList production matches a series of objects separated by ‘,‘ following a predicate. This expresses a series of RDF Triples with the corresponding subject and predicate and each object allocated to one triple. Thus, the ‘,’ symbol is used to repeat the subject and predicate of triples that only differ in the object RDF term.

2.4 IRIs
IRIs may be written as relative or absolute IRIs or prefixed names. Relative and absolute IRIs are enclosed in ‘<‘ and ‘>’ and may contain numeric escape sequences (described below). For example <http://example.org/#green-goblin>.

Relative IRIs like <#green-goblin> are resolved relative to the current base IRI. A new base IRI can be defined using the ‘@base‘ or ‘BASE’ directive. Specifics of this operation are defined in section 6.3 IRI References

The token ‘a‘ in the predicate position of a Turtle triple represents the IRI http://www.w3.org/1999/02/22-rdf-syntax-ns#type .

A prefixed name is a prefix label and a local part, separated by a colon “:“. A prefixed name is turned into an IRI by concatenating the IRI associated with the prefix and the local part. The ‘@prefix‘ or ‘PREFIX’ directive associates a prefix label with an IRI. Subsequent ‘@prefix’ or ‘PREFIX’ directives may re-map the same prefix label.

The Turtle language originally permitted only the syntax including the ‘@’ character for writing prefix and base directives. The case-insensitive ‘PREFIX’ and ‘BASE’ forms were added to align Turtle’s syntax with that of SPARQL. It is advisable to serialize RDF using the ‘@prefix’ and ‘@base’ forms until RDF 1.1 Turtle parsers are widely deployed.

Prefixed names are a superset of XML QNames. They differ in that the local part of prefixed names may include:

  • leading digits, e.g. leg:3032571 or isbn13:9780136019701
  • non leading colons, e.g. og:video:height
  • reserved character escape sequences, e.g. wgs:lat\-long

The ‘@prefix’ and ‘@base’ directives require a trailing ‘.‘ after the IRI, the equalivent ‘PREFIX’ and ‘BASE’ must not have a trailing ‘.’ after the IRI part of the directive.

2.5 RDF Literals
Literals are used to identify values such as strings, numbers, dates.

2.5.1 Quoted Literals
Quoted Literals have a lexical form followed by a language tag, a datatype IRI, or neither. The representation of the lexical form consists of an initial delimiter, e.g. , a sequence of permitted characters or numeric escape sequence or string escape sequence, and a final delimiter. The corresponding RDF lexical form is the characters between the delimiters, after processing any escape sequences. If present, the language tag is preceded by a ‘@‘. If there is no language tag, there may be a datatype IRI, preceeded by ‘^^‘. The datatype IRI in Turtle may be written using either an absolute IRI, a relative IRI, or prefixed name. If there is no datatype IRI and no language tag, the datatype is xsd:string.

2.5.2 Numbers
Numbers can be written like other literals with lexical form and datatype (e.g. “-5.0″^^xsd:decimal). Turtle has a shorthand syntax for writing integer values, arbitrary precision decimal values, and double precision floating point values.

2.5.3 Booleans
Boolean values may be written as either ‘true’ or ‘false’ (case-sensitive) and represent RDF literals with the datatype xsd:boolean.

2.6 RDF Blank Nodes
RDF blank nodes in Turtle are expressed as _: followed by a blank node label which is a series of name characters. The characters in the label are built upon PN_CHARS_BASE, liberalized as follows:

  • The characters _ and digits may appear anywhere in a blank node label.
  • The character . may appear anywhere except the first or last character.
  • The characters -, U+00B7, U+0300 to U+036F and U+203F to U+2040 are permitted anywhere except the first character.

A fresh RDF blank node is allocated for each unique blank node label in a document. Repeated use of the same blank node label identifies the same RDF blank node.

2.7 Nesting Unlabeled Blank Nodes in Turtle
In Turtle, fresh RDF blank nodes are also allocated when matching the production blankNodePropertyList and the terminal ANON. Both of these may appear in the subject or object position of a triple. That subject or object is a fresh RDF blank node. This blank node also serves as the subject of the triples produced by matching the predicateObjectList production embedded in a blankNodePropertyList. The generation of these triples is described in Predicate Lists. Blank nodes are also allocated for collections described below.

The Turtle grammar allows blankNodePropertyLists to be nested. In this case, each inner [ establishes a new subject blank node which reverts to the outer node at the ], and serves as the current subject for predicate object lists.

The use of predicateObjectList within a blankNodePropertyList is a common idiom for representing a series of properties of a node.

2.8 Collections
RDF provides a Collection structure for lists of RDF nodes. The Turtle syntax for Collections is a possibly empty list of RDF terms enclosed by (). This collection represents an rdf:first/rdf:rest list structure with the sequence of objects of the rdf:first statements being the order of the terms enclosed by ().

The (…) syntax must appear in the subject or object position of a triple. The blank node at the head of the list is the subject or object of the containing triple.

TriG

2.1 Triple Statements
As TriG is an extention of the Turtle language it allows for any constructs from the Turtle language. Simple Triples, Predicate Lists, and Object Lists can all be used either inside a graph statement, or on their own as in a Turtle document. When outside a graph statement, the triples are considered to be part of the default graph of the RDF Dataset.

2.2 Graph Statements
A graph statement pairs an IRI or blank node with a RDF graph. The triple statements that make up the graph are enclosed in {}.

In a TriG document a graph IRI or blank node may be used as label for more than one graph statements. The graph label of a graph statement may be omitted. In this case the graph is considered the default graph of the RDF Dataset.

A RDF Dataset might contain only a single graph.

A RDF Dataset may contain a default graph, and named graphs.

TriG provides various alternative ways to write graphs and triples, giving the data writer choices for clarity.

2.3 Other Terms
All other terms and directives come from Turtle.

2.3.1 Special Considerations for Blank Nodes
BlankNodes sharing the same label in differently labeled graph statements are considered to be the same BlankNode.

RDF-star

1.2 Overview
This specification describes RDF-star, an extension of RDF’s conceptual data model and concrete syntaxes, which provides a compact alternative to standard RDF reification. This model and its syntaxes enable the creation of concise triples that reference other triples as subject and object resources. Triples that include a triple as a subject or an object are known as RDF-star triples. The following dataset shows the example RDF-star triples from above using the Turtle-star syntax, which uses double angle brackets ‘<< … >>‘ to enclose a triple serving as a subject or object resource.

After declaring a prefix so that IRIs can be abbreviated, the first triple in this example asserts that employee38 has a familyName of “Smith”. Note that this dataset does not assert that employee38 has a jobTitle of “Assistant Designer”; it says that employee22 has made that claim. In other words, the triple “employee38 has a jobTitle of ‘Assistant Designer’” is not what we call an asserted triple, like “employee38 has a familyName of ‘Smith’” above; rather, it is known as a quoted triple.

If we added the triple :employee38 :jobTitle “Assistant Designer” to the example above, then this triple about employee38’s jobTitle would be both a quoted and an asserted triple. This pattern is quite common, so Turtle-star offers a dedicated syntax for it, called the annotation syntax, illustrated in Example 2 below. Note that this construct is purely syntactic sugar, as it can be expanded using only the double angle brackets.

This specification also describes an extension to the SPARQL Protocol and Query Language known as SPARQL-star for the querying of RDF-star triples. SPARQL can also be used to update RDF data, and SPARQL-star also extends that part. For example, the following SPARQL-star adds all the statements made by employee22 about employee38 as asserted triples, annotating them as “confirmed“.

1.3 Common misconceptions
People coming to RDF-star may have wrong ideas about what it is or how to use it. The purpose of this section is to dispel the most common misconceptions.

RDF-star is not syntactic sugar for standard reification. While the latter is a vocabulary that fits into the standard RDF model (abstract syntax), RDF-star extends that model (see § 2. Concepts and Abstract Syntax) with a new construct, namely quoted triples. Note also that the two are not mutually exclusive: standard reification can be used in conjunction with RDF-star.

Unlike reified statements, RDF-star quoted triples are unique: wherever << :employee38 :jobTitle “Assistant Designer” >> appears, it always denotes one and the same thing. This impacts the modeling choices one has to make when using RDF-star; this is further discussed in § 2.3 Triples and occurrences.

Finally, quoted triples are referentially opaque. This means that two quoted triples containing distinct but equivalent terms (i.e., coreferences, known to denote the same thing) are nonetheless considered to be different triples. § 6.4.4 Referential opacity and the following sections discuss the rationale for this design, and how some form of referential transparency can still be added to RDF-star if and when needed.

An RDF-star graph is a set of RDF-star triples.

An RDF-star triple is a 3-tuple defined recursively as follows:

any RDF triple is an RDF-star triple;
if t and t’ are RDF-star triples, s is an IRI or a blank node, p is an IRI, o is an IRI, a blank node or a literal, then (t, p, o), (s, p, t) and (t, p, t’) are RDF-star triples.
As for RDF triples, we call the 3 components of an RDF-star triple its subject, predicate and object, respectively. From the definitions above, it follows that any RDF graph is also an RDF-star graph. Note also that, by definition, an RDF-star triple cannot contain itself and cannot be nested infinitely.

IRIs, literals, blank nodes and RDF-star triples are collectively known as RDF-star terms.

For every RDF-star triple t, we define its constituent terms (or simply constituents) as the set containing its subject, its predicate, its object, plus all the constituent terms of its subject and/or its object if they are themselves RDF-star triples. By extension, we define the constituent terms of an RDF-star graph to be the union set of the constituent terms of all its triples.

An RDF-star triple used as the subject or object of another RDF-star triple is called a quoted triple. An RDF-star triple that is an element of an RDF-star graph is called an asserted triple. Note that, in a given RDF-star graph, the same triple MAY be both quoted and asserted.

An RDF-star dataset is a collection of RDF-star graphs, and comprises:

Exactly one default graph, being an RDF-star graph. The default graph does not have a name and MAY be empty.
Zero or more named graphs. Each named graph is a pair consisting of either an IRI or a blank node (called the graph name), and an RDF-star graph. Graph names are unique within an RDF-star dataset.
Again, this definition is an extension of the notion of RDF dataset, hence it follows that any RDF dataset is also an RDF-star dataset.

2.1 Quoted and Asserted Triples
This section is non-normative.

A triple in RDF is a tuple of three components: subject, predicate, and object. These are collectively known as RDF Terms as defined in [RDF11-CONCEPTS].

RDF-star introduces quoted triple, which is a new kind of RDF term. A quoted triple is a triple used as the subject or object of another triple. Quoted triples can also be called “embedded triples”.

in RDF 1.1, an asserted triple is an element of the set of triples that make up an RDF graph. RDF-star does not change this except that an RDF-star triple can contain quoted triples. A triple can be used as an asserted triple, a quoted triple, or both, in a given graph.

A quoted triple is written in Turtle-star and related syntaxes using delimiters << and >>.

<< :a :name “Alice” >>

The definition of quoted triple is recursive. That is, a quoted triple can itself have a subject or object component which is another quoted triple. Cycles of quoted triples can not be created. In the next example, there is a quoted triple with property :reportedBy, whose subject is another quoted triple, :a :name “Alice”.

<< << :a :name “Alice” >> :reportedBy :charlie >>

2.3 Triples and occurrences
This section is non-normative.

According to the definitions above, an RDF-star triple is an abstract entity whose identity is entirely defined by its subject, predicate, and object. Conversely, given three RDF-star terms s, p, and o, there is exactly and only one RDF-star triple with subject s, predicate p, and object o. This unique triple (s, p, o) can be quoted as the subject or object of multiple other triples, but must be assumed to represent the same thing everywhere it occurs, just like the same IRI p is assumed to represent the same thing everywhere it occurs.

In some situations, however, it might be necessary to distinguish the occurrences of a triple in different graphs. Consider the following sentence: “The triple <http://example.org/s> <http://example.org/p> <http://example.org/o> in (the graph represented by) file1.ttl was added by Alice, and the same triple in file2.ttl was added by Bob.” Note that the words “same triple” in this sentence may be confusing, because although the triple (as an abstract entity) is the same, its respective occurrences are different things, each within a different file and with a different author (this is known, in philosophy and linguistics, as the type-token distinction). As the quoted triple represents a unique thing, adequately conveying the meaning of the sentence above requires additional nodes for representing the two distinct occurrences. One possible solution is illustrated in the following example (using the Turtle-star concrete syntax described in the next section).

4. SPARQL-star Query Language
This Section introduces SPARQL-star, which is an RDF-star-aware extension of the RDF query language SPARQL [SPARQL11-QUERY]; i.e., SPARQL-star can be used to query RDF-star graphs.

Turtle-star

3.2 Turtle-star
In this section, we present Turtle-star, an extension of the Turtle format [TURTLE] allowing the representation of RDF-star graphs. For the sake of conciseness, we only describe here the differences between Turtle-star and Turtle.

3.2.1 Grammar
Turtle-star is defined to follow the same grammar as Turtle, except for the EBNF productions specified below, which replace the productions having the same number (if any) in the original grammar.

[8] objectList ::= object annotation? ( ‘,’ object annotation? )*
[10] subject ::= iri | BlankNode | collection | quotedTriple
[12] object ::= iri | BlankNode | collection | blankNodePropertyList | literal | quotedTriple
[27t] quotedTriple ::= ‘<<‘ qtSubject verb qtObject ‘>>’
[28t] qtSubject ::= iri | BlankNode | quotedTriple
[29t] qtObject ::= iri | BlankNode | literal | quotedTriple
[30t] annotation ::= ‘{|’ predicateObjectList ‘|}’

The complete grammar may be found in § C.1 Turtle-Star EBNF Grammar.

The changes are that subject and object productions have been extended to accept quoted triples, which are described by the new productions 27t to 30t. Note that quoted triples accept a more restricted range of subject and object expressions than asserted triples. Additionally, the objectList production now accepts an optional annotation after each object.

3.2.2 Parsing
A Turtle-star parser is similar to a Turtle parser as defined in Section 7 of the Turtle specification [TURTLE], with an additional item in its state :

RDF-star Term curObject — The curObject is bound to the qtObject production.
Additionally, the curSubject can be bound to any RDF-star term (including a quoted triple).

A Turtle-star document defines an RDF-star graph composed of a set of RDF-star triples. The subject and qtSubject productions set the curSubject. The verb production sets the curPredicate. The object and qtObject productions set the curObject. Finishing the object production, an RDF-star triple curSubject curPredicate curObject is produced (added to the RDF-star graph).

Beginning the quotedTriple production records the curSubject and curPredicate. Finishing the quotedTriple production yields the RDF-star triple curSubject curPredicate curObject and restores the recorded values of curSubject and curPredicate.

Beginning the annotation production records the curSubject and curPredicate, and sets the curSubject to the RDF-star triple curSubject curPredicate curObject. Finishing the annotation production restores the recorded values of curSubject and curPredicate.

All other productions MUST be handled as specified by Section 7 of the Turtle specification [TURTLE], while still applying the changes above recursively.

.2.2.1 Discussion
This section is non-normative.

This section describes parser behavior when parsing a Turtle-star document that contains quoted triples and annotations.

Consider a Turtle-star document that describes an RDF triple, and also uses that triple as a quoted triple as the subject of another RDF-star triple:

EXAMPLE 11: Turtle-star quoted triples
BASE <http://example.org/>
PREFIX : <#>
_:a :name “Alice” .
<< _:a :name “Alice” >> :statedBy :bob .
The usual process of parsing a Turtle document applies with the addition of matching the quoted triple << _:a :name “Alice” >> as part of the subject production. The resulting RDF-star graph consists of two RDF-star triples:

(b, http://example.org/#name, “Alice”), where b is a blank node
((b, http://example.org/#name, “Alice”), http://example.org/#statedBy, http://example.org/#bob/), where b is the same blank node
Because the above example includes the triple (b, http://example.org/#name, “Alice”) as an asserted triple, the same RDF-star graph may also be represented by using the Turtle-star annotation syntax as follows:

EXAMPLE 12: Turtle-star annotated triples
BASE <http://example.org/>
PREFIX : <#>
_:a :name “Alice” {| :statedBy :bob |} .
In this case, the objectList production matches the annotation production on {| :source :bob |} after parsing the object production on “Alice”. At this point, the curSubject, curPredicate, and curObject are saved, and a new RDF-star triple _:a :name “Alice” is created and used as curSubject while processing the annotation production.

C.1 Turtle-Star EBNF Grammar

The following is a complete grammar for Turtle-Star. The EBNF used here is defined in XML 1.0 [EBNF-NOTATION].

[1] turtleDoc ::= statement*
[2] statement ::= directive | ( triples “.”)
[3] directive ::= prefixID | base | sparqlPrefix | sparqlBase
[4] prefixID ::= “@prefix” PNAME_NS IRIREF “.”?
[5] base ::= “@base” IRIREF “.”?
[5s] sparqlPrefix ::= “PREFIX” PNAME_NS IRIREF
[6s] sparqlBase ::= “BASE” IRIREF
[6] triples ::= ( subject predicateObjectList) | ( blankNodePropertyList predicateObjectList? )
[7] predicateObjectList ::= verb objectList ( “;” ( verb objectList) ? ) *
[8] objectList ::= object annotation? ( “,” object annotation? ) *
[9] verb ::= predicate | “a”
[10] subject ::= iri | BlankNode | collection | quotedTriple
[11] predicate ::= iri
[12] object ::= iri | BlankNode | collection | blankNodePropertyList | literal | quotedTriple
[13] literal ::= RDFLiteral | NumericLiteral | BooleanLiteral
[14] blankNodePropertyList ::= “[” predicateObjectList “]”
[15] collection ::= “(” object* “)”
[16] NumericLiteral ::= INTEGER | DECIMAL | DOUBLE
[128s] RDFLiteral ::= String ( LANGTAG | ( “^^” iri) ) ?
[133s] BooleanLiteral ::= “true” | “false”
[17] String ::= STRING_LITERAL_QUOTE | STRING_LITERAL_SINGLE_QUOTE | STRING_LITERAL_LONG_SINGLE_QUOTE | STRING_LITERAL_LONG_QUOTE
[135s] iri ::= IRIREF | PrefixedName
[136s] PrefixedName ::= PNAME_LN | PNAME_NS
[137s] BlankNode ::= BLANK_NODE_LABEL | ANON
[27] quotedTriple ::= “<<” qtSubject predicate qtObject “>>”
[28] qtSubject ::= iri | BlankNode | quotedTriple
[29] qtObject ::= iri | BlankNode | literal | quotedTriple
[30] annotation ::= “{|” predicateObjectList “|}”
@terminals # Productions for terminals
[18] IRIREF ::= “<” ( [ ^#x00-#x20<>”{}|^`\] | UCHAR) * “>”
[139s] PNAME_NS ::= PN_PREFIX? “:”
[140s] PNAME_LN ::= PNAME_NS PN_LOCAL
[141s] BLANK_NODE_LABEL ::= “_:” ( PN_CHARS_U | [ 0-9] ) ( ( PN_CHARS | “.”) * PN_CHARS) ?
[144s] LANGTAG ::= “@” [ a-zA-Z] + ( “-” [ a-zA-Z0-9] + ) *
[19] INTEGER ::= [ +-] ? [ 0-9] +
[20] DECIMAL ::= [ +-] ? ( [ 0-9] * “.” [ 0-9] + )
[21] DOUBLE ::= [ +-] ? ( ( [ 0-9] + “.” [ 0-9] * EXPONENT) | ( “.” [ 0-9] + EXPONENT) | ( [ 0-9] + EXPONENT) )
[154s] EXPONENT ::= [ eE] [ +-] ? [ 0-9] +
[22] STRING_LITERAL_QUOTE ::= ‘”‘ ( [ ^>”#x5C#x0A#x0D] | ECHAR | UCHAR) * ‘”‘
[23] STRING_LITERAL_SINGLE_QUOTE ::= “‘” ( [ ^#x27#x5C#x0A#x0D] | ECHAR | UCHAR) * “‘”
[24] STRING_LITERAL_LONG_SINGLE_QUOTE ::= “”’” ( ( “‘” | “””) ? ( [ ^’\] | ECHAR | UCHAR) ) * “”’”
[25] STRING_LITERAL_LONG_QUOTE ::= ‘”””‘ ( ( ‘”‘ | ‘””‘) ? ( [ ^”\] | ECHAR | UCHAR) ) * ‘”””‘
[26] UCHAR ::= ( “\u” HEX HEX HEX HEX) | ( “\U” HEX HEX HEX HEX HEX HEX HEX HEX)
[159s] ECHAR ::= “\” [ tbnrf\”‘]
[161s] WS ::= #x20 | #x09 | #x0D | #x0A
[162s] ANON ::= “[” WS* “]”
[163s] PN_CHARS_BASE ::= [ A-Z]
| [ a-z]
| [ #xC0-#xD6]
| [ #xD8-#xF6]
| [ #xF8-#x02FF]
| [ #x0370-#x037D]
| [ #x037F-#x1FFF]
| [ #x200C-#x200D]
| [ #x2070-#x218F]
| [ #x2C00-#x2FEF]
| [ #x3001-#xD7FF]
| [ #xF900-#xFDCF]
| [ #xFDF0-#xFFFD]
| [ #x00010000-#x000EFFFF]
[164s] PN_CHARS_U ::= PN_CHARS_BASE | “_”
[166s] PN_CHARS ::= PN_CHARS_U | “-” | [ 0-9] | #xB7 | [ #x0300-#x036F] | [ #x203F-#x2040]
[167s] PN_PREFIX ::= PN_CHARS_BASE ( ( PN_CHARS | “.”) * PN_CHARS) ?
[168s] PN_LOCAL ::= ( PN_CHARS_U | “:” | [ 0-9] | PLX) ( ( PN_CHARS | “.” | “:” | PLX) * ( PN_CHARS | “:” | PLX) ) ?
[169s] PLX ::= PERCENT | PN_LOCAL_ESC
[170s] PERCENT ::= “%” HEX HEX
[171s] HEX ::= [ 0-9] | [ A-F] | [ a-f]
[172s] PN_LOCAL_ESC ::= “\” ( “_” | “~” | “.” | “-” | “!” | “$” | “&” | “‘” | “(” | “)” | “*” | “+” | “,” | “;” | “=” | “/” | “?” | “#” | “@” | “%”)

TriG-star

3.3 TriG-star
This section describes TriG-star, a minimal extension of the TriG format [TRIG] using the same production updates described in § 3.2 Turtle-star.

A TriG-star document defines an RDF-star dataset, composed of a single default graph and zero or more named graphs, all of which are RDF-star graphs.

3.3.1 Grammar
TriG-star is defined to follow the same grammar as TriG, except for the EBNF productions specified below, which replace the productions having the same number (if any) in the original grammar.

The TriG-star grammar contains exactly the same production updates described in § 3.2.1 Grammar with an additional change to the triplesOrGraph production.

[3g] triplesOrGraph ::= labelOrSubject ( wrappedGraph | predicateObjectList ‘.’ )
| quotedTriple predicateObjectList ‘.’
[8] objectList ::= object annotation? ( ‘,’ object annotation? )*
[10] subject ::= iri | BlankNode | collection | quotedTriple
[12] object ::= iri | BlankNode | collection | blankNodePropertyList | literal | quotedTriple
[27t] quotedTriple ::= ‘<<‘ qtSubject verb qtObject ‘>>’
[28t] qtSubject ::= iri | BlankNode | quotedTriple
[29t] qtObject ::= iri | BlankNode | literal | quotedTriple
[30t] annotation ::= ‘{|’ predicateObjectList ‘|}’
NOTE
The complete grammar may be found in § C.2 TriG-Star EBNF Grammar.

3.3.2 Parsing
TriG-star parsing uses the same updates described in § 3.2.2 Parsing as applied to Section 5 of the TriG specification [TRIG].

NOTE
As with Turtle-star, the quotedTriple and annotation are used to set either the curSubject or curObject, and do not directly add the associated quoted triple to curGraph. Subsequent productions which use either curSubject or curObject may result in adding triples to curGraph.

A conforming TriG-star parser MUST parse any valid TriG document and any valid Turtle-star document in addition to the Turtle-star grammar productions contained within a named graph.

3.3.3 Discussion
This section is non-normative.

TriG-star allows the same expressivity as Turtle-star with the addition of allowing quoted triples and annotations within named graphs.

EXAMPLE 13: TriG-star annotated triples
BASE <http://example.org/>
PREFIX : <#>
:G {
_:a :name “Alice” {| :statedBy :bob |} .
}
The resulting RDF-star dataset consists of an empty default graph, and a graph named http://example.org/#G with two RDF-star triples:

(b, http://example.org/#name, “Alice”), where b is a blank node
((b, http://example.org/#name, “Alice”), http://example.org/#statedBy, http://example.org/#bob/), where b is the same blank node

C.2 TriG-Star EBNF Grammar

The following is a complete grammar for TriG-Star. The EBNF used here is defined in XML 1.0 [EBNF-NOTATION].

[1g] trigDoc ::= ( directive | block) *
[2g] block ::= triplesOrGraph | wrappedGraph | triples2 | ( “GRAPH” labelOrSubject wrappedGraph)
[3g] triplesOrGraph ::= ( labelOrSubject ( wrappedGraph | ( predicateObjectList “.”) ) ) | ( quotedTriple predicateObjectList “.”)
[4g] triples2 ::= ( blankNodePropertyList predicateObjectList? “.”) | ( collection predicateObjectList “.”)
[5g] wrappedGraph ::= “{” triplesBlock? “}”
[6g] triplesBlock ::= triples ( “.” triplesBlock? ) ?
[7g] labelOrSubject ::= iri | BlankNode
[3] directive ::= prefixID | base | sparqlPrefix | sparqlBase
[4] prefixID ::= “@prefix” PNAME_NS IRIREF “.”?
[5] base ::= “@base” IRIREF “.”?
[5s] sparqlPrefix ::= “PREFIX” PNAME_NS IRIREF
[6s] sparqlBase ::= “BASE” IRIREF
[6] triples ::= ( subject predicateObjectList) | ( blankNodePropertyList predicateObjectList? )
[7] predicateObjectList ::= verb objectList ( “;” ( verb objectList) ? ) *
[8] objectList ::= object annotation? ( “,” object annotation? ) *
[9] verb ::= predicate | “a”
[10] subject ::= iri | blank | quotedTriple
[11] predicate ::= iri
[12] object ::= iri | blank | blankNodePropertyList | literal | quotedTriple
[13] literal ::= RDFLiteral | NumericLiteral | BooleanLiteral
[14] blank ::= BlankNode | collection
[15] blankNodePropertyList ::= “[” predicateObjectList “]”
[16] collection ::= “(” object* “)”
[17] NumericLiteral ::= INTEGER | DECIMAL | DOUBLE
[128s] RDFLiteral ::= String ( LANGTAG | ( “^^” iri) ) ?
[133s] BooleanLiteral ::= “true” | “false”
[18] String ::= STRING_LITERAL_QUOTE | STRING_LITERAL_SINGLE_QUOTE | STRING_LITERAL_LONG_SINGLE_QUOTE | STRING_LITERAL_LONG_QUOTE
[135s] iri ::= IRIREF | PrefixedName
[136s] PrefixedName ::= PNAME_LN | PNAME_NS
[137s] BlankNode ::= BLANK_NODE_LABEL | ANON
[27] quotedTriple ::= “<<” qtSubject predicate qtObject “>>”
[28] qtSubject ::= iri | BlankNode | quotedTriple
[29] qtObject ::= iri | BlankNode | literal | quotedTriple
[30] annotation ::= “{|” predicateObjectList “|}”
@terminals # Productions for terminals
[19] IRIREF ::= “<” ( [ ^#x00-#x20<>”{}|^`\] | UCHAR) * “>”
[139s] PNAME_NS ::= PN_PREFIX? “:”
[140s] PNAME_LN ::= PNAME_NS PN_LOCAL
[141s] BLANK_NODE_LABEL ::= “_:” ( PN_CHARS_U | [ 0-9] ) ( ( PN_CHARS | “.”) * PN_CHARS) ?
[144s] LANGTAG ::= “@” [ a-zA-Z] + ( “-” [ a-zA-Z0-9] + ) *
[20] INTEGER ::= [ +-] ? [ 0-9] +
[21] DECIMAL ::= [ +-] ? ( [ 0-9] * “.” [ 0-9] + )
[22] DOUBLE ::= [ +-] ? ( ( [ 0-9] + “.” [ 0-9] * EXPONENT) | ( “.” [ 0-9] + EXPONENT) | ( [ 0-9] + EXPONENT) )
[154s] EXPONENT ::= [ eE] [ +-] ? [ 0-9] +
[23] STRING_LITERAL_QUOTE ::= ‘”‘ ( [ ^>”#x5C#x0A#x0D] | ECHAR | UCHAR) * ‘”‘
[24] STRING_LITERAL_SINGLE_QUOTE ::= “‘” ( [ ^#x27#x5C#x0A#x0D] | ECHAR | UCHAR) * “‘”
[25] STRING_LITERAL_LONG_SINGLE_QUOTE ::= “”’” ( ( “‘” | “””) ? ( [ ^’\] | ECHAR | UCHAR) ) * “”’”
[26] STRING_LITERAL_LONG_QUOTE ::= ‘”””‘ ( ( ‘”‘ | ‘””‘) ? ( [ ^”\] | ECHAR | UCHAR) ) * ‘”””‘
[27] UCHAR ::= ( “\u” HEX HEX HEX HEX) | ( “\U” HEX HEX HEX HEX HEX HEX HEX HEX)
[159s] ECHAR ::= “\” [ tbnrf\”‘]
[160s] NIL ::= “(” WS* “)”
[161s] WS ::= #x20 | #x09 | #x0D | #x0A
[162s] ANON ::= “[” WS* “]”
[163s] PN_CHARS_BASE ::= [ A-Z]
| [ a-z]
| [ #xC0-#xD6]
| [ #xD8-#xF6]
| [ #xF8-#x02FF]
| [ #x0370-#x037D]
| [ #x037F-#x1FFF]
| [ #x200C-#x200D]
| [ #x2070-#x218F]
| [ #x2C00-#x2FEF]
| [ #x3001-#xD7FF]
| [ #xF900-#xFDCF]
| [ #xFDF0-#xFFFD]
| [ #x00010000-#x000EFFFF]
[164s] PN_CHARS_U ::= PN_CHARS_BASE | “_”
[166s] PN_CHARS ::= PN_CHARS_U | “-” | [ 0-9] | #xB7 | [ #x0300-#x036F] | [ #x203F-#x2040]
[167s] PN_PREFIX ::= PN_CHARS_BASE ( ( PN_CHARS | “.”) * PN_CHARS) ?
[168s] PN_LOCAL ::= ( PN_CHARS_U | “:” | [ 0-9] | PLX) ( ( PN_CHARS | “.” | “:” | PLX) * ( PN_CHARS | “:” | PLX) ) ?
[169s] PLX ::= PERCENT | PN_LOCAL_ESC
[170s] PERCENT ::= “%” HEX HEX
[171s] HEX ::= [ 0-9] | [ A-F] | [ a-f]
[172s] PN_LOCAL_ESC ::= “\” ( “_” | “~” | “.” | “-” | “!” | “$” | “&” | “‘” | “(” | “)” | “*” | “+” | “,” | “;” | “=” | “/” | “?” | “#” | “@” | “%”)