-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(lxl-querylang): grammar and highlighting (#1159)
* Add rudimentary grammar and tests * Add highlighting etc * Bundle language + extension in export
- Loading branch information
1 parent
4a879a7
commit 1ebbd1d
Showing
8 changed files
with
279 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
.lxlq.qualifier { | ||
color: green; | ||
} | ||
|
||
.lxlq.qualifier-key { | ||
color: green; | ||
} | ||
|
||
.lxlq.qualifier-value { | ||
color: green; | ||
} | ||
|
||
.lxlq.equal-operator, | ||
.lxlq.compare-operator { | ||
color: darkolivegreen; | ||
} | ||
|
||
.lxlq.boolean-operator { | ||
color: #935493; | ||
} | ||
|
||
.lxlq.boolean-query { | ||
color: purple; | ||
} | ||
|
||
.lxlq.wildcard { | ||
color: orange; | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,47 @@ | ||
import { parser } from './syntax.grammar'; | ||
import { LRLanguage, LanguageSupport } from '@codemirror/language'; | ||
import { styleTags, tags as t } from '@lezer/highlight'; | ||
import { LRLanguage, LanguageSupport, syntaxHighlighting } from '@codemirror/language'; | ||
import { styleTags, Tag, tagHighlighter } from '@lezer/highlight'; | ||
|
||
// custom tags attached to the language parser | ||
const customTags = { | ||
Qualifier: Tag.define('Qualifier'), | ||
QualifierKey: Tag.define('QualifierKey'), | ||
QualifierValue: Tag.define('QualifierValue'), | ||
EqualOperator: Tag.define('EqualOperator'), | ||
CompareOperator: Tag.define('CompareOperator'), | ||
BooleanQuery: Tag.define('BooleanQuery'), | ||
BooleanOperator: Tag.define('BooleanOperator'), | ||
Wildcard: Tag.define('Wildcard') | ||
}; | ||
|
||
export const lxlQueryLanguage = LRLanguage.define({ | ||
name: 'Libris XL query', | ||
parser: parser.configure({ | ||
props: [ | ||
styleTags({ | ||
Identifier: t.variableName, | ||
String: t.string, | ||
CompareOperator: t.compareOperator, | ||
'( )': t.paren | ||
}) | ||
] | ||
props: [styleTags(customTags)] | ||
}), | ||
languageData: {} | ||
}); | ||
|
||
export function lxlQuery() { | ||
return new LanguageSupport(lxlQueryLanguage); | ||
} | ||
const highlighter = tagHighlighter( | ||
[ | ||
{ tag: customTags.Qualifier, class: 'qualifier' }, | ||
{ tag: customTags.QualifierKey, class: 'qualifier-key' }, | ||
{ tag: customTags.QualifierValue, class: 'qualifier-value' }, | ||
{ tag: customTags.EqualOperator, class: 'equal-operator' }, | ||
{ tag: customTags.CompareOperator, class: 'compare-operator' }, | ||
{ tag: customTags.BooleanOperator, class: 'boolean-operator' }, | ||
{ tag: customTags.BooleanQuery, class: 'boolean-query' }, | ||
{ tag: customTags.Wildcard, class: 'wildcard' } | ||
], | ||
{ | ||
all: 'lxlq' | ||
} | ||
); | ||
|
||
const highlighterExtension = syntaxHighlighting(highlighter); | ||
|
||
/** | ||
* Libris XL query language together with a highlighter extension | ||
* that adds CSS classes for certain nodes | ||
*/ | ||
export const lxlQuery = new LanguageSupport(lxlQueryLanguage, highlighterExtension) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,57 @@ | ||
@top Program { expression* } | ||
@top Query { term* } | ||
|
||
@skip { space | LineComment } | ||
@skip { space } | ||
|
||
expression { | ||
Identifier | | ||
String | | ||
Boolean | | ||
Application { "(" expression* ")" } | ||
term { | ||
freetext | | ||
Qualifier | | ||
Group | | ||
BooleanQuery | ||
} | ||
|
||
Group { "(" term* ")" } | ||
|
||
BooleanQuery { | ||
(freetext | Qualifier) BooleanOperator (freetext | Qualifier) | ||
(BooleanOperator (freetext | Qualifier))+? | ||
} | ||
|
||
Qualifier { | ||
(QualifierKey (EqualOperator | CompareOperator) QualifierValue) | reserved | ||
} | ||
|
||
QualifierKey { | ||
identifier | string | ||
} | ||
|
||
QualifierValue { | ||
freetext | Group | ||
} | ||
|
||
freetext { | ||
(identifier | string | number) Wildcard? | ||
} | ||
|
||
@tokens { | ||
Identifier { $[a-zA-Z_\-0-9]+ } | ||
identifier { $[a-zA-ZåäöÅÄÖ]+ } | ||
|
||
string { '"' (!["\\] | "\\" _)* '"' } | ||
|
||
number { @digit+ } | ||
|
||
EqualOperator { ":" | "=" } | ||
|
||
CompareOperator { ">" | "<" | ">=" | "<=" } | ||
|
||
String { '"' (!["\\] | "\\" _)* '"' } | ||
BooleanOperator { "AND" | "OR" | "NOT" } | ||
|
||
Boolean { "#t" | "#f" } | ||
Wildcard { "*"+ } | ||
|
||
LineComment { ";" ![\n]* } | ||
reserved { "includeEplikt" | "includePreliminary" } | ||
|
||
space { $[ \t\n\r]+ } | ||
space { @whitespace+ } | ||
|
||
"(" ")" | ||
@precedence {BooleanOperator, reserved, identifier} | ||
} | ||
|
||
@detectDelim |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,171 @@ | ||
# Booleans | ||
# Freetext words | ||
|
||
#t | ||
#f | ||
Astrid lindgren | ||
|
||
==> | ||
|
||
Program(Boolean, Boolean) | ||
Query() | ||
|
||
# Identifiers | ||
|
||
one | ||
Two_Three | ||
# Freetext string | ||
|
||
"2001: A Space Odyssey" | ||
|
||
==> | ||
|
||
Query() | ||
|
||
|
||
# Freetext with Wildcard | ||
|
||
Astrid lind* | ||
|
||
==> | ||
|
||
Query(Wildcard) | ||
|
||
|
||
# Qualifier with EqualOperator | ||
|
||
ÅR:2024 | ||
|
||
==> | ||
|
||
Query( | ||
Qualifier(QualifierKey,EqualOperator,QualifierValue) | ||
) | ||
|
||
|
||
# Qualifier with CompareOperator | ||
|
||
ÅR>2024 | ||
ÅR<=2024 | ||
|
||
==> | ||
|
||
Program(Identifier, Identifier) | ||
Query( | ||
Qualifier(QualifierKey,CompareOperator,QualifierValue) | ||
Qualifier(QualifierKey,CompareOperator,QualifierValue) | ||
) | ||
|
||
|
||
# Qualifier with string key | ||
|
||
"rdf:type":Text | ||
|
||
==> | ||
|
||
Query( | ||
Qualifier(QualifierKey,EqualOperator,QualifierValue) | ||
) | ||
|
||
|
||
# Qualifier with string value | ||
|
||
contributor:"Astrid Lindgren" | ||
|
||
==> | ||
|
||
Query( | ||
Qualifier(QualifierKey,EqualOperator,QualifierValue) | ||
) | ||
|
||
|
||
# Qualifier linked | ||
|
||
contributor:"libris:fcrtpljz1qp2bdv#it" | ||
|
||
==> | ||
|
||
Query( | ||
Qualifier(QualifierKey,EqualOperator,QualifierValue) | ||
) | ||
|
||
|
||
# Strings | ||
# BooleanQuery | ||
|
||
"hello" | ||
"one\"\\two" | ||
sommar OR vinter NOT vår | ||
|
||
==> | ||
|
||
Program(String, String) | ||
Query( | ||
BooleanQuery(BooleanOperator,BooleanOperator) | ||
) | ||
|
||
|
||
# BooleanQuery - erroneous | ||
|
||
OR AND sommar | ||
|
||
==> | ||
|
||
Query( | ||
⚠(BooleanOperator),⚠(BooleanOperator) | ||
) | ||
|
||
|
||
# Combined: Qualifier and Freetext | ||
|
||
contributor:"Astrid Lindgren" Pippi Långstrump | ||
|
||
==> | ||
|
||
Query( | ||
Qualifier(QualifierKey,EqualOperator,QualifierValue) | ||
) | ||
|
||
|
||
# Combined: Freetext BooleanQuery (Qualifier NOT Qualifier) | ||
|
||
träd* bibliografi:"sigel:DST" NOT typ:Text | ||
|
||
==> | ||
|
||
Query( | ||
Wildcard,BooleanQuery(Qualifier(...),BooleanOperator,Qualifier(...)) | ||
) | ||
|
||
|
||
# Combined: Freetext Qualifier (Group with BooleanQuery) Qualifier | ||
|
||
pippi långstrump språk:(engelska OR franska) ÅR>2002 | ||
|
||
==> | ||
|
||
Query( | ||
Qualifier( | ||
QualifierKey,EqualOperator,QualifierValue( | ||
Group( | ||
BooleanQuery(BooleanOperator) | ||
) | ||
) | ||
), | ||
Qualifier(...) | ||
) | ||
|
||
|
||
# Other filters: cover image | ||
|
||
image:* | ||
|
||
==> | ||
|
||
Query(Qualifier(...)) | ||
|
||
|
||
# Other filters: include E-plikt | ||
|
||
Pippi includeEplikt | ||
|
||
==> | ||
|
||
Query(Qualifier) | ||
|
||
|
||
# Applications | ||
# Other filters: include preliminary | ||
|
||
(begin | ||
(when #t | ||
(print (concat "hello" " " "world"))) | ||
(print "DONE")) | ||
includePreliminary Pippi | ||
|
||
==> | ||
|
||
Program(Application( | ||
Identifier, | ||
Application(Identifier, Boolean, Application( | ||
Identifier, Application(Identifier, String, String, String))) | ||
Application(Identifier, String))) | ||
Query(Qualifier) |
Oops, something went wrong.