Commits

Alexander Dutton committed 520064b Draft

Added support for lexing SPARQL queries.

Comments (0)

Files changed (3)

pygments/lexers/_mapping.py

     'SmartyLexer': ('pygments.lexers.templates', 'Smarty', ('smarty',), ('*.tpl',), ('application/x-smarty',)),
     'SnobolLexer': ('pygments.lexers.other', 'Snobol', ('snobol',), ('*.snobol',), ('text/x-snobol',)),
     'SourcesListLexer': ('pygments.lexers.text', 'Debian Sourcelist', ('sourceslist', 'sources.list'), ('sources.list',), ()),
+    'SparqlLexer': ('pygments.lexers.rdf', 'SPARQL', ('sparql',), ('*.rq', '*.sparql'), ('application/sparql-query',)),
     'SqlLexer': ('pygments.lexers.sql', 'SQL', ('sql',), ('*.sql',), ('text/x-sql',)),
     'SqliteConsoleLexer': ('pygments.lexers.sql', 'sqlite3con', ('sqlite3',), ('*.sqlite3-console',), ('text/x-sqlite3-console',)),
     'SquidConfLexer': ('pygments.lexers.text', 'SquidConf', ('squidconf', 'squid.conf', 'squid'), ('squid.conf',), ('text/x-squidconf',)),

pygments/lexers/rdf.py

+import re
+
+from pygments.lexer import RegexLexer, include, this, bygroups, include
+from pygments.token import Keyword, Punctuation, String, Number, Operator, Whitespace, Name, Literal, Comment
+
+__all__ = ['SparqlLexer']
+
+class SparqlLexer(RegexLexer):
+    name = 'SPARQL'
+    aliases = ['sparql']
+    filenames = ['.rq', '*.sparql']
+    mimetypes = ['application/sparql-query']
+
+    flags = re.I
+
+    tokens = {
+        'root': [
+            (r'\s+', Whitespace),
+            (r'(select|construct|describe|ask|where|filter|group\s+by|minus|'
+             r'distinct|reduced|from named|from|order\s+by|limit|'
+             r'offset|bindings|load|clear|drop|create|add|move|copy|'
+             r'insert\s+data|delete\s+data|delete\s+where|delete|insert|'
+             r'using named|using|graph|default|named|all|optional|service|'
+             r'silent|bind|union|not in|in|as|a)', Keyword),
+            (r'(prefix|base)(\s+)([a-z][a-z\d_\-]*)(\s*)(\:)', bygroups(Keyword, Whitespace, Name.Namespace, Whitespace, Punctuation)),
+            (r'\?[a-z_][a-z\d_]*', Name.Variable),
+            (r'<[^>]+>', Name.Label),
+            (r'([a-z][a-z\d_\-]*)(\:)([a-z][a-z\d_\-]*)', bygroups(Name.Namespace, Punctuation, Name.Tag)),
+            (r'(str|lang|langmatches|datatype|bound|iri|uri|bnode|rand|abs|'
+             r'ceil|floor|round|concat|strlen|ucase|lcase|encode_for_uri|'
+             r'contains|strstarts|strends|strbefore|strafter|year|month|day|'
+             r'hours|minutes|seconds|timezone|tz|now|md5|sha1|sha256|sha384|'
+             r'sha512|coalesce|if|strlang|strdt|sameterm|isiri|isuri|isblank|'
+             r'isliteral|isnumeric|regex|substr|replace|exists|not exists|'
+             r'count|sum|min|max|avg|sample|group_concat|separator)', Name.Function),
+            (r'(true|false)', Literal),
+            (r'[+\-]?\d*\.\d+', Number.Float),
+            (r'[+\-]?\d*(:?\.\d+)?[eE][+\-]?\d+', Number.Float),
+            (r'[+\-]?\d+', Number.Integer),
+            (r'(\|\||&&|=|\*|\-|\+|/)', Operator),
+            (r'[(){}.;,:^]', Punctuation),
+            (r'#[^\n]+', Comment),
+            (r'"""', String, 'triple-double-quoted-string'),
+            (r'"', String, 'single-double-quoted-string'),
+            (r"'''", String, 'triple-single-quoted-string'),
+            (r"'", String, 'single-single-quoted-string'),
+        ],
+        'triple-double-quoted-string': [
+            (r'"""', String, 'end-of-string'),
+            (r'[^\\]+', String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'single-double-quoted-string': [
+            (r'"', String, 'end-of-string'),
+            (r'[^"\\\n]+', String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'triple-single-quoted-string': [
+            (r"'''", String, 'end-of-string'),
+            (r'[^\\]+', String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'single-single-quoted-string': [
+            (r"'", String, 'end-of-string'),
+            (r"[^'\\\n]+", String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'string-escape': [
+            (r'.', String, '#pop'),
+        ],
+        'end-of-string': [
+            (r'(@)([a-zA-Z]+(:?-[a-zA-Z0-9]+)*)', bygroups(Operator, Name.Function), 'root'),
+            (r'^^', Operator, 'root'),
+            include('root'),
+        ],
+    }

tests/examplefiles/sparql.rq

+# This is a test SPARQL query
+
+PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+PREFIX ex: <http://example.org/>
+PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
+PREFIX dcterms: <http://purl.org/dc/terms/>
+
+SELECT ?person (COUNT(?nick) AS ?nickCount) {
+    ?person foaf:nick ?nick ;
+      foaf:lastName "Smith" ;
+      foaf:age "21"^^xsd:int ;
+      ex:title 'Mr' ; # single-quoted string
+      ex:height 1.80 ; # float
+      ex:distanceToSun +1.4e8 ; # float with exponent
+      ex:ownsACat true ;
+      dcterms:description "Someone with a cat called \"cat\"."@en .
+    OPTIONAL { ?person foaf:isPrimaryTopicOf ?page }
+    OPTIONAL { ?person foaf:name ?name
+               { ?person foaf:depiction ?img }
+               UNION
+               { ?person foaf:firstName ?firstN } }
+    FILTER ( bound(?page) || bound(?img) || bound(?firstN) )
+} GROUP BY ?person ORDER BY ?img