Skip to content

Commit 40e5e99

Browse files
authored
Add JSONata Lexer (#983)
Add lexer for [JSONata](https://docs.jsonata.org/overview.html) including test data.
1 parent 8c88943 commit 40e5e99

File tree

3 files changed

+456
-0
lines changed

3 files changed

+456
-0
lines changed

lexers/embedded/jsonata.xml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<lexer>
2+
<config>
3+
<name>JSONata</name>
4+
<alias>jsonata</alias>
5+
<filename>*.jsonata</filename>
6+
<dot_all>true</dot_all>
7+
</config>
8+
<rules>
9+
<state name="root">
10+
<rule pattern="/\*.*?\*/">
11+
<token type="CommentMultiline"/>
12+
</rule>
13+
<rule pattern="[{}()\[\]:;,\.=]">
14+
<token type="Punctuation"/>
15+
</rule>
16+
<rule pattern="\.\."> // Spread operator
17+
<token type="Operator"/>
18+
</rule>
19+
<rule pattern="\^(?=\()"> // Sort operator
20+
<token type="Operator"/>
21+
</rule>
22+
<rule pattern="\*\*|\*(?=\.)|\*"> // Descendant | Wildcard | Multiplication
23+
<token type="Operator"/>
24+
</rule>
25+
<rule pattern="\/(?!\*)"> // Division
26+
<token type="Operator"/>
27+
</rule>
28+
<rule pattern="[&lt;&gt;!]=?"> // Comparison operators
29+
<token type="Operator"/>
30+
</rule>
31+
<rule pattern="~>">
32+
<token type="Operator"/>
33+
</rule>
34+
<rule pattern="\b(and|or|in)\b">
35+
<token type="Operator"/>
36+
</rule>
37+
<rule pattern="[%@#&amp;?]|\+(?!\d)|\-(?!\d)">
38+
<token type="Operator"/>
39+
</rule>
40+
<rule pattern="\$[a-zA-Z0-9_]*(?![\w\(])">
41+
<token type="NameVariable"/>
42+
</rule>
43+
<rule pattern="\$\w*(?=\()">
44+
<token type="NameFunction"/>
45+
</rule>
46+
<rule pattern="\s+">
47+
<token type="Text"/>
48+
</rule>
49+
<rule pattern="(true|false)\b">
50+
<token type="KeywordConstant"/>
51+
</rule>
52+
<rule pattern="\b(function)\b">
53+
<token type="Keyword"/>
54+
</rule>
55+
<rule pattern="(\+|-)?(0|[1-9]\d*)(\.\d+[eE](\+|-)?\d+|[eE](\+|-)?\d+|\.\d+)">
56+
<token type="LiteralNumberFloat"/>
57+
</rule>
58+
<rule pattern="(\+|-)?(0|[1-9]\d*)">
59+
<token type="LiteralNumberInteger"/>
60+
</rule>
61+
<!-- NOTE: This expression matches all object keys (NameTags), which are essentially strings with double quotes
62+
that should only be captured on the left side of a colon (:) within a JSON-like object.
63+
Therefore, this expression must preceed the one for all LiteralStringDouble -->
64+
<rule pattern="&#34;(\\.|[^\\&#34;\r\n])*&#34;(?=\s*:)">
65+
<token type="NameTag"/>
66+
</rule>
67+
<rule pattern="&#34;(\\\\|\\&#34;|[^&#34;])*&#34;">
68+
<token type="LiteralStringDouble"/>
69+
</rule>
70+
<rule pattern="&#39;(\\|\\&#39;|[^&#39;])*&#39;">
71+
<token type="LiteralStringSingle"/>
72+
</rule>
73+
<rule pattern="`.*`">
74+
<token type="LiteralStringBacktick"/>
75+
</rule>
76+
<!-- NOTE: This expression matches everything remaining, which should be only JSONata names.
77+
Therefore, it has been left as last intentionally -->
78+
<rule pattern="[a-zA-Z0-9_]*">
79+
<token type="Name"/>
80+
</rule>
81+
</state>
82+
</rules>
83+
</lexer>

lexers/testdata/jsonata.actual

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
(
2+
$.a.b.c;
3+
4+
/* Example json input */
5+
$jsonInput := {
6+
"firstName": "JSONata",
7+
"lastName": "User",
8+
"age": 25,
9+
"skills": ["programming", "cooking"],
10+
"over 18": true,
11+
"coordinates": { "latitude": 51.509865, "longitude": -0.118092 }
12+
};
13+
14+
/* Example function definition */
15+
$getGreeting := function($firstName, $lastName) {
16+
"Hello, " & $firstName & " " & $lastName
17+
};
18+
19+
$isAdult := $jsonInput.`over 18`;
20+
21+
/* Example json transformation */
22+
$jsonInput.{
23+
"fullName": $join([firstName, lastName], " "),
24+
"greeting": $getGreeting(firstName, lastName),
25+
"skills": $append(skills, "jsonata"),
26+
"isAdult": $isAdult
27+
}
28+
29+
$spreadOp = [1..5];
30+
$sortOperator := Account.Order^(>Price, <Quantity);
31+
$descendants := **.Postcode;
32+
$math:= 10 / 5 * 2 + 4 - 2 % 2;
33+
$conditions := 20 > 10 and 10 > 20 ? 20 = 20 or 20 != 10 : 10 in [1,10,20];
34+
$chainOperator := " trim " ~> $trim();
35+
$sum := +10 + -5 - +3 + $x / $y;
36+
$multiplyVars := $a*$b * $c;
37+
$wildcard := $.wild.*.card;
38+
)

0 commit comments

Comments
 (0)