Skip to content

Commit 841c391

Browse files
authored
Basic lexer for Microsoft Power Query M (#462)
1 parent d13f838 commit 841c391

File tree

3 files changed

+205
-0
lines changed

3 files changed

+205
-0
lines changed

Diff for: lexers/p/powerquery.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package p
2+
3+
import (
4+
. "github.com/alecthomas/chroma" // nolint
5+
"github.com/alecthomas/chroma/lexers/internal"
6+
)
7+
8+
// PowerQuery lexer.
9+
var PowerQuery = internal.Register(MustNewLazyLexer(
10+
&Config{
11+
Name: "PowerQuery",
12+
Aliases: []string{"powerquery", "pq"},
13+
Filenames: []string{"*.pq"},
14+
MimeTypes: []string{"text/x-powerquery"},
15+
DotAll: true,
16+
CaseInsensitive: true,
17+
},
18+
powerqueryRules,
19+
))
20+
21+
func powerqueryRules() Rules {
22+
return Rules{
23+
"root": {
24+
{`\s+`, Text, nil},
25+
{`//.*?\n`, CommentSingle, nil},
26+
{`/\*.*?\*/`, CommentMultiline, nil},
27+
{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
28+
{`(and|as|each|else|error|false|if|in|is|let|meta|not|null|or|otherwise|section|shared|then|true|try|type)\b`, Keyword, nil},
29+
{`(#binary|#date|#datetime|#datetimezone|#duration|#infinity|#nan|#sections|#shared|#table|#time)\b`, KeywordType, nil},
30+
{`(([a-zA-Z]|_)[\w|._]*|#"[^"]+")`, Name, nil},
31+
{`0[xX][0-9a-fA-F][0-9a-fA-F_]*[lL]?`, LiteralNumberHex, nil},
32+
{`([0-9]+\.[0-9]+|\.[0-9]+)([eE][0-9]+)?`, LiteralNumberFloat, nil},
33+
{`[0-9]+`, LiteralNumberInteger, nil},
34+
{`[\(\)\[\]\{\}]`, Punctuation, nil},
35+
{`\.\.|\.\.\.|=>|<=|>=|<>|[@!?,;=<>\+\-\*\/&]`, Operator, nil},
36+
},
37+
}
38+
}

Diff for: lexers/testdata/powerquery.actual

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
let
2+
GetLabel = (subject as text) as nullable table =>
3+
let
4+
// Request Ntriples from the LDF Service
5+
Options = [Headers = [#"Accept"="text/csv"]],
6+
FixedSubject = if Text.At(subject,0) <> "<" then Text.Combine({"<",subject,">"}) else subject,
7+
Query = Text.Combine({"SELECT ?label WHERE {
8+
SERVICE wikibase:label {
9+
bd:serviceParam wikibase:language ""en"" .
10+
",FixedSubject," <http://www.w3.org/2000/01/rdf-schema#label> ?label
11+
}
12+
}"}),
13+
/* this is a multiline comment, see https://docs.microsoft.com/en-us/powerquery-m/comments
14+
*/
15+
url = Text.Combine({"https://query.wikidata.org/sparql?",Uri.BuildQueryString([query=Query])}),
16+
data = Csv.Document(Web.Contents(url,Options)),
17+
promoted = Table.PromoteHeaders(data, [PromoteAllScalars=true])
18+
in
19+
promoted
20+
in
21+
GetLabel

Diff for: lexers/testdata/powerquery.expected

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
[
2+
{"type":"Keyword","value":"let"},
3+
{"type":"Text","value":"\n "},
4+
{"type":"Name","value":"GetLabel"},
5+
{"type":"Text","value":" "},
6+
{"type":"Operator","value":"="},
7+
{"type":"Text","value":" "},
8+
{"type":"Punctuation","value":"("},
9+
{"type":"Name","value":"subject"},
10+
{"type":"Text","value":" "},
11+
{"type":"Keyword","value":"as"},
12+
{"type":"Text","value":" "},
13+
{"type":"Name","value":"text"},
14+
{"type":"Punctuation","value":")"},
15+
{"type":"Text","value":" "},
16+
{"type":"Keyword","value":"as"},
17+
{"type":"Text","value":" "},
18+
{"type":"Name","value":"nullable"},
19+
{"type":"Text","value":" "},
20+
{"type":"Name","value":"table"},
21+
{"type":"Text","value":" "},
22+
{"type":"Operator","value":"=\u003e"},
23+
{"type":"Text","value":"\n "},
24+
{"type":"Keyword","value":"let"},
25+
{"type":"Text","value":" \n "},
26+
{"type":"CommentSingle","value":"// Request Ntriples from the LDF Service\n"},
27+
{"type":"Text","value":" "},
28+
{"type":"Name","value":"Options"},
29+
{"type":"Text","value":" "},
30+
{"type":"Operator","value":"="},
31+
{"type":"Text","value":" "},
32+
{"type":"Punctuation","value":"["},
33+
{"type":"Name","value":"Headers"},
34+
{"type":"Text","value":" "},
35+
{"type":"Operator","value":"="},
36+
{"type":"Text","value":" "},
37+
{"type":"Punctuation","value":"["},
38+
{"type":"Name","value":"#\"Accept\""},
39+
{"type":"Operator","value":"="},
40+
{"type":"LiteralString","value":"\"text/csv\""},
41+
{"type":"Punctuation","value":"]]"},
42+
{"type":"Operator","value":","},
43+
{"type":"Text","value":"\n "},
44+
{"type":"Name","value":"FixedSubject"},
45+
{"type":"Text","value":" "},
46+
{"type":"Operator","value":"="},
47+
{"type":"Text","value":" "},
48+
{"type":"Keyword","value":"if"},
49+
{"type":"Text","value":" "},
50+
{"type":"Name","value":"Text.At"},
51+
{"type":"Punctuation","value":"("},
52+
{"type":"Name","value":"subject"},
53+
{"type":"Operator","value":","},
54+
{"type":"LiteralNumberInteger","value":"0"},
55+
{"type":"Punctuation","value":")"},
56+
{"type":"Text","value":" "},
57+
{"type":"Operator","value":"\u003c\u003e"},
58+
{"type":"Text","value":" "},
59+
{"type":"LiteralString","value":"\"\u003c\""},
60+
{"type":"Text","value":" "},
61+
{"type":"Keyword","value":"then"},
62+
{"type":"Text","value":" "},
63+
{"type":"Name","value":"Text.Combine"},
64+
{"type":"Punctuation","value":"({"},
65+
{"type":"LiteralString","value":"\"\u003c\""},
66+
{"type":"Operator","value":","},
67+
{"type":"Name","value":"subject"},
68+
{"type":"Operator","value":","},
69+
{"type":"LiteralString","value":"\"\u003e\""},
70+
{"type":"Punctuation","value":"})"},
71+
{"type":"Text","value":" "},
72+
{"type":"Keyword","value":"else"},
73+
{"type":"Text","value":" "},
74+
{"type":"Name","value":"subject"},
75+
{"type":"Operator","value":","},
76+
{"type":"Text","value":"\n "},
77+
{"type":"Name","value":"Query"},
78+
{"type":"Text","value":" "},
79+
{"type":"Operator","value":"="},
80+
{"type":"Text","value":" "},
81+
{"type":"Name","value":"Text.Combine"},
82+
{"type":"Punctuation","value":"({"},
83+
{"type":"LiteralString","value":"\"SELECT ?label WHERE {\n SERVICE wikibase:label {\n bd:serviceParam wikibase:language \"\"en\"\" .\n \""},
84+
{"type":"Operator","value":","},
85+
{"type":"Name","value":"FixedSubject"},
86+
{"type":"Operator","value":","},
87+
{"type":"LiteralString","value":"\" \u003chttp://www.w3.org/2000/01/rdf-schema#label\u003e ?label\n }\n }\""},
88+
{"type":"Punctuation","value":"})"},
89+
{"type":"Operator","value":","},
90+
{"type":"Text","value":"\n "},
91+
{"type":"CommentMultiline","value":"/* this is a multiline comment, see https://docs.microsoft.com/en-us/powerquery-m/comments\n */"},
92+
{"type":"Text","value":"\n "},
93+
{"type":"Name","value":"url"},
94+
{"type":"Text","value":" "},
95+
{"type":"Operator","value":"="},
96+
{"type":"Text","value":" "},
97+
{"type":"Name","value":"Text.Combine"},
98+
{"type":"Punctuation","value":"({"},
99+
{"type":"LiteralString","value":"\"https://query.wikidata.org/sparql?\""},
100+
{"type":"Operator","value":","},
101+
{"type":"Name","value":"Uri.BuildQueryString"},
102+
{"type":"Punctuation","value":"(["},
103+
{"type":"Name","value":"query"},
104+
{"type":"Operator","value":"="},
105+
{"type":"Name","value":"Query"},
106+
{"type":"Punctuation","value":"])})"},
107+
{"type":"Operator","value":","},
108+
{"type":"Text","value":"\n "},
109+
{"type":"Name","value":"data"},
110+
{"type":"Text","value":" "},
111+
{"type":"Operator","value":"="},
112+
{"type":"Text","value":" "},
113+
{"type":"Name","value":"Csv.Document"},
114+
{"type":"Punctuation","value":"("},
115+
{"type":"Name","value":"Web.Contents"},
116+
{"type":"Punctuation","value":"("},
117+
{"type":"Name","value":"url"},
118+
{"type":"Operator","value":","},
119+
{"type":"Name","value":"Options"},
120+
{"type":"Punctuation","value":"))"},
121+
{"type":"Operator","value":","},
122+
{"type":"Text","value":"\n "},
123+
{"type":"Name","value":"promoted"},
124+
{"type":"Text","value":" "},
125+
{"type":"Operator","value":"="},
126+
{"type":"Text","value":" "},
127+
{"type":"Name","value":"Table.PromoteHeaders"},
128+
{"type":"Punctuation","value":"("},
129+
{"type":"Name","value":"data"},
130+
{"type":"Operator","value":","},
131+
{"type":"Text","value":" "},
132+
{"type":"Punctuation","value":"["},
133+
{"type":"Name","value":"PromoteAllScalars"},
134+
{"type":"Operator","value":"="},
135+
{"type":"Keyword","value":"true"},
136+
{"type":"Punctuation","value":"])"},
137+
{"type":"Text","value":"\n "},
138+
{"type":"Keyword","value":"in"},
139+
{"type":"Text","value":" \n "},
140+
{"type":"Name","value":"promoted"},
141+
{"type":"Text","value":" \n"},
142+
{"type":"Keyword","value":"in"},
143+
{"type":"Text","value":"\n "},
144+
{"type":"Name","value":"GetLabel"},
145+
{"type":"Text","value":" "}
146+
]

0 commit comments

Comments
 (0)