parser.py 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567
  1. """
  2. SPARQL 1.1 Parser
  3. based on pyparsing
  4. """
  5. from __future__ import annotations # noqa: I001
  6. import re
  7. import sys
  8. from typing import Any, BinaryIO, List
  9. from typing import Optional as OptionalType
  10. from typing import TextIO, Tuple, Union
  11. from pyparsing import CaselessKeyword as Keyword # watch out :)
  12. from pyparsing import (
  13. Combine,
  14. Forward,
  15. Group,
  16. Literal,
  17. OneOrMore,
  18. Optional,
  19. ParseResults,
  20. Regex,
  21. Suppress,
  22. ZeroOrMore,
  23. )
  24. import rdflib
  25. from rdflib.compat import decodeUnicodeEscape
  26. from . import operators as op
  27. from .pyparsing_compat import DelimitedList, combine_join_kwargs, rest_of_line
  28. from .parserutils import Comp, CompValue, Param, ParamList
  29. # from pyparsing import Keyword as CaseSensitiveKeyword
  30. DEBUG = False
  31. # ---------------- ACTIONS
  32. def neg(literal: rdflib.Literal) -> rdflib.Literal:
  33. return rdflib.Literal(-literal, datatype=literal.datatype)
  34. def setLanguage(terms: Tuple[Any, OptionalType[str]]) -> rdflib.Literal:
  35. return rdflib.Literal(terms[0], lang=terms[1])
  36. def setDataType(terms: Tuple[Any, OptionalType[str]]) -> rdflib.Literal:
  37. return rdflib.Literal(terms[0], datatype=terms[1])
  38. def expandTriples(terms: ParseResults) -> List[Any]:
  39. """
  40. Expand ; and , syntax for repeat predicates, subjects
  41. """
  42. # import pdb; pdb.set_trace()
  43. last_subject, last_predicate = None, None # Used for ; and ,
  44. try:
  45. res: List[Any] = []
  46. if DEBUG:
  47. print("Terms", terms)
  48. l_ = len(terms)
  49. for i, t in enumerate(terms):
  50. if t == ",":
  51. res.extend([last_subject, last_predicate])
  52. elif t == ";":
  53. if i + 1 == len(terms) or terms[i + 1] == ";" or terms[i + 1] == ".":
  54. continue # this semicolon is spurious
  55. res.append(last_subject)
  56. elif isinstance(t, list):
  57. # BlankNodePropertyList
  58. # is this bnode the object of previous triples?
  59. if (len(res) % 3) == 2:
  60. res.append(t[0])
  61. # is this a single [] ?
  62. if len(t) > 1:
  63. res += t # Don't update last_subject/last_predicate
  64. # is this bnode the subject of more triples?
  65. if i + 1 < l_ and terms[i + 1] not in [
  66. ".",
  67. ",",
  68. ";",
  69. ]: # term might not be a string
  70. last_subject, last_predicate = t[0], None
  71. res.append(t[0])
  72. elif isinstance(t, ParseResults):
  73. res += t.as_list()
  74. elif t != ".":
  75. res.append(t)
  76. if (len(res) % 3) == 1:
  77. last_subject = t
  78. elif (len(res) % 3) == 2:
  79. last_predicate = t
  80. if DEBUG:
  81. print(len(res), t)
  82. if DEBUG:
  83. import json
  84. print(json.dumps(res, indent=2))
  85. return res
  86. # print res
  87. # assert len(res)%3 == 0, \
  88. # "Length of triple-list is not divisible by 3: %d!"%len(res)
  89. # return [tuple(res[i:i+3]) for i in range(len(res)/3)]
  90. except:
  91. if DEBUG:
  92. import traceback
  93. traceback.print_exc()
  94. raise
  95. def expandBNodeTriples(terms: ParseResults) -> List[Any]:
  96. """
  97. expand [ ?p ?o ] syntax for implicit bnodes
  98. """
  99. # import pdb; pdb.set_trace()
  100. try:
  101. if DEBUG:
  102. print("Bnode terms", terms)
  103. print("1", terms[0])
  104. print("2", [rdflib.BNode()] + terms.as_list()[0])
  105. return [expandTriples([rdflib.BNode()] + terms.as_list()[0])]
  106. except Exception as e:
  107. if DEBUG:
  108. print(">>>>>>>>", e)
  109. raise
  110. def expandCollection(terms: ParseResults) -> List[List[Any]]:
  111. """
  112. expand ( 1 2 3 ) notation for collections
  113. """
  114. if DEBUG:
  115. print("Collection: ", terms)
  116. res: List[Any] = []
  117. other = []
  118. for x in terms:
  119. if isinstance(x, list): # is this a [ .. ] ?
  120. other += x
  121. x = x[0]
  122. b = rdflib.BNode()
  123. if res:
  124. res += [res[-3], rdflib.RDF.rest, b, b, rdflib.RDF.first, x]
  125. else:
  126. res += [b, rdflib.RDF.first, x]
  127. res += [b, rdflib.RDF.rest, rdflib.RDF.nil]
  128. res += other
  129. if DEBUG:
  130. print("CollectionOut", res)
  131. return [res]
  132. # SPARQL Grammar from http://www.w3.org/TR/sparql11-query/#grammar
  133. # ------ TERMINALS --------------
  134. # [139] IRIREF ::= '<' ([^<>"{}|^`\]-[#x00-#x20])* '>'
  135. IRIREF = Combine(
  136. Suppress("<")
  137. + Regex(r'[^<>"{}|^`\\%s]*' % "".join("\\x%02X" % i for i in range(33)))
  138. + Suppress(">")
  139. )
  140. IRIREF.set_parse_action(lambda x: rdflib.URIRef(x[0]))
  141. # [164] P_CHARS_BASE ::= [A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
  142. if sys.maxunicode == 0xFFFF:
  143. # this is narrow python build (default on windows/osx)
  144. # this means that unicode code points over 0xffff are stored
  145. # as several characters, which in turn means that regex character
  146. # ranges with these characters do not work.
  147. # See
  148. # * http://bugs.python.org/issue12729
  149. # * http://bugs.python.org/issue12749
  150. # * http://bugs.python.org/issue3665
  151. #
  152. # Here we simple skip the [#x10000-#xEFFFF] part
  153. # this means that some SPARQL queries will not parse :(
  154. # We *could* generate a new regex with \U00010000|\U00010001 ...
  155. # but it would be quite long :)
  156. #
  157. # in py3.3 this is fixed
  158. PN_CHARS_BASE_re = "A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD"
  159. else:
  160. # wide python build
  161. PN_CHARS_BASE_re = "A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\U00010000-\U000EFFFF"
  162. # [165] PN_CHARS_U ::= PN_CHARS_BASE | '_'
  163. PN_CHARS_U_re = "_" + PN_CHARS_BASE_re
  164. # [167] PN_CHARS ::= PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040]
  165. PN_CHARS_re = "\\-0-9\u00B7\u0300-\u036F\u203F-\u2040" + PN_CHARS_U_re
  166. # PN_CHARS = Regex(u'[%s]'%PN_CHARS_re, flags=re.U)
  167. # [168] PN_PREFIX ::= PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)?
  168. PN_PREFIX = Regex(
  169. "[%s](?:[%s\\.]*[%s])?" % (PN_CHARS_BASE_re, PN_CHARS_re, PN_CHARS_re), flags=re.U
  170. )
  171. # [140] PNAME_NS ::= PN_PREFIX? ':'
  172. PNAME_NS = Optional(Param("prefix", PN_PREFIX)) + Suppress(":").leave_whitespace()
  173. # [173] PN_LOCAL_ESC ::= '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )
  174. PN_LOCAL_ESC_re = "\\\\[_~\\.\\-!$&\"'()*+,;=/?#@%]"
  175. # PN_LOCAL_ESC = Regex(PN_LOCAL_ESC_re) # regex'd
  176. # PN_LOCAL_ESC.set_parse_action(lambda x: x[0][1:])
  177. # [172] HEX ::= [0-9] | [A-F] | [a-f]
  178. # HEX = Regex('[0-9A-Fa-f]') # not needed
  179. # [171] PERCENT ::= '%' HEX HEX
  180. PERCENT_re = "%[0-9a-fA-F]{2}"
  181. # PERCENT = Regex(PERCENT_re) # regex'd
  182. # PERCENT.set_parse_action(lambda x: chr(int(x[0][1:], 16)))
  183. # [170] PLX ::= PERCENT | PN_LOCAL_ESC
  184. PLX_re = "(%s|%s)" % (PN_LOCAL_ESC_re, PERCENT_re)
  185. # PLX = PERCENT | PN_LOCAL_ESC # regex'd
  186. # [169] PN_LOCAL ::= (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )?
  187. PN_LOCAL = Regex(
  188. """([%(PN_CHARS_U)s:0-9]|%(PLX)s)
  189. (([%(PN_CHARS)s\\.:]|%(PLX)s)*
  190. ([%(PN_CHARS)s:]|%(PLX)s) )?"""
  191. % dict(PN_CHARS_U=PN_CHARS_U_re, PN_CHARS=PN_CHARS_re, PLX=PLX_re),
  192. flags=re.X | re.UNICODE,
  193. )
  194. # [141] PNAME_LN ::= PNAME_NS PN_LOCAL
  195. PNAME_LN = PNAME_NS + Param("localname", PN_LOCAL.leave_whitespace())
  196. # [142] BLANK_NODE_LABEL ::= '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?
  197. BLANK_NODE_LABEL = Regex(
  198. "_:[0-9%s](?:[\\.%s]*[%s])?" % (PN_CHARS_U_re, PN_CHARS_re, PN_CHARS_re),
  199. flags=re.U,
  200. )
  201. BLANK_NODE_LABEL.set_parse_action(lambda x: rdflib.BNode(x[0][2:]))
  202. # [166] VARNAME ::= ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )*
  203. VARNAME = Regex(
  204. "[%s0-9][%s0-9\u00B7\u0300-\u036F\u203F-\u2040]*" % (PN_CHARS_U_re, PN_CHARS_U_re),
  205. flags=re.U,
  206. )
  207. # [143] VAR1 ::= '?' VARNAME
  208. VAR1 = Combine(Suppress("?") + VARNAME)
  209. # [144] VAR2 ::= '$' VARNAME
  210. VAR2 = Combine(Suppress("$") + VARNAME)
  211. # [145] LANGTAG ::= '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)*
  212. LANGTAG = Combine(Suppress("@") + Regex("[a-zA-Z]+(?:-[a-zA-Z0-9]+)*"))
  213. # [146] INTEGER ::= [0-9]+
  214. INTEGER = Regex(r"[0-9]+")
  215. # INTEGER.set_results_name('integer')
  216. INTEGER.set_parse_action(lambda x: rdflib.Literal(x[0], datatype=rdflib.XSD.integer))
  217. # [155] EXPONENT ::= [eE] [+-]? [0-9]+
  218. EXPONENT_re = "[eE][+-]?[0-9]+"
  219. # [147] DECIMAL ::= [0-9]* '.' [0-9]+
  220. DECIMAL = Regex(r"[0-9]*\.[0-9]+") # (?![eE])
  221. # DECIMAL.set_results_name('decimal')
  222. DECIMAL.set_parse_action(lambda x: rdflib.Literal(x[0], datatype=rdflib.XSD.decimal))
  223. # [148] DOUBLE ::= [0-9]+ '.' [0-9]* EXPONENT | '.' ([0-9])+ EXPONENT | ([0-9])+ EXPONENT
  224. DOUBLE = Regex(r"[0-9]+\.[0-9]*%(e)s|\.([0-9])+%(e)s|[0-9]+%(e)s" % {"e": EXPONENT_re})
  225. # DOUBLE.set_results_name('double')
  226. DOUBLE.set_parse_action(lambda x: rdflib.Literal(x[0], datatype=rdflib.XSD.double))
  227. # [149] INTEGER_POSITIVE ::= '+' INTEGER
  228. INTEGER_POSITIVE = Suppress("+") + INTEGER.copy().leave_whitespace()
  229. INTEGER_POSITIVE.set_parse_action(
  230. lambda x: rdflib.Literal("+" + x[0], datatype=rdflib.XSD.integer)
  231. )
  232. # [150] DECIMAL_POSITIVE ::= '+' DECIMAL
  233. DECIMAL_POSITIVE = Suppress("+") + DECIMAL.copy().leave_whitespace()
  234. # [151] DOUBLE_POSITIVE ::= '+' DOUBLE
  235. DOUBLE_POSITIVE = Suppress("+") + DOUBLE.copy().leave_whitespace()
  236. # [152] INTEGER_NEGATIVE ::= '-' INTEGER
  237. INTEGER_NEGATIVE = Suppress("-") + INTEGER.copy().leave_whitespace()
  238. INTEGER_NEGATIVE.set_parse_action(lambda x: neg(x[0]))
  239. # [153] DECIMAL_NEGATIVE ::= '-' DECIMAL
  240. DECIMAL_NEGATIVE = Suppress("-") + DECIMAL.copy().leave_whitespace()
  241. DECIMAL_NEGATIVE.set_parse_action(lambda x: neg(x[0]))
  242. # [154] DOUBLE_NEGATIVE ::= '-' DOUBLE
  243. DOUBLE_NEGATIVE = Suppress("-") + DOUBLE.copy().leave_whitespace()
  244. DOUBLE_NEGATIVE.set_parse_action(lambda x: neg(x[0]))
  245. # [160] ECHAR ::= '\' [tbnrf\"']
  246. # ECHAR = Regex('\\\\[tbnrf"\']')
  247. # [158] STRING_LITERAL_LONG1 ::= "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR ) )* "'''"
  248. # STRING_LITERAL_LONG1 = Literal("'''") + ( Optional( Literal("'") | "''"
  249. # ) + ZeroOrMore( ~ Literal("'\\") | ECHAR ) ) + "'''"
  250. STRING_LITERAL_LONG1 = Regex("'''((?:'|'')?(?:[^'\\\\]|\\\\['ntbrf\\\\]))*'''")
  251. STRING_LITERAL_LONG1.set_parse_action(
  252. lambda x: rdflib.Literal(decodeUnicodeEscape(x[0][3:-3]))
  253. )
  254. # [159] STRING_LITERAL_LONG2 ::= '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR ) )* '"""'
  255. # STRING_LITERAL_LONG2 = Literal('"""') + ( Optional( Literal('"') | '""'
  256. # ) + ZeroOrMore( ~ Literal('"\\') | ECHAR ) ) + '"""'
  257. STRING_LITERAL_LONG2 = Regex('"""(?:(?:"|"")?(?:[^"\\\\]|\\\\["ntbrf\\\\]))*"""')
  258. STRING_LITERAL_LONG2.set_parse_action(
  259. lambda x: rdflib.Literal(decodeUnicodeEscape(x[0][3:-3]))
  260. )
  261. # [156] STRING_LITERAL1 ::= "'" ( ([^#x27#x5C#xA#xD]) | ECHAR )* "'"
  262. # STRING_LITERAL1 = Literal("'") + ZeroOrMore(
  263. # Regex(u'[^\u0027\u005C\u000A\u000D]',flags=re.U) | ECHAR ) + "'"
  264. STRING_LITERAL1 = Regex("'(?:[^'\\n\\r\\\\]|\\\\['ntbrf\\\\])*'(?!')", flags=re.U)
  265. STRING_LITERAL1.set_parse_action(
  266. lambda x: rdflib.Literal(decodeUnicodeEscape(x[0][1:-1]))
  267. )
  268. # [157] STRING_LITERAL2 ::= '"' ( ([^#x22#x5C#xA#xD]) | ECHAR )* '"'
  269. # STRING_LITERAL2 = Literal('"') + ZeroOrMore (
  270. # Regex(u'[^\u0022\u005C\u000A\u000D]',flags=re.U) | ECHAR ) + '"'
  271. STRING_LITERAL2 = Regex('"(?:[^"\\n\\r\\\\]|\\\\["ntbrf\\\\])*"(?!")', flags=re.U)
  272. STRING_LITERAL2.set_parse_action(
  273. lambda x: rdflib.Literal(decodeUnicodeEscape(x[0][1:-1]))
  274. )
  275. # [161] NIL ::= '(' WS* ')'
  276. NIL = Literal("(") + ")"
  277. NIL.set_parse_action(lambda x: rdflib.RDF.nil)
  278. # [162] WS ::= #x20 | #x9 | #xD | #xA
  279. # Not needed?
  280. # WS = #x20 | #x9 | #xD | #xA
  281. # [163] ANON ::= '[' WS* ']'
  282. ANON = Literal("[") + "]"
  283. ANON.set_parse_action(lambda x: rdflib.BNode())
  284. # A = CaseSensitiveKeyword('a')
  285. A = Literal("a")
  286. A.set_parse_action(lambda x: rdflib.RDF.type)
  287. # ------ NON-TERMINALS --------------
  288. # [5] BaseDecl ::= 'BASE' IRIREF
  289. BaseDecl = Comp("Base", Keyword("BASE") + Param("iri", IRIREF))
  290. # [6] PrefixDecl ::= 'PREFIX' PNAME_NS IRIREF
  291. PrefixDecl = Comp("PrefixDecl", Keyword("PREFIX") + PNAME_NS + Param("iri", IRIREF))
  292. # [4] Prologue ::= ( BaseDecl | PrefixDecl )*
  293. Prologue = Group(ZeroOrMore(BaseDecl | PrefixDecl))
  294. # [108] Var ::= VAR1 | VAR2
  295. Var = VAR1 | VAR2
  296. Var.set_parse_action(lambda x: rdflib.term.Variable(x[0]))
  297. # [137] PrefixedName ::= PNAME_LN | PNAME_NS
  298. PrefixedName = Comp("pname", PNAME_LN | PNAME_NS)
  299. # [136] iri ::= IRIREF | PrefixedName
  300. iri = IRIREF | PrefixedName
  301. # [135] String ::= STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2
  302. String = STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2 | STRING_LITERAL1 | STRING_LITERAL2
  303. # [129] RDFLiteral ::= String ( LANGTAG | ( '^^' iri ) )?
  304. RDFLiteral = Comp(
  305. "literal",
  306. Param("string", String)
  307. + Optional(
  308. Param("lang", LANGTAG.leave_whitespace())
  309. | Literal("^^").leave_whitespace() + Param("datatype", iri).leave_whitespace()
  310. ),
  311. )
  312. # [132] NumericLiteralPositive ::= INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE
  313. NumericLiteralPositive = DOUBLE_POSITIVE | DECIMAL_POSITIVE | INTEGER_POSITIVE
  314. # [133] NumericLiteralNegative ::= INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE
  315. NumericLiteralNegative = DOUBLE_NEGATIVE | DECIMAL_NEGATIVE | INTEGER_NEGATIVE
  316. # [131] NumericLiteralUnsigned ::= INTEGER | DECIMAL | DOUBLE
  317. NumericLiteralUnsigned = DOUBLE | DECIMAL | INTEGER
  318. # [130] NumericLiteral ::= NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative
  319. NumericLiteral = (
  320. NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative
  321. )
  322. # [134] BooleanLiteral ::= 'true' | 'false'
  323. BooleanLiteral = Keyword("true").set_parse_action(
  324. lambda: rdflib.Literal(True)
  325. ) | Keyword("false").set_parse_action(lambda: rdflib.Literal(False))
  326. # [138] BlankNode ::= BLANK_NODE_LABEL | ANON
  327. BlankNode = BLANK_NODE_LABEL | ANON
  328. # [109] GraphTerm ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL
  329. GraphTerm = iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL
  330. # [106] VarOrTerm ::= Var | GraphTerm
  331. VarOrTerm = Var | GraphTerm
  332. # [107] VarOrIri ::= Var | iri
  333. VarOrIri = Var | iri
  334. # [46] GraphRef ::= 'GRAPH' iri
  335. GraphRef = Keyword("GRAPH") + Param("graphiri", iri)
  336. # [47] GraphRefAll ::= GraphRef | 'DEFAULT' | 'NAMED' | 'ALL'
  337. GraphRefAll = (
  338. GraphRef
  339. | Param("graphiri", Keyword("DEFAULT"))
  340. | Param("graphiri", Keyword("NAMED"))
  341. | Param("graphiri", Keyword("ALL"))
  342. )
  343. # [45] GraphOrDefault ::= 'DEFAULT' | 'GRAPH'? iri
  344. GraphOrDefault = ParamList("graph", Keyword("DEFAULT")) | Optional(
  345. Keyword("GRAPH")
  346. ) + ParamList("graph", iri)
  347. # [65] DataBlockValue ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF'
  348. DataBlockValue = iri | RDFLiteral | NumericLiteral | BooleanLiteral | Keyword("UNDEF")
  349. # [78] Verb ::= VarOrIri | A
  350. Verb = VarOrIri | A
  351. # [85] VerbSimple ::= Var
  352. VerbSimple = Var
  353. # [97] Integer ::= INTEGER
  354. Integer = INTEGER
  355. TriplesNode = Forward()
  356. TriplesNodePath = Forward()
  357. # [104] GraphNode ::= VarOrTerm | TriplesNode
  358. GraphNode = VarOrTerm | TriplesNode
  359. # [105] GraphNodePath ::= VarOrTerm | TriplesNodePath
  360. GraphNodePath = VarOrTerm | TriplesNodePath
  361. # [93] PathMod ::= '?' | '*' | '+'
  362. PathMod = Literal("?") | "*" | "+"
  363. # [96] PathOneInPropertySet ::= iri | A | '^' ( iri | A )
  364. PathOneInPropertySet = iri | A | Comp("InversePath", "^" + (iri | A))
  365. Path = Forward()
  366. # [95] PathNegatedPropertySet ::= PathOneInPropertySet | '(' ( PathOneInPropertySet ( '|' PathOneInPropertySet )* )? ')'
  367. PathNegatedPropertySet = Comp(
  368. "PathNegatedPropertySet",
  369. ParamList("part", PathOneInPropertySet)
  370. | "("
  371. + Optional(
  372. ParamList("part", PathOneInPropertySet)
  373. + ZeroOrMore("|" + ParamList("part", PathOneInPropertySet))
  374. )
  375. + ")",
  376. )
  377. # [94] PathPrimary ::= iri | A | '!' PathNegatedPropertySet | '(' Path ')' | 'DISTINCT' '(' Path ')'
  378. PathPrimary = (
  379. iri
  380. | A
  381. | Suppress("!") + PathNegatedPropertySet
  382. | Suppress("(") + Path + Suppress(")")
  383. | Comp("DistinctPath", Keyword("DISTINCT") + "(" + Param("part", Path) + ")")
  384. )
  385. # [91] PathElt ::= PathPrimary Optional(PathMod)
  386. PathElt = Comp(
  387. "PathElt",
  388. Param("part", PathPrimary) + Optional(Param("mod", PathMod.leave_whitespace())),
  389. )
  390. # [92] PathEltOrInverse ::= PathElt | '^' PathElt
  391. PathEltOrInverse = PathElt | Suppress("^") + Comp(
  392. "PathEltOrInverse", Param("part", PathElt)
  393. )
  394. # [90] PathSequence ::= PathEltOrInverse ( '/' PathEltOrInverse )*
  395. PathSequence = Comp(
  396. "PathSequence",
  397. ParamList("part", PathEltOrInverse)
  398. + ZeroOrMore("/" + ParamList("part", PathEltOrInverse)),
  399. )
  400. # [89] PathAlternative ::= PathSequence ( '|' PathSequence )*
  401. PathAlternative = Comp(
  402. "PathAlternative",
  403. ParamList("part", PathSequence) + ZeroOrMore("|" + ParamList("part", PathSequence)),
  404. )
  405. # [88] Path ::= PathAlternative
  406. Path <<= PathAlternative
  407. # [84] VerbPath ::= Path
  408. VerbPath = Path
  409. # [87] ObjectPath ::= GraphNodePath
  410. ObjectPath = GraphNodePath
  411. # [86] ObjectListPath ::= ObjectPath ( ',' ObjectPath )*
  412. ObjectListPath = ObjectPath + ZeroOrMore("," + ObjectPath)
  413. GroupGraphPattern = Forward()
  414. # [102] Collection ::= '(' OneOrMore(GraphNode) ')'
  415. Collection = Suppress("(") + OneOrMore(GraphNode) + Suppress(")")
  416. Collection.set_parse_action(expandCollection)
  417. # [103] CollectionPath ::= '(' OneOrMore(GraphNodePath) ')'
  418. CollectionPath = Suppress("(") + OneOrMore(GraphNodePath) + Suppress(")")
  419. CollectionPath.set_parse_action(expandCollection)
  420. # [80] Object ::= GraphNode
  421. Object = GraphNode
  422. # [79] ObjectList ::= Object ( ',' Object )*
  423. ObjectList = Object + ZeroOrMore("," + Object)
  424. # [83] PropertyListPathNotEmpty ::= ( VerbPath | VerbSimple ) ObjectListPath ( ';' ( ( VerbPath | VerbSimple ) ObjectList )? )*
  425. PropertyListPathNotEmpty = (
  426. (VerbPath | VerbSimple)
  427. + ObjectListPath
  428. + ZeroOrMore(";" + Optional((VerbPath | VerbSimple) + ObjectListPath))
  429. )
  430. # [82] PropertyListPath ::= Optional(PropertyListPathNotEmpty)
  431. PropertyListPath = Optional(PropertyListPathNotEmpty)
  432. # [77] PropertyListNotEmpty ::= Verb ObjectList ( ';' ( Verb ObjectList )? )*
  433. PropertyListNotEmpty = Verb + ObjectList + ZeroOrMore(";" + Optional(Verb + ObjectList))
  434. # [76] PropertyList ::= Optional(PropertyListNotEmpty)
  435. PropertyList = Optional(PropertyListNotEmpty)
  436. # [99] BlankNodePropertyList ::= '[' PropertyListNotEmpty ']'
  437. BlankNodePropertyList = Group(Suppress("[") + PropertyListNotEmpty + Suppress("]"))
  438. BlankNodePropertyList.set_parse_action(expandBNodeTriples)
  439. # [101] BlankNodePropertyListPath ::= '[' PropertyListPathNotEmpty ']'
  440. BlankNodePropertyListPath = Group(
  441. Suppress("[") + PropertyListPathNotEmpty + Suppress("]")
  442. )
  443. BlankNodePropertyListPath.set_parse_action(expandBNodeTriples)
  444. # [98] TriplesNode ::= Collection | BlankNodePropertyList
  445. TriplesNode <<= Collection | BlankNodePropertyList
  446. # [100] TriplesNodePath ::= CollectionPath | BlankNodePropertyListPath
  447. TriplesNodePath <<= CollectionPath | BlankNodePropertyListPath
  448. # [75] TriplesSameSubject ::= VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList
  449. TriplesSameSubject = VarOrTerm + PropertyListNotEmpty | TriplesNode + PropertyList
  450. TriplesSameSubject.set_parse_action(expandTriples)
  451. # [52] TriplesTemplate ::= TriplesSameSubject ( '.' TriplesTemplate? )?
  452. # NOTE: pyparsing.py handling of recursive rules is limited by python's recursion
  453. # limit.
  454. # (https://docs.python.org/3/library/sys.html#sys.setrecursionlimit)
  455. # To accommodate arbitrary amounts of triples this rule is rewritten to not be
  456. # recursive:
  457. # [52*] TriplesTemplate ::= TriplesSameSubject ( '.' TriplesSameSubject? )*
  458. TriplesTemplate = ParamList("triples", TriplesSameSubject) + ZeroOrMore(
  459. Suppress(".") + Optional(ParamList("triples", TriplesSameSubject))
  460. )
  461. # [51] QuadsNotTriples ::= 'GRAPH' VarOrIri '{' Optional(TriplesTemplate) '}'
  462. QuadsNotTriples = Comp(
  463. "QuadsNotTriples",
  464. Keyword("GRAPH") + Param("term", VarOrIri) + "{" + Optional(TriplesTemplate) + "}",
  465. )
  466. # [50] Quads ::= Optional(TriplesTemplate) ( QuadsNotTriples '.'? Optional(TriplesTemplate) )*
  467. Quads = Comp(
  468. "Quads",
  469. Optional(TriplesTemplate)
  470. + ZeroOrMore(
  471. ParamList("quadsNotTriples", QuadsNotTriples)
  472. + Optional(Suppress("."))
  473. + Optional(TriplesTemplate)
  474. ),
  475. )
  476. # [48] QuadPattern ::= '{' Quads '}'
  477. QuadPattern = "{" + Param("quads", Quads) + "}"
  478. # [49] QuadData ::= '{' Quads '}'
  479. QuadData = "{" + Param("quads", Quads) + "}"
  480. # [81] TriplesSameSubjectPath ::= VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath
  481. TriplesSameSubjectPath = (
  482. VarOrTerm + PropertyListPathNotEmpty | TriplesNodePath + PropertyListPath
  483. )
  484. TriplesSameSubjectPath.set_parse_action(expandTriples)
  485. # [55] TriplesBlock ::= TriplesSameSubjectPath ( '.' Optional(TriplesBlock) )?
  486. TriplesBlock = Forward()
  487. TriplesBlock <<= ParamList("triples", TriplesSameSubjectPath) + Optional(
  488. Suppress(".") + Optional(TriplesBlock)
  489. )
  490. # [66] MinusGraphPattern ::= 'MINUS' GroupGraphPattern
  491. MinusGraphPattern = Comp(
  492. "MinusGraphPattern", Keyword("MINUS") + Param("graph", GroupGraphPattern)
  493. )
  494. # [67] GroupOrUnionGraphPattern ::= GroupGraphPattern ( 'UNION' GroupGraphPattern )*
  495. GroupOrUnionGraphPattern = Comp(
  496. "GroupOrUnionGraphPattern",
  497. ParamList("graph", GroupGraphPattern)
  498. + ZeroOrMore(Keyword("UNION") + ParamList("graph", GroupGraphPattern)),
  499. )
  500. Expression = Forward()
  501. # [72] ExpressionList ::= NIL | '(' Expression ( ',' Expression )* ')'
  502. ExpressionList = NIL | Group(Suppress("(") + DelimitedList(Expression) + Suppress(")"))
  503. # [122] RegexExpression ::= 'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')'
  504. RegexExpression = Comp(
  505. "Builtin_REGEX",
  506. Keyword("REGEX")
  507. + "("
  508. + Param("text", Expression)
  509. + ","
  510. + Param("pattern", Expression)
  511. + Optional("," + Param("flags", Expression))
  512. + ")",
  513. )
  514. RegexExpression.setEvalFn(op.Builtin_REGEX)
  515. # [123] SubstringExpression ::= 'SUBSTR' '(' Expression ',' Expression ( ',' Expression )? ')'
  516. SubstringExpression = Comp(
  517. "Builtin_SUBSTR",
  518. Keyword("SUBSTR")
  519. + "("
  520. + Param("arg", Expression)
  521. + ","
  522. + Param("start", Expression)
  523. + Optional("," + Param("length", Expression))
  524. + ")",
  525. ).setEvalFn(op.Builtin_SUBSTR)
  526. # [124] StrReplaceExpression ::= 'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')'
  527. StrReplaceExpression = Comp(
  528. "Builtin_REPLACE",
  529. Keyword("REPLACE")
  530. + "("
  531. + Param("arg", Expression)
  532. + ","
  533. + Param("pattern", Expression)
  534. + ","
  535. + Param("replacement", Expression)
  536. + Optional("," + Param("flags", Expression))
  537. + ")",
  538. ).setEvalFn(op.Builtin_REPLACE)
  539. # [125] ExistsFunc ::= 'EXISTS' GroupGraphPattern
  540. ExistsFunc = Comp(
  541. "Builtin_EXISTS", Keyword("EXISTS") + Param("graph", GroupGraphPattern)
  542. ).setEvalFn(op.Builtin_EXISTS)
  543. # [126] NotExistsFunc ::= 'NOT' 'EXISTS' GroupGraphPattern
  544. NotExistsFunc = Comp(
  545. "Builtin_NOTEXISTS",
  546. Keyword("NOT") + Keyword("EXISTS") + Param("graph", GroupGraphPattern),
  547. ).setEvalFn(op.Builtin_EXISTS)
  548. # [127] Aggregate ::= 'COUNT' '(' 'DISTINCT'? ( '*' | Expression ) ')'
  549. # | 'SUM' '(' Optional('DISTINCT') Expression ')'
  550. # | 'MIN' '(' Optional('DISTINCT') Expression ')'
  551. # | 'MAX' '(' Optional('DISTINCT') Expression ')'
  552. # | 'AVG' '(' Optional('DISTINCT') Expression ')'
  553. # | 'SAMPLE' '(' Optional('DISTINCT') Expression ')'
  554. # | 'GROUP_CONCAT' '(' Optional('DISTINCT') Expression ( ';' 'SEPARATOR' '=' String )? ')'
  555. _Distinct = Optional(Keyword("DISTINCT"))
  556. _AggregateParams = "(" + Param("distinct", _Distinct) + Param("vars", Expression) + ")"
  557. Aggregate = (
  558. Comp(
  559. "Aggregate_Count",
  560. Keyword("COUNT")
  561. + "("
  562. + Param("distinct", _Distinct)
  563. + Param("vars", "*" | Expression)
  564. + ")",
  565. )
  566. | Comp("Aggregate_Sum", Keyword("SUM") + _AggregateParams)
  567. | Comp("Aggregate_Min", Keyword("MIN") + _AggregateParams)
  568. | Comp("Aggregate_Max", Keyword("MAX") + _AggregateParams)
  569. | Comp("Aggregate_Avg", Keyword("AVG") + _AggregateParams)
  570. | Comp("Aggregate_Sample", Keyword("SAMPLE") + _AggregateParams)
  571. | Comp(
  572. "Aggregate_GroupConcat",
  573. Keyword("GROUP_CONCAT")
  574. + "("
  575. + Param("distinct", _Distinct)
  576. + Param("vars", Expression)
  577. + Optional(";" + Keyword("SEPARATOR") + "=" + Param("separator", String))
  578. + ")",
  579. )
  580. )
  581. # [121] BuiltInCall ::= Aggregate
  582. # | 'STR' '(' + Expression + ')'
  583. # | 'LANG' '(' + Expression + ')'
  584. # | 'LANGMATCHES' '(' + Expression + ',' + Expression + ')'
  585. # | 'DATATYPE' '(' + Expression + ')'
  586. # | 'BOUND' '(' Var ')'
  587. # | 'IRI' '(' + Expression + ')'
  588. # | 'URI' '(' + Expression + ')'
  589. # | 'BNODE' ( '(' + Expression + ')' | NIL )
  590. # | 'RAND' NIL
  591. # | 'ABS' '(' + Expression + ')'
  592. # | 'CEIL' '(' + Expression + ')'
  593. # | 'FLOOR' '(' + Expression + ')'
  594. # | 'ROUND' '(' + Expression + ')'
  595. # | 'CONCAT' ExpressionList
  596. # | SubstringExpression
  597. # | 'STRLEN' '(' + Expression + ')'
  598. # | StrReplaceExpression
  599. # | 'UCASE' '(' + Expression + ')'
  600. # | 'LCASE' '(' + Expression + ')'
  601. # | 'ENCODE_FOR_URI' '(' + Expression + ')'
  602. # | 'CONTAINS' '(' + Expression + ',' + Expression + ')'
  603. # | 'STRSTARTS' '(' + Expression + ',' + Expression + ')'
  604. # | 'STRENDS' '(' + Expression + ',' + Expression + ')'
  605. # | 'STRBEFORE' '(' + Expression + ',' + Expression + ')'
  606. # | 'STRAFTER' '(' + Expression + ',' + Expression + ')'
  607. # | 'YEAR' '(' + Expression + ')'
  608. # | 'MONTH' '(' + Expression + ')'
  609. # | 'DAY' '(' + Expression + ')'
  610. # | 'HOURS' '(' + Expression + ')'
  611. # | 'MINUTES' '(' + Expression + ')'
  612. # | 'SECONDS' '(' + Expression + ')'
  613. # | 'TIMEZONE' '(' + Expression + ')'
  614. # | 'TZ' '(' + Expression + ')'
  615. # | 'NOW' NIL
  616. # | 'UUID' NIL
  617. # | 'STRUUID' NIL
  618. # | 'MD5' '(' + Expression + ')'
  619. # | 'SHA1' '(' + Expression + ')'
  620. # | 'SHA256' '(' + Expression + ')'
  621. # | 'SHA384' '(' + Expression + ')'
  622. # | 'SHA512' '(' + Expression + ')'
  623. # | 'COALESCE' ExpressionList
  624. # | 'IF' '(' Expression ',' Expression ',' Expression ')'
  625. # | 'STRLANG' '(' + Expression + ',' + Expression + ')'
  626. # | 'STRDT' '(' + Expression + ',' + Expression + ')'
  627. # | 'sameTerm' '(' + Expression + ',' + Expression + ')'
  628. # | 'isIRI' '(' + Expression + ')'
  629. # | 'isURI' '(' + Expression + ')'
  630. # | 'isBLANK' '(' + Expression + ')'
  631. # | 'isLITERAL' '(' + Expression + ')'
  632. # | 'isNUMERIC' '(' + Expression + ')'
  633. # | RegexExpression
  634. # | ExistsFunc
  635. # | NotExistsFunc
  636. BuiltInCall = (
  637. Aggregate
  638. | Comp(
  639. "Builtin_STR", Keyword("STR") + "(" + Param("arg", Expression) + ")"
  640. ).setEvalFn(op.Builtin_STR)
  641. | Comp(
  642. "Builtin_LANG", Keyword("LANG") + "(" + Param("arg", Expression) + ")"
  643. ).setEvalFn(op.Builtin_LANG)
  644. | Comp(
  645. "Builtin_LANGMATCHES",
  646. Keyword("LANGMATCHES")
  647. + "("
  648. + Param("arg1", Expression)
  649. + ","
  650. + Param("arg2", Expression)
  651. + ")",
  652. ).setEvalFn(op.Builtin_LANGMATCHES)
  653. | Comp(
  654. "Builtin_DATATYPE", Keyword("DATATYPE") + "(" + Param("arg", Expression) + ")"
  655. ).setEvalFn(op.Builtin_DATATYPE)
  656. | Comp("Builtin_BOUND", Keyword("BOUND") + "(" + Param("arg", Var) + ")").setEvalFn(
  657. op.Builtin_BOUND
  658. )
  659. | Comp(
  660. "Builtin_IRI", Keyword("IRI") + "(" + Param("arg", Expression) + ")"
  661. ).setEvalFn(op.Builtin_IRI)
  662. | Comp(
  663. "Builtin_URI", Keyword("URI") + "(" + Param("arg", Expression) + ")"
  664. ).setEvalFn(op.Builtin_IRI)
  665. | Comp(
  666. "Builtin_BNODE", Keyword("BNODE") + ("(" + Param("arg", Expression) + ")" | NIL)
  667. ).setEvalFn(op.Builtin_BNODE)
  668. | Comp("Builtin_RAND", Keyword("RAND") + NIL).setEvalFn(op.Builtin_RAND)
  669. | Comp(
  670. "Builtin_ABS", Keyword("ABS") + "(" + Param("arg", Expression) + ")"
  671. ).setEvalFn(op.Builtin_ABS)
  672. | Comp(
  673. "Builtin_CEIL", Keyword("CEIL") + "(" + Param("arg", Expression) + ")"
  674. ).setEvalFn(op.Builtin_CEIL)
  675. | Comp(
  676. "Builtin_FLOOR", Keyword("FLOOR") + "(" + Param("arg", Expression) + ")"
  677. ).setEvalFn(op.Builtin_FLOOR)
  678. | Comp(
  679. "Builtin_ROUND", Keyword("ROUND") + "(" + Param("arg", Expression) + ")"
  680. ).setEvalFn(op.Builtin_ROUND)
  681. | Comp(
  682. "Builtin_CONCAT", Keyword("CONCAT") + Param("arg", ExpressionList)
  683. ).setEvalFn(op.Builtin_CONCAT)
  684. | SubstringExpression
  685. | Comp(
  686. "Builtin_STRLEN", Keyword("STRLEN") + "(" + Param("arg", Expression) + ")"
  687. ).setEvalFn(op.Builtin_STRLEN)
  688. | StrReplaceExpression
  689. | Comp(
  690. "Builtin_UCASE", Keyword("UCASE") + "(" + Param("arg", Expression) + ")"
  691. ).setEvalFn(op.Builtin_UCASE)
  692. | Comp(
  693. "Builtin_LCASE", Keyword("LCASE") + "(" + Param("arg", Expression) + ")"
  694. ).setEvalFn(op.Builtin_LCASE)
  695. | Comp(
  696. "Builtin_ENCODE_FOR_URI",
  697. Keyword("ENCODE_FOR_URI") + "(" + Param("arg", Expression) + ")",
  698. ).setEvalFn(op.Builtin_ENCODE_FOR_URI)
  699. | Comp(
  700. "Builtin_CONTAINS",
  701. Keyword("CONTAINS")
  702. + "("
  703. + Param("arg1", Expression)
  704. + ","
  705. + Param("arg2", Expression)
  706. + ")",
  707. ).setEvalFn(op.Builtin_CONTAINS)
  708. | Comp(
  709. "Builtin_STRSTARTS",
  710. Keyword("STRSTARTS")
  711. + "("
  712. + Param("arg1", Expression)
  713. + ","
  714. + Param("arg2", Expression)
  715. + ")",
  716. ).setEvalFn(op.Builtin_STRSTARTS)
  717. | Comp(
  718. "Builtin_STRENDS",
  719. Keyword("STRENDS")
  720. + "("
  721. + Param("arg1", Expression)
  722. + ","
  723. + Param("arg2", Expression)
  724. + ")",
  725. ).setEvalFn(op.Builtin_STRENDS)
  726. | Comp(
  727. "Builtin_STRBEFORE",
  728. Keyword("STRBEFORE")
  729. + "("
  730. + Param("arg1", Expression)
  731. + ","
  732. + Param("arg2", Expression)
  733. + ")",
  734. ).setEvalFn(op.Builtin_STRBEFORE)
  735. | Comp(
  736. "Builtin_STRAFTER",
  737. Keyword("STRAFTER")
  738. + "("
  739. + Param("arg1", Expression)
  740. + ","
  741. + Param("arg2", Expression)
  742. + ")",
  743. ).setEvalFn(op.Builtin_STRAFTER)
  744. | Comp(
  745. "Builtin_YEAR", Keyword("YEAR") + "(" + Param("arg", Expression) + ")"
  746. ).setEvalFn(op.Builtin_YEAR)
  747. | Comp(
  748. "Builtin_MONTH", Keyword("MONTH") + "(" + Param("arg", Expression) + ")"
  749. ).setEvalFn(op.Builtin_MONTH)
  750. | Comp(
  751. "Builtin_DAY", Keyword("DAY") + "(" + Param("arg", Expression) + ")"
  752. ).setEvalFn(op.Builtin_DAY)
  753. | Comp(
  754. "Builtin_HOURS", Keyword("HOURS") + "(" + Param("arg", Expression) + ")"
  755. ).setEvalFn(op.Builtin_HOURS)
  756. | Comp(
  757. "Builtin_MINUTES", Keyword("MINUTES") + "(" + Param("arg", Expression) + ")"
  758. ).setEvalFn(op.Builtin_MINUTES)
  759. | Comp(
  760. "Builtin_SECONDS", Keyword("SECONDS") + "(" + Param("arg", Expression) + ")"
  761. ).setEvalFn(op.Builtin_SECONDS)
  762. | Comp(
  763. "Builtin_TIMEZONE", Keyword("TIMEZONE") + "(" + Param("arg", Expression) + ")"
  764. ).setEvalFn(op.Builtin_TIMEZONE)
  765. | Comp(
  766. "Builtin_TZ", Keyword("TZ") + "(" + Param("arg", Expression) + ")"
  767. ).setEvalFn(op.Builtin_TZ)
  768. | Comp("Builtin_NOW", Keyword("NOW") + NIL).setEvalFn(op.Builtin_NOW)
  769. | Comp("Builtin_UUID", Keyword("UUID") + NIL).setEvalFn(op.Builtin_UUID)
  770. | Comp("Builtin_STRUUID", Keyword("STRUUID") + NIL).setEvalFn(op.Builtin_STRUUID)
  771. | Comp(
  772. "Builtin_MD5", Keyword("MD5") + "(" + Param("arg", Expression) + ")"
  773. ).setEvalFn(op.Builtin_MD5)
  774. | Comp(
  775. "Builtin_SHA1", Keyword("SHA1") + "(" + Param("arg", Expression) + ")"
  776. ).setEvalFn(op.Builtin_SHA1)
  777. | Comp(
  778. "Builtin_SHA256", Keyword("SHA256") + "(" + Param("arg", Expression) + ")"
  779. ).setEvalFn(op.Builtin_SHA256)
  780. | Comp(
  781. "Builtin_SHA384", Keyword("SHA384") + "(" + Param("arg", Expression) + ")"
  782. ).setEvalFn(op.Builtin_SHA384)
  783. | Comp(
  784. "Builtin_SHA512", Keyword("SHA512") + "(" + Param("arg", Expression) + ")"
  785. ).setEvalFn(op.Builtin_SHA512)
  786. | Comp(
  787. "Builtin_COALESCE", Keyword("COALESCE") + Param("arg", ExpressionList)
  788. ).setEvalFn(op.Builtin_COALESCE)
  789. | Comp(
  790. "Builtin_IF",
  791. Keyword("IF")
  792. + "("
  793. + Param("arg1", Expression)
  794. + ","
  795. + Param("arg2", Expression)
  796. + ","
  797. + Param("arg3", Expression)
  798. + ")",
  799. ).setEvalFn(op.Builtin_IF)
  800. | Comp(
  801. "Builtin_STRLANG",
  802. Keyword("STRLANG")
  803. + "("
  804. + Param("arg1", Expression)
  805. + ","
  806. + Param("arg2", Expression)
  807. + ")",
  808. ).setEvalFn(op.Builtin_STRLANG)
  809. | Comp(
  810. "Builtin_STRDT",
  811. Keyword("STRDT")
  812. + "("
  813. + Param("arg1", Expression)
  814. + ","
  815. + Param("arg2", Expression)
  816. + ")",
  817. ).setEvalFn(op.Builtin_STRDT)
  818. | Comp(
  819. "Builtin_sameTerm",
  820. Keyword("sameTerm")
  821. + "("
  822. + Param("arg1", Expression)
  823. + ","
  824. + Param("arg2", Expression)
  825. + ")",
  826. ).setEvalFn(op.Builtin_sameTerm)
  827. | Comp(
  828. "Builtin_isIRI", Keyword("isIRI") + "(" + Param("arg", Expression) + ")"
  829. ).setEvalFn(op.Builtin_isIRI)
  830. | Comp(
  831. "Builtin_isURI", Keyword("isURI") + "(" + Param("arg", Expression) + ")"
  832. ).setEvalFn(op.Builtin_isIRI)
  833. | Comp(
  834. "Builtin_isBLANK", Keyword("isBLANK") + "(" + Param("arg", Expression) + ")"
  835. ).setEvalFn(op.Builtin_isBLANK)
  836. | Comp(
  837. "Builtin_isLITERAL", Keyword("isLITERAL") + "(" + Param("arg", Expression) + ")"
  838. ).setEvalFn(op.Builtin_isLITERAL)
  839. | Comp(
  840. "Builtin_isNUMERIC", Keyword("isNUMERIC") + "(" + Param("arg", Expression) + ")"
  841. ).setEvalFn(op.Builtin_isNUMERIC)
  842. | RegexExpression
  843. | ExistsFunc
  844. | NotExistsFunc
  845. )
  846. # [71] ArgList ::= NIL | '(' 'DISTINCT'? Expression ( ',' Expression )* ')'
  847. ArgList = (
  848. NIL
  849. | "("
  850. + Param("distinct", _Distinct)
  851. + DelimitedList(ParamList("expr", Expression))
  852. + ")"
  853. )
  854. # [128] iriOrFunction ::= iri Optional(ArgList)
  855. iriOrFunction = (
  856. Comp("Function", Param("iri", iri) + ArgList).setEvalFn(op.Function)
  857. ) | iri
  858. # [70] FunctionCall ::= iri ArgList
  859. FunctionCall = Comp("Function", Param("iri", iri) + ArgList).setEvalFn(op.Function)
  860. # [120] BrackettedExpression ::= '(' Expression ')'
  861. BrackettedExpression = Suppress("(") + Expression + Suppress(")")
  862. # [119] PrimaryExpression ::= BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var
  863. PrimaryExpression = (
  864. BrackettedExpression
  865. | BuiltInCall
  866. | iriOrFunction
  867. | RDFLiteral
  868. | NumericLiteral
  869. | BooleanLiteral
  870. | Var
  871. )
  872. # [118] UnaryExpression ::= '!' PrimaryExpression
  873. # | '+' PrimaryExpression
  874. # | '-' PrimaryExpression
  875. # | PrimaryExpression
  876. UnaryExpression = (
  877. Comp("UnaryNot", "!" + Param("expr", PrimaryExpression)).setEvalFn(op.UnaryNot)
  878. | Comp("UnaryPlus", "+" + Param("expr", PrimaryExpression)).setEvalFn(op.UnaryPlus)
  879. | Comp("UnaryMinus", "-" + Param("expr", PrimaryExpression)).setEvalFn(
  880. op.UnaryMinus
  881. )
  882. | PrimaryExpression
  883. )
  884. # [117] MultiplicativeExpression ::= UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )*
  885. MultiplicativeExpression = Comp(
  886. "MultiplicativeExpression",
  887. Param("expr", UnaryExpression)
  888. + ZeroOrMore(
  889. ParamList("op", "*") + ParamList("other", UnaryExpression)
  890. | ParamList("op", "/") + ParamList("other", UnaryExpression)
  891. ),
  892. ).setEvalFn(op.MultiplicativeExpression)
  893. # [116] AdditiveExpression ::= MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )*
  894. # NOTE: The second part of this production is there because:
  895. # "In signed numbers, no white space is allowed between the sign and the number. The AdditiveExpression grammar rule allows for this by covering the two cases of an expression followed by a signed number. These produce an addition or subtraction of the unsigned number as appropriate."
  896. # Here (I think) this is not necessary since pyparsing doesn't separate
  897. # tokenizing and parsing
  898. AdditiveExpression = Comp(
  899. "AdditiveExpression",
  900. Param("expr", MultiplicativeExpression)
  901. + ZeroOrMore(
  902. ParamList("op", "+") + ParamList("other", MultiplicativeExpression)
  903. | ParamList("op", "-") + ParamList("other", MultiplicativeExpression)
  904. ),
  905. ).setEvalFn(op.AdditiveExpression)
  906. # [115] NumericExpression ::= AdditiveExpression
  907. NumericExpression = AdditiveExpression
  908. # [114] RelationalExpression ::= NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )?
  909. RelationalExpression = Comp(
  910. "RelationalExpression",
  911. Param("expr", NumericExpression)
  912. + Optional(
  913. Param("op", "=") + Param("other", NumericExpression)
  914. | Param("op", "!=") + Param("other", NumericExpression)
  915. | Param("op", "<") + Param("other", NumericExpression)
  916. | Param("op", ">") + Param("other", NumericExpression)
  917. | Param("op", "<=") + Param("other", NumericExpression)
  918. | Param("op", ">=") + Param("other", NumericExpression)
  919. | Param("op", Keyword("IN")) + Param("other", ExpressionList)
  920. | Param(
  921. "op",
  922. Combine(
  923. Keyword("NOT") + Keyword("IN"),
  924. adjacent=False,
  925. **combine_join_kwargs(" "),
  926. ),
  927. )
  928. + Param("other", ExpressionList)
  929. ),
  930. ).setEvalFn(op.RelationalExpression)
  931. # [113] ValueLogical ::= RelationalExpression
  932. ValueLogical = RelationalExpression
  933. # [112] ConditionalAndExpression ::= ValueLogical ( '&&' ValueLogical )*
  934. ConditionalAndExpression = Comp(
  935. "ConditionalAndExpression",
  936. Param("expr", ValueLogical) + ZeroOrMore("&&" + ParamList("other", ValueLogical)),
  937. ).setEvalFn(op.ConditionalAndExpression)
  938. # [111] ConditionalOrExpression ::= ConditionalAndExpression ( '||' ConditionalAndExpression )*
  939. ConditionalOrExpression = Comp(
  940. "ConditionalOrExpression",
  941. Param("expr", ConditionalAndExpression)
  942. + ZeroOrMore("||" + ParamList("other", ConditionalAndExpression)),
  943. ).setEvalFn(op.ConditionalOrExpression)
  944. # [110] Expression ::= ConditionalOrExpression
  945. Expression <<= ConditionalOrExpression
  946. # [69] Constraint ::= BrackettedExpression | BuiltInCall | FunctionCall
  947. Constraint = BrackettedExpression | BuiltInCall | FunctionCall
  948. # [68] Filter ::= 'FILTER' Constraint
  949. Filter = Comp("Filter", Keyword("FILTER") + Param("expr", Constraint))
  950. # [16] SourceSelector ::= iri
  951. SourceSelector = iri
  952. # [14] DefaultGraphClause ::= SourceSelector
  953. DefaultGraphClause = SourceSelector
  954. # [15] NamedGraphClause ::= 'NAMED' SourceSelector
  955. NamedGraphClause = Keyword("NAMED") + Param("named", SourceSelector)
  956. # [13] DatasetClause ::= 'FROM' ( DefaultGraphClause | NamedGraphClause )
  957. DatasetClause = Comp(
  958. "DatasetClause",
  959. Keyword("FROM") + (Param("default", DefaultGraphClause) | NamedGraphClause),
  960. )
  961. # [20] GroupCondition ::= BuiltInCall | FunctionCall | '(' Expression ( 'AS' Var )? ')' | Var
  962. GroupCondition = (
  963. BuiltInCall
  964. | FunctionCall
  965. | Comp(
  966. "GroupAs",
  967. "("
  968. + Param("expr", Expression)
  969. + Optional(Keyword("AS") + Param("var", Var))
  970. + ")",
  971. )
  972. | Var
  973. )
  974. # [19] GroupClause ::= 'GROUP' 'BY' GroupCondition+
  975. GroupClause = Comp(
  976. "GroupClause",
  977. Keyword("GROUP")
  978. + Keyword("BY")
  979. + OneOrMore(ParamList("condition", GroupCondition)),
  980. )
  981. _Silent = Optional(Param("silent", Keyword("SILENT")))
  982. # [31] Load ::= 'LOAD' 'SILENT'? iri ( 'INTO' GraphRef )?
  983. Load = Comp(
  984. "Load",
  985. Keyword("LOAD")
  986. + _Silent
  987. + Param("iri", iri)
  988. + Optional(Keyword("INTO") + GraphRef),
  989. )
  990. # [32] Clear ::= 'CLEAR' 'SILENT'? GraphRefAll
  991. Clear = Comp("Clear", Keyword("CLEAR") + _Silent + GraphRefAll)
  992. # [33] Drop ::= 'DROP' _Silent GraphRefAll
  993. Drop = Comp("Drop", Keyword("DROP") + _Silent + GraphRefAll)
  994. # [34] Create ::= 'CREATE' _Silent GraphRef
  995. Create = Comp("Create", Keyword("CREATE") + _Silent + GraphRef)
  996. # [35] Add ::= 'ADD' _Silent GraphOrDefault 'TO' GraphOrDefault
  997. Add = Comp(
  998. "Add", Keyword("ADD") + _Silent + GraphOrDefault + Keyword("TO") + GraphOrDefault
  999. )
  1000. # [36] Move ::= 'MOVE' _Silent GraphOrDefault 'TO' GraphOrDefault
  1001. Move = Comp(
  1002. "Move", Keyword("MOVE") + _Silent + GraphOrDefault + Keyword("TO") + GraphOrDefault
  1003. )
  1004. # [37] Copy ::= 'COPY' _Silent GraphOrDefault 'TO' GraphOrDefault
  1005. Copy = Comp(
  1006. "Copy", Keyword("COPY") + _Silent + GraphOrDefault + Keyword("TO") + GraphOrDefault
  1007. )
  1008. # [38] InsertData ::= 'INSERT DATA' QuadData
  1009. InsertData = Comp("InsertData", Keyword("INSERT") + Keyword("DATA") + QuadData)
  1010. # [39] DeleteData ::= 'DELETE DATA' QuadData
  1011. DeleteData = Comp("DeleteData", Keyword("DELETE") + Keyword("DATA") + QuadData)
  1012. # [40] DeleteWhere ::= 'DELETE WHERE' QuadPattern
  1013. DeleteWhere = Comp("DeleteWhere", Keyword("DELETE") + Keyword("WHERE") + QuadPattern)
  1014. # [42] DeleteClause ::= 'DELETE' QuadPattern
  1015. DeleteClause = Comp("DeleteClause", Keyword("DELETE") + QuadPattern)
  1016. # [43] InsertClause ::= 'INSERT' QuadPattern
  1017. InsertClause = Comp("InsertClause", Keyword("INSERT") + QuadPattern)
  1018. # [44] UsingClause ::= 'USING' ( iri | 'NAMED' iri )
  1019. UsingClause = Comp(
  1020. "UsingClause",
  1021. Keyword("USING") + (Param("default", iri) | Keyword("NAMED") + Param("named", iri)),
  1022. )
  1023. # [41] Modify ::= ( 'WITH' iri )? ( DeleteClause Optional(InsertClause) | InsertClause ) ZeroOrMore(UsingClause) 'WHERE' GroupGraphPattern
  1024. Modify = Comp(
  1025. "Modify",
  1026. Optional(Keyword("WITH") + Param("withClause", iri))
  1027. + (
  1028. Param("delete", DeleteClause) + Optional(Param("insert", InsertClause))
  1029. | Param("insert", InsertClause)
  1030. )
  1031. + ZeroOrMore(ParamList("using", UsingClause))
  1032. + Keyword("WHERE")
  1033. + Param("where", GroupGraphPattern),
  1034. )
  1035. # [30] Update1 ::= Load | Clear | Drop | Add | Move | Copy | Create | InsertData | DeleteData | DeleteWhere | Modify
  1036. Update1 = (
  1037. Load
  1038. | Clear
  1039. | Drop
  1040. | Add
  1041. | Move
  1042. | Copy
  1043. | Create
  1044. | InsertData
  1045. | DeleteData
  1046. | DeleteWhere
  1047. | Modify
  1048. )
  1049. # [63] InlineDataOneVar ::= Var '{' ZeroOrMore(DataBlockValue) '}'
  1050. InlineDataOneVar = (
  1051. ParamList("var", Var) + "{" + ZeroOrMore(ParamList("value", DataBlockValue)) + "}"
  1052. )
  1053. # [64] InlineDataFull ::= ( NIL | '(' ZeroOrMore(Var) ')' ) '{' ( '(' ZeroOrMore(DataBlockValue) ')' | NIL )* '}'
  1054. InlineDataFull = (
  1055. (NIL | "(" + ZeroOrMore(ParamList("var", Var)) + ")")
  1056. + "{"
  1057. + ZeroOrMore(
  1058. ParamList(
  1059. "value",
  1060. Group(Suppress("(") + ZeroOrMore(DataBlockValue) + Suppress(")") | NIL),
  1061. )
  1062. )
  1063. + "}"
  1064. )
  1065. # [62] DataBlock ::= InlineDataOneVar | InlineDataFull
  1066. DataBlock = InlineDataOneVar | InlineDataFull
  1067. # [28] ValuesClause ::= ( 'VALUES' DataBlock )?
  1068. ValuesClause = Optional(
  1069. Param("valuesClause", Comp("ValuesClause", Keyword("VALUES") + DataBlock))
  1070. )
  1071. # [74] ConstructTriples ::= TriplesSameSubject ( '.' Optional(ConstructTriples) )?
  1072. ConstructTriples = Forward()
  1073. ConstructTriples <<= ParamList("template", TriplesSameSubject) + Optional(
  1074. Suppress(".") + Optional(ConstructTriples)
  1075. )
  1076. # [73] ConstructTemplate ::= '{' Optional(ConstructTriples) '}'
  1077. ConstructTemplate = Suppress("{") + Optional(ConstructTriples) + Suppress("}")
  1078. # [57] OptionalGraphPattern ::= 'OPTIONAL' GroupGraphPattern
  1079. OptionalGraphPattern = Comp(
  1080. "OptionalGraphPattern", Keyword("OPTIONAL") + Param("graph", GroupGraphPattern)
  1081. )
  1082. # [58] GraphGraphPattern ::= 'GRAPH' VarOrIri GroupGraphPattern
  1083. GraphGraphPattern = Comp(
  1084. "GraphGraphPattern",
  1085. Keyword("GRAPH") + Param("term", VarOrIri) + Param("graph", GroupGraphPattern),
  1086. )
  1087. # [59] ServiceGraphPattern ::= 'SERVICE' _Silent VarOrIri GroupGraphPattern
  1088. ServiceGraphPattern = Comp(
  1089. "ServiceGraphPattern",
  1090. Keyword("SERVICE")
  1091. + _Silent
  1092. + Param("term", VarOrIri)
  1093. + Param("graph", GroupGraphPattern),
  1094. )
  1095. # [60] Bind ::= 'BIND' '(' Expression 'AS' Var ')'
  1096. Bind = Comp(
  1097. "Bind",
  1098. Keyword("BIND")
  1099. + "("
  1100. + Param("expr", Expression)
  1101. + Keyword("AS")
  1102. + Param("var", Var)
  1103. + ")",
  1104. )
  1105. # [61] InlineData ::= 'VALUES' DataBlock
  1106. InlineData = Comp("InlineData", Keyword("VALUES") + DataBlock)
  1107. # [56] GraphPatternNotTriples ::= GroupOrUnionGraphPattern | OptionalGraphPattern | MinusGraphPattern | GraphGraphPattern | ServiceGraphPattern | Filter | Bind | InlineData
  1108. GraphPatternNotTriples = (
  1109. GroupOrUnionGraphPattern
  1110. | OptionalGraphPattern
  1111. | MinusGraphPattern
  1112. | GraphGraphPattern
  1113. | ServiceGraphPattern
  1114. | Filter
  1115. | Bind
  1116. | InlineData
  1117. )
  1118. # [54] GroupGraphPatternSub ::= Optional(TriplesBlock) ( GraphPatternNotTriples '.'? Optional(TriplesBlock) )*
  1119. GroupGraphPatternSub = Comp(
  1120. "GroupGraphPatternSub",
  1121. Optional(ParamList("part", Comp("TriplesBlock", TriplesBlock)))
  1122. + ZeroOrMore(
  1123. ParamList("part", GraphPatternNotTriples)
  1124. + Optional(".")
  1125. + Optional(ParamList("part", Comp("TriplesBlock", TriplesBlock)))
  1126. ),
  1127. )
  1128. # ----------------
  1129. # [22] HavingCondition ::= Constraint
  1130. HavingCondition = Constraint
  1131. # [21] HavingClause ::= 'HAVING' HavingCondition+
  1132. HavingClause = Comp(
  1133. "HavingClause",
  1134. Keyword("HAVING") + OneOrMore(ParamList("condition", HavingCondition)),
  1135. )
  1136. # [24] OrderCondition ::= ( ( 'ASC' | 'DESC' ) BrackettedExpression )
  1137. # | ( Constraint | Var )
  1138. OrderCondition = Comp(
  1139. "OrderCondition",
  1140. Param("order", Keyword("ASC") | Keyword("DESC"))
  1141. + Param("expr", BrackettedExpression)
  1142. | Param("expr", Constraint | Var),
  1143. )
  1144. # [23] OrderClause ::= 'ORDER' 'BY' OneOrMore(OrderCondition)
  1145. OrderClause = Comp(
  1146. "OrderClause",
  1147. Keyword("ORDER")
  1148. + Keyword("BY")
  1149. + OneOrMore(ParamList("condition", OrderCondition)),
  1150. )
  1151. # [26] LimitClause ::= 'LIMIT' INTEGER
  1152. LimitClause = Keyword("LIMIT") + Param("limit", INTEGER)
  1153. # [27] OffsetClause ::= 'OFFSET' INTEGER
  1154. OffsetClause = Keyword("OFFSET") + Param("offset", INTEGER)
  1155. # [25] LimitOffsetClauses ::= LimitClause Optional(OffsetClause) | OffsetClause Optional(LimitClause)
  1156. LimitOffsetClauses = Comp(
  1157. "LimitOffsetClauses",
  1158. LimitClause + Optional(OffsetClause) | OffsetClause + Optional(LimitClause),
  1159. )
  1160. # [18] SolutionModifier ::= GroupClause? HavingClause? OrderClause? LimitOffsetClauses?
  1161. SolutionModifier = (
  1162. Optional(Param("groupby", GroupClause))
  1163. + Optional(Param("having", HavingClause))
  1164. + Optional(Param("orderby", OrderClause))
  1165. + Optional(Param("limitoffset", LimitOffsetClauses))
  1166. )
  1167. # [9] SelectClause ::= 'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
  1168. SelectClause = (
  1169. Keyword("SELECT")
  1170. + Optional(Param("modifier", Keyword("DISTINCT") | Keyword("REDUCED")))
  1171. + (
  1172. OneOrMore(
  1173. ParamList(
  1174. "projection",
  1175. Comp(
  1176. "vars",
  1177. Param("var", Var)
  1178. | (
  1179. Literal("(")
  1180. + Param("expr", Expression)
  1181. + Keyword("AS")
  1182. + Param("evar", Var)
  1183. + ")"
  1184. ),
  1185. ),
  1186. )
  1187. )
  1188. | "*"
  1189. )
  1190. )
  1191. # [17] WhereClause ::= 'WHERE'? GroupGraphPattern
  1192. WhereClause = Optional(Keyword("WHERE")) + Param("where", GroupGraphPattern)
  1193. # [8] SubSelect ::= SelectClause WhereClause SolutionModifier ValuesClause
  1194. SubSelect = Comp(
  1195. "SubSelect", SelectClause + WhereClause + SolutionModifier + ValuesClause
  1196. )
  1197. # [53] GroupGraphPattern ::= '{' ( SubSelect | GroupGraphPatternSub ) '}'
  1198. GroupGraphPattern <<= Suppress("{") + (SubSelect | GroupGraphPatternSub) + Suppress("}")
  1199. # [7] SelectQuery ::= SelectClause DatasetClause* WhereClause SolutionModifier
  1200. SelectQuery = Comp(
  1201. "SelectQuery",
  1202. SelectClause
  1203. + ZeroOrMore(ParamList("datasetClause", DatasetClause))
  1204. + WhereClause
  1205. + SolutionModifier
  1206. + ValuesClause,
  1207. )
  1208. # [10] ConstructQuery ::= 'CONSTRUCT' ( ConstructTemplate DatasetClause* WhereClause SolutionModifier | DatasetClause* 'WHERE' '{' TriplesTemplate? '}' SolutionModifier )
  1209. # NOTE: The CONSTRUCT WHERE alternative has unnecessarily many Comp/Param pairs
  1210. # to allow it to through the same algebra translation process
  1211. ConstructQuery = Comp(
  1212. "ConstructQuery",
  1213. Keyword("CONSTRUCT")
  1214. + (
  1215. ConstructTemplate
  1216. + ZeroOrMore(ParamList("datasetClause", DatasetClause))
  1217. + WhereClause
  1218. + SolutionModifier
  1219. + ValuesClause
  1220. | ZeroOrMore(ParamList("datasetClause", DatasetClause))
  1221. + Keyword("WHERE")
  1222. + "{"
  1223. + Optional(
  1224. Param(
  1225. "where",
  1226. Comp(
  1227. "FakeGroupGraphPatten",
  1228. ParamList("part", Comp("TriplesBlock", TriplesTemplate)),
  1229. ),
  1230. )
  1231. )
  1232. + "}"
  1233. + SolutionModifier
  1234. + ValuesClause
  1235. ),
  1236. )
  1237. # [12] AskQuery ::= 'ASK' DatasetClause* WhereClause SolutionModifier
  1238. AskQuery = Comp(
  1239. "AskQuery",
  1240. Keyword("ASK")
  1241. + ZeroOrMore(ParamList("datasetClause", DatasetClause))
  1242. + WhereClause
  1243. + SolutionModifier
  1244. + ValuesClause,
  1245. )
  1246. # [11] DescribeQuery ::= 'DESCRIBE' ( VarOrIri+ | '*' ) DatasetClause* WhereClause? SolutionModifier
  1247. DescribeQuery = Comp(
  1248. "DescribeQuery",
  1249. Keyword("DESCRIBE")
  1250. + (OneOrMore(ParamList("var", VarOrIri)) | "*")
  1251. + ZeroOrMore(ParamList("datasetClause", DatasetClause))
  1252. + Optional(WhereClause)
  1253. + SolutionModifier
  1254. + ValuesClause,
  1255. )
  1256. # [29] Update ::= Prologue ( Update1 ( ';' Update )? )?
  1257. Update = Forward()
  1258. Update <<= ParamList("prologue", Prologue) + Optional(
  1259. ParamList("request", Update1) + Optional(";" + Update)
  1260. )
  1261. # [2] Query ::= Prologue
  1262. # ( SelectQuery | ConstructQuery | DescribeQuery | AskQuery )
  1263. # ValuesClause
  1264. # NOTE: ValuesClause was moved to individual queries
  1265. Query = Prologue + (SelectQuery | ConstructQuery | DescribeQuery | AskQuery)
  1266. # [3] UpdateUnit ::= Update
  1267. UpdateUnit = Comp("Update", Update)
  1268. # [1] QueryUnit ::= Query
  1269. QueryUnit = Query
  1270. QueryUnit.ignore("#" + rest_of_line)
  1271. UpdateUnit.ignore("#" + rest_of_line)
  1272. expandUnicodeEscapes_re: re.Pattern = re.compile(
  1273. r"\\u([0-9a-f]{4}(?:[0-9a-f]{4})?)", flags=re.I
  1274. )
  1275. def expandUnicodeEscapes(q: str) -> str:
  1276. r"""
  1277. The syntax of the SPARQL Query Language is expressed over code points in Unicode [UNICODE]. The encoding is always UTF-8 [RFC3629].
  1278. Unicode code points may also be expressed using an \ uXXXX (U+0 to U+FFFF) or \ UXXXXXXXX syntax (for U+10000 onwards) where X is a hexadecimal digit [0-9A-F]
  1279. """
  1280. def expand(m: re.Match) -> str:
  1281. try:
  1282. return chr(int(m.group(1), 16))
  1283. except (ValueError, OverflowError) as e:
  1284. raise ValueError("Invalid unicode code point: " + m.group(1)) from e
  1285. return expandUnicodeEscapes_re.sub(expand, q)
  1286. def parseQuery(q: Union[str, bytes, TextIO, BinaryIO]) -> ParseResults:
  1287. if hasattr(q, "read"):
  1288. q = q.read()
  1289. if isinstance(q, bytes):
  1290. q = q.decode("utf-8")
  1291. q = expandUnicodeEscapes(q)
  1292. return Query.parse_string(q, parse_all=True)
  1293. def parseUpdate(q: Union[str, bytes, TextIO, BinaryIO]) -> CompValue:
  1294. if hasattr(q, "read"):
  1295. q = q.read()
  1296. if isinstance(q, bytes):
  1297. q = q.decode("utf-8")
  1298. q = expandUnicodeEscapes(q)
  1299. return UpdateUnit.parse_string(q, parse_all=True)[0]