123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- %include {
- /** @brief Lemon parser grammar for Turtle.
- *
- * The `lemon' parser generator executable must be in your PATH:
- * https://sqlite.org/src/doc/trunk/doc/lemon.html
- *
- * TTL EBNF: https://www.w3.org/TeamSubmission/turtle/#sec-grammar-grammar
- */
- #include "volksdata/codec.h"
- }
- %name TTLParse
- %stack_overflow {
- log_error ("Stack oveflow in TTL parsing.");
- state->rc = VOLK_MEM_ERR;
- }
- %parse_failure {
- log_error ("TTL parse error. Cannot continue.");
- state->rc = VOLK_PARSE_ERR;
- }
- %syntax_error {
- // Fail immediately on first error.
- yy_parse_failed (yypParser);
- }
- //%stack_size 1024
- %token_prefix "T_"
- %token_type { char * }
- %token_destructor { (void) state; free ($$); }
- %default_type { char * }
- %extra_argument { VOLK_TTLParserState *state }
- // Low- to high-priority.
- %left PERIOD .
- %left SEMICOLON .
- %left COMMA .
- %left STRING INTEGER DOUBLE DECIMAL BOOLEAN QNAME BNODE_ID IRIREF .
- %nonassoc LANGTAG PREFIX .
- %nonassoc COLON .
- /*
- * Rules.
- */
- turtleDoc ::= statements EOF .
- statements ::= statements statement .
- statements ::= .
- statement ::= prefixID .
- statement ::= base .
- statement ::= triples .
- statement ::= WS .
- prefixID ::= PREFIX(P) WS IRIREF(N) PERIOD . {
- VOLK_nsmap_add (P, N);
- free (P);
- free (N);
- }
- base ::= BASE WS IRIREF(D) PERIOD . {
- VOLK_term_free (state->base);
- state->base = VOLK_iriref_new (D);
- free (D);
- }
- triples ::= subject(S) ows predObjList(L) PERIOD . {
- size_t ct = VOLK_graph_add_link_map (state->it, L);
- state->ct += ct;
- state->rc = VOLK_OK;
- LOG_TRACE("Added %lu triples.", ct);
- VOLK_term_free (S);
- VOLK_link_map_free (L);
- }
- triples ::= subject(S) ows predObjList(L) SEMICOLON PERIOD . [PERIOD] {
- size_t ct = VOLK_graph_add_link_map (state->it, L);
- state->ct += ct;
- state->rc = VOLK_OK;
- LOG_TRACE("Added %lu triples.", ct);
- VOLK_term_free (S);
- VOLK_link_map_free (L);
- }
- %type predObjList { VOLK_LinkMap * }
- %destructor predObjList { VOLK_link_map_free ($$); }
- predObjList(A) ::= predicate(P) ows objectList(O) . [SEMICOLON] {
- A = VOLK_link_map_new (state->lms, VOLK_LINK_OUTBOUND);
- VOLK_link_map_add (A, P, O);
- }
- predObjList(A) ::= predObjList(L) SEMICOLON predicate(P) ows objectList(O) . {
- VOLK_link_map_add (L, P, O);
- A = L;
- }
- %type objectList { VOLK_TermSet * }
- %destructor objectList { VOLK_term_set_free ($$); }
- objectList(A) ::= objectList(L) COMMA object(O) . {
- if (VOLK_term_set_add (L, O, NULL) == VOLK_NOACTION)
- VOLK_term_free (O);
- A = L;
- }
- objectList(A) ::= object(O) . [IRIREF] {
- A = VOLK_term_set_new();
- VOLK_term_set_add (A, O, NULL);
- }
- %type subject { VOLK_Term * }
- %destructor subject { VOLK_term_free ($$); }
- subject ::= resource(D) . { state->lms = D; }
- subject ::= blank(D) . { state->lms = D; }
- %type predicate { VOLK_Term * }
- %destructor predicate { VOLK_term_free ($$); }
- predicate ::= resource .
- predicate(A)::= RDF_TYPE . { A = VOLK_iriref_new_ns ("rdf:type"); }
- %type object { VOLK_Term * }
- %destructor object { VOLK_term_free ($$); }
- object ::= resource .
- object ::= blank .
- object ::= literal .
- %type literal { VOLK_Term * }
- %destructor literal { VOLK_term_free ($$); }
- literal(A) ::= STRING(D) . {
- A = VOLK_literal_new (D, NULL);
- LOG_TRACE("Created plain literal: \"%s\"", A->data);
- free (D);
- }
- literal(A) ::= STRING(D) LANGTAG(L) . {
- A = VOLK_lt_literal_new (D, L);
- LOG_TRACE("Created LT-literal: \"%s\"@%s", A->data, A->lang);
- free (D);
- free (L);
- }
- literal(A) ::= STRING(D) DTYPE_MARKER resource(M) . {
- A = VOLK_literal_new (D, M);
- LOG_TRACE(
- "Created DT-literal: \"%s\"^^%s",
- A->data, A->datatype);
- free (D);
- }
- literal(A) ::= INTEGER(D) . {
- A = VOLK_literal_new (D, VOLK_iriref_new_ns ("xsd:integer"));
- free (D);
- }
- literal(A) ::= DOUBLE(D) . {
- A = VOLK_literal_new (D, VOLK_iriref_new_ns ("xsd:double"));
- free (D);
- }
- literal(A) ::= DECIMAL(D) . {
- A = VOLK_literal_new (D, VOLK_iriref_new_ns ("xsd:decimal"));
- free (D);
- }
- literal(A) ::= BOOLEAN(D) . {
- A = VOLK_literal_new (D, VOLK_iriref_new_ns ("xsd:boolean"));
- free (D);
- }
- %type blank { VOLK_Term * }
- %destructor blank { VOLK_term_free ($$); }
- blank(A) ::= BNODE_ID(D) . {
- A = VOLK_bnode_new (D);
- LOG_TRACE("Created blank node: _:%s", A->data);
- free (D);
- }
- blank(A) ::= LBRACKET RBRACKET . [BNODE_ID] {
- A = VOLK_bnode_new (NULL);
- LOG_TRACE("Created empty list BN: _:%s", A->data);
- }
- blank(A) ::= LBRACKET predObjList(L) RBRACKET . [BNODE_ID] {
- A = VOLK_bnode_new (NULL);
- state->lms = A;
- state->ct += VOLK_graph_add_link_map (state->it, L);
- LOG_TRACE("Created list BN: _:%s", A->data);
- VOLK_link_map_free (L);
- }
- blank ::= collection . [BNODE_ID]
- blank(A) ::= LPAREN RPAREN . [BNODE_ID] {
- A = VOLK_iriref_new_ns ("rdf:nil");
- LOG_TRACE("Created list terminator: %s", A->data);
- }
- // "collection" is the subject of the first collection item.
- %type collection { VOLK_Term * }
- %destructor collection { VOLK_term_free ($$); }
- // Collection triples are added here to the graph.
- collection(A) ::= LPAREN itemList(L) RPAREN . {
- A = VOLK_bnode_add_collection (state->it, L);
- VOLK_term_set_free (L);
- }
- %type itemList { VOLK_TermSet * }
- %destructor itemList { VOLK_term_set_free ($$); }
- itemList(A) ::= itemList(L) ows object(O) . {
- if (VOLK_term_set_add (L, O, NULL) == VOLK_NOACTION)
- VOLK_term_free (O);
- A = L;
- }
- itemList(A) ::= object(O) . {
- A = VOLK_term_set_new ();
- VOLK_term_set_add (A, O, NULL);
- }
- %type resource { VOLK_Term * }
- %destructor resource { VOLK_term_free ($$); }
- resource(A) ::= IRIREF(D) . {
- VOLK_Term *rel_iri = VOLK_iriref_new (D);
- free (D);
- if (state->base) {
- A = VOLK_iriref_new_abs (rel_iri, state->base);
- VOLK_term_free (rel_iri);
- } else {
- A = rel_iri;
- }
- LOG_TRACE("Created IRI: <%s>", A->data);
- }
- resource(A) ::= QNAME(D) . {
- A = VOLK_iriref_new_ns (D);
- LOG_TRACE("Created IRI: %s", A->data);
- free (D);
- }
- ows ::= WS .
- ows ::= .
|