From 54df10a1576f154056ec8bf8e6d43a398f81b27d Mon Sep 17 00:00:00 2001 From: Achraf Atauil Date: Wed, 22 Feb 2023 22:10:46 +0100 Subject: [PATCH 1/9] move deps to devDeps + update packages --- package.json | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 608db2d..7439f76 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,11 @@ }, "types": "dist/index.d.ts", "sideEffects": false, - "dependencies": { - "@codemirror/language": "^6.0.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - }, "devDependencies": { - "@lezer/generator": "^1.0.0", + "@codemirror/language": "^6.6.0", + "@lezer/generator": "^1.2.2", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.3", "mocha": "^9.0.1", "rollup": "^2.60.2", "rollup-plugin-dts": "^4.0.1", @@ -31,7 +29,7 @@ "typescript": "^4.3.4" }, "repository": { - "type" : "git", - "url" : "https://github.com/aatauil/codemirror-lang-sparql.git" + "type": "git", + "url": "https://github.com/aatauil/codemirror-lang-sparql.git" } -} \ No newline at end of file +} From 2ae35081a44133744196629713dc4d73ca9ffc22 Mon Sep 17 00:00:00 2001 From: Achraf Atauil Date: Sun, 5 Mar 2023 11:51:26 +0100 Subject: [PATCH 2/9] add generate script This will generate a parser & parser terms file in src folder but cant be commited. This is just to help test since token.js depends on parser.terms.js --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7439f76..b3f316a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Sparql language support for CodeMirror", "scripts": { "test": "mocha test/test.js", - "prepare": "rollup -c" + "prepare": "rollup -c", + "generate": "lezer-generator src/syntax.grammar -o src/parser.js" }, "type": "module", "main": "dist/index.cjs", From 0433f5729a902bcba22ae99d5f78f6e0955f6f26 Mon Sep 17 00:00:00 2001 From: Achraf Atauil Date: Sun, 5 Mar 2023 13:02:53 +0100 Subject: [PATCH 3/9] update package.json, licence & gitignore --- .gitignore | 3 ++- LICENSE | 2 +- package.json | 29 ++++++++++++++++------------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 85706df..96f4a02 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /node_modules package-lock.json /dist -/src/*.js +/src/parser.js +/src/parser.terms.js /src/*.d.ts \ No newline at end of file diff --git a/LICENSE b/LICENSE index 23b98b7..b878ba1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (C) 2021 by Achraf Atauil and others +Copyright (C) 2021 by Achraf Atauil and others Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/package.json b/package.json index b3f316a..0f67d65 100644 --- a/package.json +++ b/package.json @@ -3,34 +3,37 @@ "version": "0.1.1", "description": "Sparql language support for CodeMirror", "scripts": { - "test": "mocha test/test.js", - "prepare": "rollup -c", - "generate": "lezer-generator src/syntax.grammar -o src/parser.js" + "build": "lezer-generator src/syntax.grammar -o src/parser && rollup -c", + "build-debug": "lezer-generator src/syntax.grammar --names -o src/parser && rollup -c", + "test": "mocha test/test-*.js" }, "type": "module", "main": "dist/index.cjs", "module": "dist/index.js", - "author": "Achraf Atauil", - "license": "MIT", "exports": { "import": "./dist/index.js", "require": "./dist/index.cjs" }, "types": "dist/index.d.ts", "sideEffects": false, + "author": "Achraf Atauil", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/aatauil/codemirror-lang-sparql.git" + }, + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + }, "devDependencies": { - "@codemirror/language": "^6.6.0", - "@lezer/generator": "^1.2.2", - "@lezer/highlight": "^1.1.3", - "@lezer/lr": "^1.3.3", + "@lezer/generator": "^1.0.0", "mocha": "^9.0.1", "rollup": "^2.60.2", "rollup-plugin-dts": "^4.0.1", "rollup-plugin-ts": "^3.0.2", "typescript": "^4.3.4" - }, - "repository": { - "type": "git", - "url": "https://github.com/aatauil/codemirror-lang-sparql.git" } + } From 883bd9f106fbb4068a1a6b0545696767cbeb5d2d Mon Sep 17 00:00:00 2001 From: Achraf Atauil Date: Sun, 5 Mar 2023 13:03:04 +0100 Subject: [PATCH 4/9] add token file to support case insensitive tokens --- src/tokens.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/tokens.js diff --git a/src/tokens.js b/src/tokens.js new file mode 100644 index 0000000..b65554a --- /dev/null +++ b/src/tokens.js @@ -0,0 +1,10 @@ +import * as tokens from "./parser.terms.js" + +/** + * Keywords are matched in a case-insensitive manner with the exception + * of the keyword 'a' which, in line with Turtle and N3, is used in place + * of the IRI rdf:type (in full, http://www.w3.org/1999/02/22-rdf-syntax-ns#type). + */ +export const caseInsensitive = (value, stack) => { + return tokens[value.toUpperCase()] || -1; +}; \ No newline at end of file From 23e4ca80ce1b1226b3b88aa9b429e8e673b0b422 Mon Sep 17 00:00:00 2001 From: Achraf Atauil Date: Sun, 5 Mar 2023 16:28:31 +0100 Subject: [PATCH 5/9] Draft round 2... FIGHT! - externalize case insentive keyword tokens - fix upper lowercase tokens (makes a difference) - add @precedence rules (complete mess, just made it work for now) - add @detectDelim at the top - simplify to 1 @top declaration called "Unit" --- src/syntax.grammar | 583 ++++++++++++++++++++++++--------------------- 1 file changed, 316 insertions(+), 267 deletions(-) diff --git a/src/syntax.grammar b/src/syntax.grammar index 4ef7bda..abdfe96 100644 --- a/src/syntax.grammar +++ b/src/syntax.grammar @@ -1,17 +1,11 @@ -@top QueryUnit { - Query -} - -@top UpdateUnit { - Update -} +@detectDelim -Prologue { - (BaseDecl | PrefixDecl)* +@top Unit { + ( Query | Update ) } Query { - Prologue ( SelectQuery | ConstructQuery | DescribeQuery | AskQuery ) ValuesClause + Prologue ( SelectQuery | ConstructQuery | DescribeQuery | AskQuery ) ValuesClause } Update { @@ -19,125 +13,67 @@ Update { } Update1 { - Load | Clear | Drop | Add | Move | Copy | Create | InsertData | DeleteData | DeleteWhere | Modify -} - -DeleteClause { - 'DELETE' QuadPattern -} - -InsertClause { - 'INSERT' QuadPattern -} - -UsingClause { - 'USING' ( iri | 'NAMED' iri ) -} - -QuadData { - '{' Quads '}' -} - -QuadPattern { - '{' Quads '}' -} - -Quads { - TriplesTemplate? ( QuadsNotTriples '.'? TriplesTemplate? )* -} - -QuadsNotTriples { - 'GRAPH' VarOrIri '{' TriplesTemplate? '}' -} - - - -GraphOrDefault { - 'DEFAULT' | 'GRAPH'? iri -} - -GraphRefAll { - GraphRef | 'DEFAULT' | 'NAMED' | 'ALL' + ( Load | Clear | Drop | Add | Move | Copy | Create | InsertData | DeleteData | DeleteWhere | Modify ) } Load { - 'LOAD' 'SILENT'? iri ( 'INTO' GraphRef )? + LOAD SILENT? Iri ( INTO GraphRef )? } Clear { - 'CLEAR' 'SILENT'? GraphRefAll + CLEAR SILENT? GraphRefAll } Drop { - 'DROP' 'SILENT'? GraphRefAll + DROP SILENT? GraphRefAll } Create { - 'CREATE' 'SILENT'? GraphRef + CREATE SILENT? GraphRef } Add { - 'ADD' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault + ADD SILENT? GraphOrDefault TO GraphOrDefault } Move { - 'MOVE' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault + MOVE SILENT? GraphOrDefault TO GraphOrDefault } Copy { - 'COPY' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault + COPY SILENT? GraphOrDefault TO GraphOrDefault } InsertData { - 'INSERT DATA' QuadData + INSERT DATA QuadData } DeleteData { - 'DELETE DATA' QuadData + DELETE DATA QuadData } DeleteWhere { - 'DELETE WHERE' QuadPattern + DELETE WHERE QuadPattern } Modify { - ( 'WITH' iri )? ( DeleteClause InsertClause? | InsertClause ) UsingClause* 'WHERE' GroupGraphPattern + ( WITH Iri )? ( DeleteClause InsertClause? | InsertClause ) UsingClause* WHERE GroupGraphPattern } GraphRef { - 'GRAPH' iri -} - -AskQuery { - 'ASK' DatasetClause* WhereClause SolutionModifier -} - -DescribeQuery { - 'DESCRIBE' ( VarOrIri+ | '*' ) DatasetClause* WhereClause? SolutionModifier -} - -ConstructQuery { - 'CONSTRUCT' ( ConstructTemplate DatasetClause* WhereClause SolutionModifier | DatasetClause* 'WHERE' '{' TriplesTemplate? '}' SolutionModifier ) -} - -TriplesTemplate { - TriplesSameSubject ( '.' TriplesTemplate? )? -} - -ConstructTemplate { - '{' ConstructTriples? '}' + GRAPH Iri } -ConstructTriples { - TriplesSameSubject ( '.' ConstructTriples? )? +Prologue { + (BaseDecl | PrefixDecl)* } -TriplesSameSubject { - VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList +BaseDecl { + BASE IriRef } -PropertyList { - PropertyListNotEmpty? +PrefixDecl { + PREFIX Namespace IriRef } SelectQuery { @@ -145,15 +81,7 @@ SelectQuery { } SelectClause { - 'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' ) -} - -BaseDecl { - 'BASE' IriRef -} - -PrefixDecl { - 'PREFIX' Namespace IriRef + SELECT ( DISTINCT | REDUCED )? ( ( Var | ( '(' Expression AS Var ')' ) )+ | '*' ) } Expression { @@ -173,7 +101,16 @@ ValueLogical { } RelationalExpression { - NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )? + NumericExpression ( + '=' NumericExpression | + '!=' NumericExpression | + '<' NumericExpression | + '>' NumericExpression | + '<=' NumericExpression | + '>=' NumericExpression | + IN ExpressionList | + NOT IN ExpressionList + )? } NumericExpression { @@ -181,7 +118,15 @@ NumericExpression { } AdditiveExpression { - MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )* + MultiplicativeExpression ( + '+' MultiplicativeExpression | + '-' MultiplicativeExpression | + ( NumericLiteralPositive | NumericLiteralNegative ) + ( + ( '*' UnaryExpression ) | + ( '/' UnaryExpression ) + )* + )* } MultiplicativeExpression { @@ -196,7 +141,15 @@ UnaryExpression { } PrimaryExpression { - (BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var) + ( + BrackettedExpression | + BuiltInCall | + iriOrFunction | + RDFLiteral | + NumericLiteral | + BooleanLiteral | + Var + ) } BrackettedExpression { @@ -205,70 +158,70 @@ BrackettedExpression { BuiltInCall { ( Aggregate - | 'STR' '(' Expression ')' - | 'LANG' '(' Expression ')' - | 'LANGMATCHES' '(' Expression ',' Expression ')' - | 'DATATYPE' '(' Expression ')' - | 'BOUND' '(' Var ')' - | 'IRI' '(' Expression ')' - | 'URI' '(' Expression ')' - | 'BNODE' ( '(' Expression ')' | NIL ) - | 'RAND' NIL - | 'ABS' '(' Expression ')' - | 'CEIL' '(' Expression ')' - | 'FLOOR' '(' Expression ')' - | 'ROUND' '(' Expression ')' - | 'CONCAT' ExpressionList + | STR '(' Expression ')' + | LANG '(' Expression ')' + | LANGMATCHES '(' Expression ',' Expression ')' + | DATATYPE '(' Expression ')' + | BOUND '(' Var ')' + | IRI '(' Expression ')' + | URI '(' Expression ')' + | BNODE ( '(' Expression ')' | Nil ) + | RAND Nil + | ABS '(' Expression ')' + | CEIL '(' Expression ')' + | FLOOR '(' Expression ')' + | ROUND '(' Expression ')' + | CONCAT ExpressionList | SubstringExpression - | 'STRLEN' '(' Expression ')' + | STRLEN '(' Expression ')' | StrReplaceExpression - | 'UCASE' '(' Expression ')' - | 'LCASE' '(' Expression ')' - | 'ENCODE_FOR_URI' '(' Expression ')' - | 'CONTAINS' '(' Expression ',' Expression ')' - | 'STRSTARTS' '(' Expression ',' Expression ')' - | 'STRENDS' '(' Expression ',' Expression ')' - | 'STRBEFORE' '(' Expression ',' Expression ')' - | 'STRAFTER' '(' Expression ',' Expression ')' - | 'YEAR' '(' Expression ')' - | 'MONTH' '(' Expression ')' - | 'DAY' '(' Expression ')' - | 'HOURS' '(' Expression ')' - | 'MINUTES' '(' Expression ')' - | 'SECONDS' '(' Expression ')' - | 'TIMEZONE' '(' Expression ')' - | 'TZ' '(' Expression ')' - | 'NOW' NIL - | 'UUID' NIL - | 'STRUUID' NIL - | 'MD5' '(' Expression ')' - | 'SHA1' '(' Expression ')' - | 'SHA256' '(' Expression ')' - | 'SHA384' '(' Expression ')' - | 'SHA512' '(' Expression ')' - | 'COALESCE' ExpressionList - | 'IF' '(' Expression ',' Expression ',' Expression ')' - | 'STRLANG' '(' Expression ',' Expression ')' - | 'STRDT' '(' Expression ',' Expression ')' - | 'sameTerm' '(' Expression ',' Expression ')' - | 'isIRI' '(' Expression ')' - | 'isURI' '(' Expression ')' - | 'isBLANK' '(' Expression ')' - | 'isLITERAL' '(' Expression ')' - | 'isNUMERIC' '(' Expression ')' + | UCASE '(' Expression ')' + | LCASE '(' Expression ')' + | ENCODE_FOR_URI '(' Expression ')' + | CONTAINS '(' Expression ',' Expression ')' + | STRSTARTS '(' Expression ',' Expression ')' + | STRENDS '(' Expression ',' Expression ')' + | STRBEFORE '(' Expression ',' Expression ')' + | STRAFTER '(' Expression ',' Expression ')' + | YEAR '(' Expression ')' + | MONTH '(' Expression ')' + | DAY '(' Expression ')' + | HOURS '(' Expression ')' + | MINUTES '(' Expression ')' + | SECONDS '(' Expression ')' + | TIMEZONE '(' Expression ')' + | TZ '(' Expression ')' + | NOW Nil + | UUID Nil + | STRUUID Nil + | MD5 '(' Expression ')' + | SHA1 '(' Expression ')' + | SHA256 '(' Expression ')' + | SHA384 '(' Expression ')' + | SHA512 '(' Expression ')' + | COALESCE ExpressionList + | IF '(' Expression ',' Expression ',' Expression ')' + | STRLANG '(' Expression ',' Expression ')' + | STRDT '(' Expression ',' Expression ')' + | SAMETERM '(' Expression ',' Expression ')' + | ISIRI '(' Expression ')' + | ISURI '(' Expression ')' + | ISBLANK '(' Expression ')' + | ISLITERAL '(' Expression ')' + | ISNUMERIC '(' Expression ')' | RegexExpression | ExistsFunc | NotExistsFunc ) } Aggregate { - ( 'COUNT' '(' 'DISTINCT'? ( '*' | Expression ) ')' - | 'SUM' '(' 'DISTINCT'? Expression ')' - | 'MIN' '(' 'DISTINCT'? Expression ')' - | 'MAX' '(' 'DISTINCT'? Expression ')' - | 'AVG' '(' 'DISTINCT'? Expression ')' - | 'SAMPLE' '(' 'DISTINCT'? Expression ')' - | 'GROUP_CONCAT' '(' 'DISTINCT'? Expression ( ';' 'SEPARATOR' '=' String )? ')' ) + ( COUNT '(' DISTINCT? ( '*' | Expression ) ')' + | SUM '(' DISTINCT? Expression ')' + | MIN '(' DISTINCT? Expression ')' + | MAX '(' DISTINCT? Expression ')' + | AVG '(' DISTINCT? Expression ')' + | SAMPLE '(' DISTINCT? Expression ')' + | GROUP_CONCAT '(' DISTINCT? Expression ( ';' SEPARATOR '=' String )? ')' ) } String { @@ -279,27 +232,27 @@ String { } ExpressionList { - ( NIL | "(" Expression ("," Expression)* ")" ) + ( Nil | "(" Expression ("," Expression)* ")" ) } SubstringExpression { - 'SUBSTR' '(' Expression ',' Expression ( ',' Expression )? ')' + SUBSTR '(' Expression ',' Expression ( ',' Expression )? ')' } StrReplaceExpression { - 'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')' + REPLACE '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')' } RegexExpression { - 'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')' + REGEX '(' Expression ',' Expression ( ',' Expression )? ')' } ExistsFunc { - 'EXISTS' GroupGraphPattern + EXISTS GroupGraphPattern } NotExistsFunc { - 'NOT' 'EXISTS' GroupGraphPattern + NOT EXISTS GroupGraphPattern } GroupGraphPattern { @@ -311,7 +264,7 @@ SubSelect { } WhereClause { - 'WHERE'? GroupGraphPattern + WHERE? GroupGraphPattern } SolutionModifier { @@ -319,39 +272,39 @@ SolutionModifier { } GroupClause { - 'GROUP' 'BY' GroupCondition+ + GROUP BY GroupCondition+ } GroupCondition { - ( BuiltInCall | FunctionCall | '(' Expression ( 'AS' Var )? ')' | Var ) + ( BuiltInCall | FunctionCall | '(' Expression ( AS Var )? ')' | Var ) } FunctionCall { - iri ArgList + Iri ArgList } ArgList { - ( NIL | '(' 'DISTINCT'? Expression ( ',' Expression )* ')' ) + ( Nil | '(' DISTINCT? Expression ( ',' Expression )* ')' ) } HavingClause { - 'HAVING' HavingCondition+ + HAVING HavingCondition+ } HavingCondition { Constraint } -OrderClause { - 'ORDER' 'BY' OrderCondition+ +Constraint { + ( BrackettedExpression | BuiltInCall | FunctionCall ) } -OrderCondition { - ( ( 'ASC' | 'DESC' ) BrackettedExpression ) | ( Constraint | Var ) +OrderClause { + ORDER BY OrderCondition+ } -Constraint { - ( BrackettedExpression | BuiltInCall | FunctionCall ) +OrderCondition { + ( ( ASC | DESC ) BrackettedExpression ) | ( Constraint | Var ) } LimitOffsetClauses { @@ -359,15 +312,15 @@ LimitOffsetClauses { } LimitClause { - 'LIMIT' INTEGER+ + LIMIT Integer+ } OffsetClause { - 'OFFSET' INTEGER+ + OFFSET Integer+ } ValuesClause { - ( 'VALUES' DataBlock )? + ( VALUES DataBlock )? } DataBlock { @@ -379,15 +332,15 @@ InlineDataOneVar { } InlineDataFull { - ( NIL | '(' Var* ')' ) '{' ( '(' DataBlockValue* ')' | NIL )* '}' + ( Nil | '(' Var* ')' ) '{' ( '(' DataBlockValue* ')' | Nil )* '}' } DataBlockValue { - ( iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF' ) + ( Iri | RDFLiteral | NumericLiteral | BooleanLiteral | UNDEF ) } RDFLiteral { - String ( LANGTAG | ( '^^' iri ) )? + String ( Langstag | ( '^^' Iri ) )? } NumericLiteral { @@ -395,19 +348,19 @@ NumericLiteral { } NumericLiteralUnsigned { - ( INTEGER | DECIMAL | DOUBLE ) + ( Integer | Decimal | Double ) } NumericLiteralPositive { - ( INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE ) + ( IntegerPositive | DecimalPositive | DoublePositive ) } NumericLiteralNegative { - ( INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE ) + ( IntegerNegative | DecimalNegative | DoubleNegative ) } BooleanLiteral { - ( 'true' | 'false' ) + Boolean } GroupGraphPatternSub { @@ -419,7 +372,7 @@ TriplesBlock { } TriplesSameSubjectPath { - ( VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath ) + VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath } VarOrTerm { @@ -427,15 +380,15 @@ VarOrTerm { } GraphTerm { - ( iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL ) + ( Iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | Nil ) } BlankNode { - ( BlankNodeLabel | ANON ) + ( BlankNodeLabel | Anon ) } BlankNodeLabel { - "_:" blankNodeValue? + "_:" BlankNodeValue? } PropertyListPathNotEmpty { @@ -467,15 +420,15 @@ PathEltOrInverse { } PathPrimary { - ( iri | 'a' | '!' PathNegatedPropertySet | '(' Path ')' ) + ( Iri | 'a' | '!' PathNegatedPropertySet | '(' Path ')' ) } PathNegatedPropertySet { - PathOneInPropertySet | '(' ( PathOneInPropertySet ( '|' PathOneInPropertySet )* )? ')' + ( PathOneInPropertySet | '(' ( PathOneInPropertySet ( '|' PathOneInPropertySet )* )? ')' ) } PathOneInPropertySet { - ( iri | 'a' | '^' ( iri | 'a' ) ) + ( Iri | 'a' | '^' ( Iri | 'a' ) ) } PathMod { @@ -495,11 +448,11 @@ ObjectPath { } GraphNodePath { - VarOrTerm | TriplesNodePath + ( VarOrTerm | TriplesNodePath ) } TriplesNodePath { - CollectionPath | BlankNodePropertyListPath + ( CollectionPath | BlankNodePropertyListPath ) } BlankNodePropertyListPath { @@ -543,7 +496,7 @@ Verb { } VarOrIri { - ( Var | iri ) + ( Var | Iri ) } PropertyListPath { @@ -551,47 +504,47 @@ PropertyListPath { } GraphPatternNotTriples { - GroupOrUnionGraphPattern | OptionalGraphPattern | MinusGraphPattern | GraphGraphPattern | ServiceGraphPattern | Filter | Bind | InlineData + ( GroupOrUnionGraphPattern | OptionalGraphPattern | MinusGraphPattern | GraphGraphPattern | ServiceGraphPattern | Filter | Bind | InlineData ) } GroupOrUnionGraphPattern { - GroupGraphPattern ( 'UNION' GroupGraphPattern )* + GroupGraphPattern ( UNION GroupGraphPattern )* } OptionalGraphPattern { - 'OPTIONAL' GroupGraphPattern + OPTIONAL GroupGraphPattern } MinusGraphPattern { - 'MINUS' GroupGraphPattern + MINUS GroupGraphPattern } GraphGraphPattern { - 'GRAPH' VarOrIri GroupGraphPattern + GRAPH VarOrIri GroupGraphPattern } ServiceGraphPattern { - 'SERVICE' 'SILENT'? VarOrIri GroupGraphPattern + SERVICE SILENT? VarOrIri GroupGraphPattern } Filter { - 'FILTER' Constraint + FILTER Constraint } Bind { - 'BIND' '(' Expression 'AS' Var ')' + BIND '(' Expression AS Var ')' } InlineData { - 'VALUES' DataBlock + VALUES DataBlock } iriOrFunction { - iri ArgList? + Iri ArgList? } DatasetClause { - 'FROM' ( DefaultGraphClause | NamedGraphClause ) + FROM ( DefaultGraphClause | NamedGraphClause ) } DefaultGraphClause { @@ -599,13 +552,82 @@ DefaultGraphClause { } NamedGraphClause { - 'NAMED' SourceSelector + NAMED SourceSelector } SourceSelector { - iri + Iri +} + +ConstructQuery { + CONSTRUCT ( ConstructTemplate DatasetClause* WhereClause SolutionModifier | DatasetClause* WHERE '{' TriplesTemplate? '}' SolutionModifier ) +} + +ConstructTemplate { + '{' ConstructTriples? '}' +} + +ConstructTriples { + TriplesSameSubject ( '.' ConstructTriples? )? +} + +TriplesSameSubject { + VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList +} + +PropertyList { + PropertyListNotEmpty? +} + +TriplesTemplate { + TriplesSameSubject ( '.' TriplesTemplate? )? +} + +DescribeQuery { + DESCRIBE ( VarOrIri+ | '*' ) DatasetClause* WhereClause? SolutionModifier +} + +AskQuery { + ASK DatasetClause* WhereClause SolutionModifier +} + +GraphRefAll { + ( GraphRef | DEFAULT | NAMED | ALL ) +} + +GraphOrDefault { + DEFAULT | GRAPH? Iri +} + +QuadData { + '{' Quads '}' +} + +Quads { + TriplesTemplate? ( QuadsNotTriples '.'? TriplesTemplate? )* +} + +QuadsNotTriples { + GRAPH VarOrIri '{' TriplesTemplate? '}' +} + +QuadPattern { + '{' Quads '}' +} + +DeleteClause { + DELETE QuadPattern +} + +InsertClause { + INSERT QuadPattern +} + +UsingClause { + USING ( Iri | NAMED Iri ) } + @skip { space | Comment* } @tokens { @@ -616,21 +638,12 @@ SourceSelector { Comment { "#" ![\n]* } - - IriRef { - "<" (![<>"{}|^`\\\x00-\x20])* ">" - } - - iri { - IriRef | PrefixedName + Keyword { + $[_a-zA-Z\u00A1-\u00ff]+ } - PrefixedName { - PnameLn | Namespace - } - - PnameLn { - Namespace PnLocal + IriRef { + "<" (![<>"{}|^`\\\x00-\x20])* ">" } Namespace { @@ -638,27 +651,27 @@ SourceSelector { } PnPrefix { - $[a-z]? + $[a-z] | $[A-Z] } - PN_CHARS_BASE { - ($[A-Z] | $[a-z]) + Var { + $[?$] VarName } - Var { - $[?$] VARNAME + VarName { + ( pn_chars_u | $[0-9] ) ( pn_chars_u | $[0-9] | $[\u00B7] | $[\u0300-\u036F] | $[\u203F-\u2040] )* } - VARNAME { - ( PN_CHARS_U | $[0-9] ) ( PN_CHARS_U | $[0-9] | $[\u00B7] | $[\u0300-\u036F] | $[\u203F-\u2040] )* + pn_chars_u { + ( pn_chars_base | '_' ) } - PN_CHARS_U { - ( PN_CHARS_BASE | '_' ) + pn_chars_base { + $[A-Z] | $[a-z] } stringLiteral1 { - "'" (![\x27\x5C\x0A\x0D] | Echar)* "'" + "'" (![\x27\x5C\x0A\x0D] | Echar)* "'" } stringLiteral2 { @@ -677,90 +690,126 @@ SourceSelector { "\\\\" $[tbnrf\\"'] } - NIL { + Nil { "(" ("\\x20" | "\\x09" | "\\x0D" | "\\x0A")* ")" } + Iri { + IriRef | PrefixedName + } + + PrefixedName { + PnameLn | Namespace + } + + PnameLn { + Namespace PnLocal + } + PnLocal { - (PN_CHARS_U | "\\:" | $[0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )? + (pn_chars_u | "\\:" | $[0-9] | plx ) ((pn_chars | '.' | ':' | plx)* (pn_chars | ':' | plx) )? } - PLX { - (PERCENT | PN_LOCAL_ESC) + plx { + (percent | pn_local_esc) } - PERCENT { - "%" HEX HEX + percent { + "%" hex hex } - HEX { + hex { $[0-9] | $[A-F] | $[a-f] } - - PN_LOCAL_ESC { + pn_local_esc { "\\" } - PN_CHARS { - ( PN_CHARS_U | '-' | $[0-9] | $[\u00B7] | $[\u0300-\u036F] | $[\u203F-\u2040] ) + pn_chars { + ( pn_chars_u | '-' | $[0-9] | $[\u00B7] | $[\u0300-\u036F] | $[\u203F-\u2040] ) } - @precedence { INTEGER, DECIMAL, DOUBLE, ".", blankNodeValue } - @precedence { INTEGER_POSITIVE, DECIMAL_POSITIVE, DOUBLE_POSITIVE, "+" } - @precedence { INTEGER_NEGATIVE, DECIMAL_NEGATIVE, DOUBLE_NEGATIVE, "-" } - @precedence { iri, "false", "true", "a", blankNodeValue, space } - @precedence { Var, "?" } - - INTEGER { + Integer { @digit+ } - DECIMAL { + Decimal { @digit* "." @digit+ } - DOUBLE { - @digit+ "." @digit* EXPONENT | "." (@digit)+ EXPONENT | (@digit)+ EXPONENT + Double { + @digit+ "." @digit* Exponent | "." (@digit)+ Exponent | (@digit)+ Exponent } - INTEGER_POSITIVE { - "+" INTEGER + + IntegerPositive { + "+" Integer } - DECIMAL_POSITIVE { - "+" DECIMAL + DecimalPositive { + "+" Decimal } - DOUBLE_POSITIVE { - "+" DOUBLE + DoublePositive { + "+" Double } - INTEGER_NEGATIVE { - "-" INTEGER + IntegerNegative { + "-" Integer } - DECIMAL_NEGATIVE { - "-" DECIMAL + DecimalNegative { + "-" Decimal } - DOUBLE_NEGATIVE { - "-" DOUBLE + DoubleNegative { + "-" Double } - EXPONENT { + Exponent { $[eE] $[+-]? @digit+ } - LANGTAG { + Langstag { "@" @asciiLetter+ ("-" ( @asciiLowercase | @asciiUppercase | @digit)+)* } - ANON { + BlankNodeValue { + ( $[A-Z] | $[a-z] | $[\u00C0-\u00D6] | $[\u00D8-\u00F6] | $[\u00F8-\u02FF] | $[\u0370-\u037D] | $[\u037F-\u1FFF] | $[\u200C-\u200D] | $[\u2070-\u218F] | $[\u2C00-\u2FEF] | $[\u3001-\uD7FF] | $[\uF900-\uFDCF] | $[\uFDF0-\uFFFD] | "_" | $[0-9] )+ + } + + Anon { "[" ("\\x20" | "\\x09" | "\\x0D" | "\\x0A")* "]" } - blankNodeValue { - $[A-Z] | $[a-z] | $[\u00C0-\u00D6] | $[\u00D8-\u00F6] | $[\u00F8-\u02FF] | $[\u0370-\u037D] | $[\u037F-\u1FFF] | $[\u200C-\u200D] | $[\u2070-\u218F] | $[\u2C00-\u2FEF] | $[\u3001-\uD7FF] | $[\uF900-\uFDCF] | $[\uFDF0-\uFFFD] | "_" | $[0-9] + Boolean { + ( TRUE | FALSE ) + } + + @precedence { Iri, "a" , "_:", space, Keyword, BlankNodeValue } + @precedence { + DoublePositive, DecimalPositive, IntegerPositive, Double, Decimal, Integer, "+", ".", BlankNodeValue } + + @precedence { + DoubleNegative, DecimalNegative, IntegerNegative, Double, Decimal, Integer, "-", ".", BlankNodeValue + } + + @precedence { + Var "?" + } + + "_:" "{" "}" "." "," ";" +} + + +@external specialize { Keyword } caseInsensitive from "./tokens" { + BASE, PREFIX, SELECT, CONSTRUCT, DESCRIBE, WHERE, DISTINCT, REDUCED, STR, LANG, LANGMATCHES, DATATYPE, ASK, BOUND, IRI, URI, BNODE, RAND, ABS, CEIL, FLOOR, ROUND, CONCAT, STRLEN, UCASE, LCASE, + ENCODE_FOR_URI, CONTAINS, STRSTARTS, STRENDS, STRBEFORE, STRAFTER, YEAR, MONTH, DAY, + HOURS, MINUTES, SECONDS, TIMEZONE, TZ, NOW, UUID, STRUUID, MD5, SHA1, SHA256, SHA384, + SHA512, COALESCE, IF, STRLANG, STRDT, SAMETERM, ISIRI, ISURI, ISBLANK, ISLITERAL, + ISNUMERIC, COUNT, SUM, MIN, MAX, AVG, SAMPLE, GROUP_CONCAT, SEPARATOR, SUBSTR, REPLACE, + REGEX, EXISTS, NOT, IN, GROUP, BY, HAVING, ORDER, ASC, DESC, LIMIT, OFFSET, VALUES, UNDEF, + UNION, OPTIONAL, MINUS, GRAPH, SERVICE, SILENT, FILTER, BIND, AS, FROM, NAMED, TRUE, FALSE, LOAD, INTO, TO, CLEAR, DROP, CREATE, ADD, MOVE, COPY, INSERT, DATA, DELETE, WITH, DEFAULT, ALL, USING } From 0d519b9e5cf352b95bbdb0b9cf437eab9aef32c6 Mon Sep 17 00:00:00 2001 From: Achraf Atauil Date: Sun, 5 Mar 2023 16:28:55 +0100 Subject: [PATCH 6/9] add styleTags (incomplete but its a start) --- src/index.ts | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/index.ts b/src/index.ts index d0d104d..454cfc0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,28 +1,23 @@ -import {parser} from "./syntax.grammar" -import {LRLanguage, LanguageSupport, indentNodeProp, foldNodeProp, foldInside, delimitedIndent} from "@codemirror/language" -import {styleTags, tags as t} from "@lezer/highlight" +import { parser } from "./syntax.grammar" +import { LRLanguage, LanguageSupport } from "@codemirror/language" +import { styleTags, tags as t } from "@lezer/highlight" export const SparqlLanguage = LRLanguage.define({ parser: parser.configure({ props: [ - indentNodeProp.add({ - Application: delimitedIndent({closing: ")", align: false}) - }), - foldNodeProp.add({ - Application: foldInside - }), styleTags({ - Identifier: t.variableName, - Boolean: t.bool, + Comment: t.comment, + "BASE PREFIX SELECT CONSTRUCT DESCRIBE WHERE DISTINCT REDUCED STR LANG LANGMATCHES DATATYPE ASK BOUND IRI URI BNODE RAND ABS CEIL FLOOR ROUND CONCAT STRLEN UCASE LCASE ENCODE_FOR_URI CONTAINS STRSTARTS STRENDS STRBEFORE STRAFTER YEAR MONTH DAY HOURS MINUTES SECONDS TIMEZONE TZ NOW UUID STRUUID MD5 SHA1 SHA256 SHA384 SHA512 COALESCE IF STRLANG STRDT SAMETERM ISIRI ISURI ISBLANK ISLITERAL ISNUMERIC COUNT SUM MIN MAX AVG SAMPLE GROUP_CONCAT SEPARATOR SUBSTR REPLACE REGEX EXISTS NOT IN GROUP BY HAVING ORDER ASC DESC LIMIT OFFSET VALUES UNDEF UNION OPTIONAL MINUS GRAPH SERVICE SILENT FILTER BIND AS FROM NAMED LOAD INTO TO CLEAR DROP CREATE ADD MOVE COPY INSERT DATA DELETE WITH DEFAULT ALL USING": t.keyword, + "Var ObjectListPath/..": t.variableName, String: t.string, - LineComment: t.lineComment, - "( )": t.paren + Integer: t.integer, + "Double Decimal": t.float, + "{ }": t.brace, + Langstag: t.annotation, + "TRUE FALSE": t.bool }) ] }), - languageData: { - commentTokens: {line: ";"} - } }) export function sparql() { From 43b16372836a0bc4dfdb51a02d86e9018c04cf35 Mon Sep 17 00:00:00 2001 From: Achraf Atauil Date: Sun, 5 Mar 2023 16:34:37 +0100 Subject: [PATCH 7/9] remove seperate boolean token --- src/syntax.grammar | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/syntax.grammar b/src/syntax.grammar index abdfe96..833e063 100644 --- a/src/syntax.grammar +++ b/src/syntax.grammar @@ -360,7 +360,7 @@ NumericLiteralNegative { } BooleanLiteral { - Boolean + ( TRUE | FALSE ) } GroupGraphPatternSub { @@ -783,10 +783,6 @@ UsingClause { "[" ("\\x20" | "\\x09" | "\\x0D" | "\\x0A")* "]" } - Boolean { - ( TRUE | FALSE ) - } - @precedence { Iri, "a" , "_:", space, Keyword, BlankNodeValue } @precedence { DoublePositive, DecimalPositive, IntegerPositive, Double, Decimal, Integer, "+", ".", BlankNodeValue @@ -813,3 +809,6 @@ UsingClause { REGEX, EXISTS, NOT, IN, GROUP, BY, HAVING, ORDER, ASC, DESC, LIMIT, OFFSET, VALUES, UNDEF, UNION, OPTIONAL, MINUS, GRAPH, SERVICE, SILENT, FILTER, BIND, AS, FROM, NAMED, TRUE, FALSE, LOAD, INTO, TO, CLEAR, DROP, CREATE, ADD, MOVE, COPY, INSERT, DATA, DELETE, WITH, DEFAULT, ALL, USING } + +@external propSource highlight from "./highlight" + From adea1002739047ade39b6544bca64ce58f4a9a40 Mon Sep 17 00:00:00 2001 From: Achraf Atauil Date: Sun, 5 Mar 2023 16:34:43 +0100 Subject: [PATCH 8/9] Update test case --- test/cases.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/cases.txt b/test/cases.txt index 47c2aa5..66e3c50 100644 --- a/test/cases.txt +++ b/test/cases.txt @@ -7,17 +7,21 @@ SELECT * WHERE { ==> -QueryUnit( +Unit( Query( Prologue( PrefixDecl( + PREFIX Namespace, IriRef ) ) SelectQuery( - SelectClause + SelectClause ( + SELECT + ) WhereClause( + WHERE GroupGraphPattern( GroupGraphPatternSub ( TriplesBlock ( @@ -47,7 +51,8 @@ QueryUnit( SolutionModifier ( LimitOffsetClauses ( LimitClause ( - INTEGER + LIMIT + Integer ) ) ) From 8b16210f32363d028703bae0d12bc9d8bfbd3bf1 Mon Sep 17 00:00:00 2001 From: Achraf Atauil Date: Sun, 5 Mar 2023 16:35:38 +0100 Subject: [PATCH 9/9] restore test script / bump version to 0.2.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0f67d65..f14a5a8 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "codemirror-lang-sparql", - "version": "0.1.1", + "version": "0.2.0", "description": "Sparql language support for CodeMirror", "scripts": { "build": "lezer-generator src/syntax.grammar -o src/parser && rollup -c", "build-debug": "lezer-generator src/syntax.grammar --names -o src/parser && rollup -c", - "test": "mocha test/test-*.js" + "test": "mocha test/test.js" }, "type": "module", "main": "dist/index.cjs",