Created
December 9, 2022 08:53
-
-
Save jackalcooper/73eed504164250f84a106b6950527eac to your computer and use it in GitHub Desktop.
Zig parser in elixir based on https://github.com/ziglang/zig-spec/blob/master/grammar/grammar.y
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
defmodule Kinda.Parser do | |
import NimbleParsec | |
# *** Tokens *** | |
container_doc_comment = | |
string("//!") |> repeat(ascii_char([?^, ?\n])) |> repeat([?\s, ?\n]) |> times(min: 1) | |
doc_comment = | |
string("///") |> repeat(ascii_char([?^, ?\n])) |> repeat([?\s, ?\n]) |> times(min: 1) | |
line_comment = | |
choice([ | |
string("//") |> lookahead_not(ascii_char([?!, ?/])) |> repeat(ascii_char([?^, ?\n])), | |
string("////") |> lookahead_not(ascii_char([?\n])) |> repeat(ascii_char([?^, ?\n])) | |
]) | |
skip = choice([ascii_char([?\s, ?\n]), line_comment]) |> repeat | |
builtinidentifier = | |
string("@") | |
|> ascii_char([?A..?Z, ?a..?z, ?_]) | |
|> concat(ascii_char([?A..?Z, ?a..?z, ?0..?9, ?_]) |> repeat) | |
|> concat(skip) | |
ampersand = string("&") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
ampersandequal = string("&=") |> concat(skip) | |
asterisk = string("*") |> lookahead_not(ascii_char([?*, ?%, ?=])) |> concat(skip) | |
asterisk2 = string("**") |> concat(skip) | |
asteriskequal = string("*=") |> concat(skip) | |
asteriskpercent = string("*%") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
asteriskpercentequal = string("*%=") |> concat(skip) | |
caret = string("^") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
caretequal = string("^=") |> concat(skip) | |
colon = string(":") |> concat(skip) | |
comma = string(",") |> concat(skip) | |
dot = string(".") |> lookahead_not(ascii_char([?*, ?., ??])) |> concat(skip) | |
dot2 = string("..") |> lookahead_not(ascii_char([?.])) |> concat(skip) | |
dot3 = string("...") |> concat(skip) | |
dotasterisk = string(".*") |> concat(skip) | |
dotquestionmark = string(".?") |> concat(skip) | |
equal = string("=") |> lookahead_not(ascii_char([?>, ?=])) |> concat(skip) | |
equalequal = string("==") |> concat(skip) | |
equalrarrow = string("=>") |> concat(skip) | |
exclamationmark = string("!") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
exclamationmarkequal = string("!=") |> concat(skip) | |
larrow = string("<") |> lookahead_not(ascii_char([?<, ?=])) |> concat(skip) | |
larrow2 = string("<<") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
larrow2equal = string("<<=") |> concat(skip) | |
larrowequal = string("<=") |> concat(skip) | |
lbrace = string("{") |> concat(skip) | |
lbracket = string("[") |> concat(skip) | |
lparen = string("(") |> concat(skip) | |
minus = string("-") |> lookahead_not(ascii_char([?%, ?=, ?>])) |> concat(skip) | |
minusequal = string("-=") |> concat(skip) | |
minuspercent = string("-%") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
minuspercentequal = string("-%=") |> concat(skip) | |
minusrarrow = string("->") |> concat(skip) | |
percent = string("%") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
percentequal = string("%=") |> concat(skip) | |
pipe = string("|") |> lookahead_not(ascii_char([?|, ?=])) |> concat(skip) | |
pipe2 = string("||") |> concat(skip) | |
pipeequal = string("|=") |> concat(skip) | |
plus = string("+") |> lookahead_not(ascii_char([?%, ?+, ?=])) |> concat(skip) | |
plus2 = string("++") |> concat(skip) | |
plusequal = string("+=") |> concat(skip) | |
pluspercent = string("+%") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
pluspercentequal = string("+%=") |> concat(skip) | |
letterc = string("c") |> concat(skip) | |
questionmark = string("?") |> concat(skip) | |
rarrow = string(">") |> lookahead_not(ascii_char([?>, ?=])) |> concat(skip) | |
rarrow2 = string(">>") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
rarrow2equal = string(">>=") |> concat(skip) | |
rarrowequal = string(">=") |> concat(skip) | |
rbrace = string("}") |> concat(skip) | |
rbracket = string("]") |> concat(skip) | |
rparen = string(")") |> concat(skip) | |
semicolon = string(";") |> concat(skip) | |
slash = string("/") |> lookahead_not(ascii_char([?=])) |> concat(skip) | |
slashequal = string("/=") |> concat(skip) | |
tilde = string("~") |> concat(skip) | |
end_of_word = lookahead_not(ascii_char([?a..?z, ?A..?Z, ?0..?9, ?_])) |> concat(skip) | |
keyword_align = string("align") |> concat(end_of_word) | |
keyword_allowzero = string("allowzero") |> concat(end_of_word) | |
keyword_and = string("and") |> concat(end_of_word) | |
keyword_anyframe = string("anyframe") |> concat(end_of_word) | |
keyword_anytype = string("anytype") |> concat(end_of_word) | |
keyword_asm = string("asm") |> concat(end_of_word) | |
keyword_async = string("async") |> concat(end_of_word) | |
keyword_await = string("await") |> concat(end_of_word) | |
keyword_break = string("break") |> concat(end_of_word) | |
keyword_callconv = string("callconv") |> concat(end_of_word) | |
keyword_catch = string("catch") |> concat(end_of_word) | |
keyword_comptime = string("comptime") |> concat(end_of_word) | |
keyword_const = string("const") |> concat(end_of_word) | |
keyword_continue = string("continue") |> concat(end_of_word) | |
keyword_defer = string("defer") |> concat(end_of_word) | |
keyword_else = string("else") |> concat(end_of_word) | |
keyword_enum = string("enum") |> concat(end_of_word) | |
keyword_errdefer = string("errdefer") |> concat(end_of_word) | |
keyword_error = string("error") |> concat(end_of_word) | |
keyword_export = string("export") |> concat(end_of_word) | |
keyword_extern = string("extern") |> concat(end_of_word) | |
keyword_fn = string("fn") |> concat(end_of_word) | |
keyword_for = string("for") |> concat(end_of_word) | |
keyword_if = string("if") |> concat(end_of_word) | |
keyword_inline = string("inline") |> concat(end_of_word) | |
keyword_noalias = string("noalias") |> concat(end_of_word) | |
keyword_nosuspend = string("nosuspend") |> concat(end_of_word) | |
keyword_noinline = string("noinline") |> concat(end_of_word) | |
keyword_opaque = string("opaque") |> concat(end_of_word) | |
keyword_or = string("or") |> concat(end_of_word) | |
keyword_orelse = string("orelse") |> concat(end_of_word) | |
keyword_packed = string("packed") |> concat(end_of_word) | |
keyword_pub = string("pub") |> concat(end_of_word) | |
keyword_resume = string("resume") |> concat(end_of_word) | |
keyword_return = string("return") |> concat(end_of_word) | |
keyword_linksection = string("linksectio") |> concat(end_of_word) | |
keyword_struct = string("struct") |> concat(end_of_word) | |
keyword_suspend = string("suspend") |> concat(end_of_word) | |
keyword_switch = string("switch") |> concat(end_of_word) | |
keyword_test = string("test") |> concat(end_of_word) | |
keyword_threadlocal = string("threadloca") |> concat(end_of_word) | |
keyword_try = string("try") |> concat(end_of_word) | |
keyword_union = string("union") |> concat(end_of_word) | |
keyword_unreachable = string("unreachabl") |> concat(end_of_word) | |
keyword_usingnamespace = string("usingnamespac") |> concat(end_of_word) | |
keyword_var = string("var") |> concat(end_of_word) | |
keyword_volatile = string("volatile") |> concat(end_of_word) | |
keyword_while = string("while") |> concat(end_of_word) | |
keyword = | |
choice([ | |
keyword_align, | |
keyword_allowzero, | |
keyword_and, | |
keyword_anyframe, | |
keyword_anytype, | |
keyword_asm, | |
keyword_async, | |
keyword_await, | |
keyword_break, | |
keyword_callconv, | |
keyword_catch, | |
keyword_comptime, | |
keyword_const, | |
keyword_continue, | |
keyword_defer, | |
keyword_else, | |
keyword_enum, | |
keyword_errdefer, | |
keyword_error, | |
keyword_export, | |
keyword_extern, | |
keyword_fn, | |
keyword_for, | |
keyword_if, | |
keyword_inline, | |
keyword_noalias, | |
keyword_nosuspend, | |
keyword_noinline, | |
keyword_opaque, | |
keyword_or, | |
keyword_orelse, | |
keyword_packed, | |
keyword_pub, | |
keyword_resume, | |
keyword_return, | |
keyword_linksection, | |
keyword_struct, | |
keyword_suspend, | |
keyword_switch, | |
keyword_test, | |
keyword_threadlocal, | |
keyword_try, | |
keyword_union, | |
keyword_unreachable, | |
keyword_usingnamespace, | |
keyword_var, | |
keyword_volatile, | |
keyword_while | |
]) | |
eof = eos() | |
bin = ascii_char([?0..?1]) | |
bin_ = optional(string("_")) |> concat(bin) | |
oct = ascii_char([?0..?7]) | |
oct_ = optional(string("_")) |> concat(oct) | |
hex = ascii_char([?0..?9, ?a..?f, ?A..?F]) | |
hex_ = optional(string("_")) |> concat(hex) | |
dec = ascii_char([?0..?9]) | |
dec_ = optional(string("_")) |> concat(dec) | |
bin_int = bin |> concat(repeat(bin_)) | |
oct_int = oct |> concat(repeat(oct_)) | |
dec_int = dec |> concat(repeat(dec_)) | |
hex_int = hex |> concat(repeat(hex_)) | |
mb_utf8_literal = utf8_char([]) | |
ascii_char_not_nl_slash_squote = ascii_char([0..11, 13..46, 46..50, 50..133, 135..177]) | |
char_escape = | |
choice([ | |
string("\\x") |> concat(hex) |> concat(hex), | |
string("\\u") |> concat(times(hex, min: 1)) |> concat(string("}")), | |
string("\\") |> concat(hex) |> concat(ascii_char([?n, ?r, ?\\, ?t, ?', ?"])) | |
]) | |
char_char = | |
choice([ | |
mb_utf8_literal, | |
char_escape, | |
ascii_char_not_nl_slash_squote | |
]) | |
string_char = choice([char_escape, ascii_char([?^, ?\\, ?", ?\n])]) | |
line_string = | |
string("\\\\") | |
|> concat(ascii_char([?^, ?\n]) |> repeat) | |
|> concat(ascii_char([?\s, ?\n]) |> repeat) | |
|> repeat | |
char_literal = string("'") |> concat(char_char) |> string("'") |> concat(skip) | |
float = | |
choice([ | |
string("0x") | |
|> concat(hex_int) | |
|> string(".") | |
|> concat(hex_int) | |
|> optional(ascii_char([?p, ?P]) |> optional(ascii_char([?-, ?+])) |> concat(hex_int)) | |
|> concat(skip), | |
dec_int | |
|> string(".") | |
|> concat(dec_int) | |
|> optional(ascii_char([?e, ?E]) |> optional(ascii_char([?-, ?+])) |> concat(dec_int)) | |
|> concat(skip), | |
string("0x") | |
|> concat(hex_int) | |
|> ascii_char([?p, ?P]) | |
|> optional(ascii_char([?-, ?+])) | |
|> concat(dec_int) | |
|> concat(skip), | |
dec_int | |
|> ascii_char([?e, ?E]) | |
|> optional(ascii_char([?-, ?+])) | |
|> concat(dec_int) | |
|> concat(skip) | |
]) | |
integer = | |
choice([ | |
string("0b") |> concat(bin_int) |> concat(skip), | |
string("0o") |> concat(oct_int) |> concat(skip), | |
string("0x") |> concat(hex_int) |> concat(skip), | |
dec_int |> concat(skip) | |
]) | |
stringliteralsingle = | |
string("\"") |> concat(repeat(string_char)) |> concat(string("\"")) |> concat(skip) | |
stringliteral = | |
choice([ | |
stringliteralsingle, | |
line_string |> concat(skip) |> times(min: 1) | |
]) | |
identifier = | |
choice([ | |
lookahead_not(keyword) | |
|> concat(ascii_char([?a..?z, ?A..?Z, ?_])) | |
|> concat(ascii_char([?A..?Z, ?a..?z, ?0..?9, ?_]) |> repeat) | |
|> concat(skip), | |
string("@\"") |> concat(string_char |> repeat) |> concat(string("\"")) |> concat(skip) | |
]) | |
# *** forward declare *** | |
expr = parsec(:expr_parsec) | |
typeexpr = parsec(:typeexpr_parsec) | |
assignexpr = parsec(:assignexpr_parsec) | |
stringlist = parsec(:stringlist_parsec) | |
asminputlist = parsec(:asminputlist_parsec) | |
asmoutputlist = parsec(:asmoutputlist_parsec) | |
ifexpr = parsec(:ifexpr_parsec) | |
ptrpayload = parsec(:ptrpayload_parsec) | |
slicetypestart = parsec(:slicetypestart_parsec) | |
bytealign = parsec(:bytealign_parsec) | |
ptrtypestart = parsec(:ptrtypestart_parsec) | |
arraytypestart = parsec(:arraytypestart_parsec) | |
exprlist = parsec(:exprlist_parsec) | |
containermembers = parsec(:containermembers_parsec) | |
loopexpr = parsec(:loopexpr_parsec) | |
block = parsec(:block_parsec) | |
statement = parsec(:statement_parsec) | |
containerdeclarations = parsec(:containerdeclarations_parsec) | |
topleveldecl = parsec(:topleveldecl_parsec) | |
# *** assembly *** | |
asmclobbers = colon |> concat(stringlist) | |
asminput = colon |> concat(asminputlist) |> optional(asmclobbers) | |
asmoutput = colon |> concat(asmoutputlist) |> optional(asminput) | |
asmexpr = | |
keyword_asm | |
|> optional(keyword_volatile) | |
|> concat(lparen) | |
|> concat(expr) | |
|> optional(asmoutput) | |
|> concat(rparen) | |
asmoutputitem = | |
lbracket | |
|> concat(identifier) | |
|> concat(rbracket) | |
|> concat(stringliteral) | |
|> concat(lparen) | |
|> concat(minusrarrow |> choice([typeexpr, identifier])) | |
|> concat(rparen) | |
asminputitem = | |
lbracket | |
|> concat(identifier) | |
|> concat(rbracket) | |
|> concat(stringliteral) | |
|> concat(lparen) | |
|> concat(expr) | |
|> concat(rparen) | |
# *** helper grammar *** | |
breaklabel = colon |> concat(identifier) | |
blocklabel = identifier |> concat(colon) | |
fieldinit = dot |> concat(identifier) |> concat(equal) |> concat(expr) | |
whilecontinueexpr = colon |> concat(lparen) |> concat(assignexpr) |> concat(rparen) | |
linksection = keyword_linksection |> concat(lparen) |> concat(expr) |> concat(rparen) | |
# fn specific | |
callconv = keyword_callconv |> concat(lparen) |> concat(expr) |> concat(rparen) | |
paramtype = choice([keyword_anytype, typeexpr]) | |
paramdecl = | |
choice([ | |
optional(doc_comment) | |
|> optional(choice([keyword_noalias, keyword_comptime])) | |
|> optional(identifier |> concat(colon)) | |
|> concat(paramtype), | |
dot3 | |
]) | |
# control flow prefixes | |
ifprefix = | |
keyword_if |> concat(lparen) |> concat(expr) |> concat(rparen) |> optional(ptrpayload) | |
whileprefix = | |
keyword_while | |
|> concat(lparen) | |
|> concat(expr) | |
|> concat(rparen) | |
|> optional(ptrpayload) | |
|> optional(whilecontinueexpr) | |
ptrindexpayload = | |
pipe | |
|> optional(asterisk) | |
|> concat(identifier) | |
|> optional(comma |> concat(identifier)) | |
|> concat(pipe) | |
forprefix = | |
keyword_for |> concat(lparen) |> concat(expr) |> concat(rparen) |> concat(ptrindexpayload) | |
# payloads | |
payload = pipe |> concat(identifier) |> concat(pipe) | |
ptrpayload = pipe |> optional(asterisk) |> concat(identifier) |> concat(pipe) | |
# switch specific | |
switchitem = expr |> optional(dot3 |> concat(expr)) | |
switchcase = | |
choice([ | |
switchitem |> repeat(comma |> concat(switchitem)) |> optional(comma), | |
keyword_else | |
]) | |
switchprong = switchcase |> concat(equalrarrow) |> optional(ptrpayload) |> concat(assignexpr) | |
# operators | |
assignop = | |
choice([ | |
asteriskequal, | |
slashequal, | |
percentequal, | |
plusequal, | |
minusequal, | |
larrow2equal, | |
rarrow2equal, | |
ampersandequal, | |
caretequal, | |
pipeequal, | |
asteriskpercentequal, | |
pluspercentequal, | |
minuspercentequal, | |
equal | |
]) | |
compareop = | |
choice([ | |
equalequal, | |
exclamationmarkequal, | |
larrow, | |
rarrow, | |
larrowequal, | |
rarrowequal | |
]) | |
bitwiseop = choice([ampersand, caret, pipe, keyword_orelse, keyword_catch |> optional(payload)]) | |
bitshiftop = choice([larrow2, rarrow2]) | |
additionop = | |
choice([ | |
plus, | |
minus, | |
plus2, | |
pluspercent, | |
minuspercent | |
]) | |
multiplyop = | |
choice([ | |
pipe2, | |
asterisk, | |
slash, | |
percent, | |
asterisk2, | |
asteriskpercent | |
]) | |
prefixop = | |
choice([ | |
exclamationmark, | |
minus, | |
tilde, | |
minuspercent, | |
ampersand, | |
keyword_try, | |
keyword_await | |
]) | |
prefixtypeop = | |
choice([ | |
questionmark, | |
keyword_anyframe |> concat(minusrarrow), | |
slicetypestart | |
|> repeat(choice([bytealign, keyword_const, keyword_volatile, keyword_allowzero])), | |
ptrtypestart | |
|> repeat( | |
keyword_align | |
|> concat(lparen) | |
|> concat(expr) | |
|> optional(colon |> concat(integer) |> concat(colon) |> concat(integer)) | |
|> choice([rparen, keyword_const, keyword_volatile, keyword_allowzero]) | |
), | |
arraytypestart | |
]) | |
suffixop = | |
choice([ | |
lbracket | |
|> concat(expr) | |
|> optional(dot2 |> optional(optional(expr) |> optional(colon |> concat(expr)))) | |
|> concat(rbracket), | |
dot |> concat(identifier), | |
dotasterisk, | |
dotquestionmark | |
]) | |
fncallarguments = lparen |> concat(exprlist) |> concat(rparen) | |
# ptr specific | |
slicetypestart = lbracket |> optional(colon |> concat(expr)) |> concat(rbracket) | |
ptrtypestart = | |
choice([ | |
asterisk, | |
asterisk2, | |
lbracket | |
|> concat(asterisk) | |
|> optional(choice([letterc, colon |> concat(expr)])) | |
|> concat(rbracket) | |
]) | |
arraytypestart = lbracket |> concat(expr) |> optional(colon |> concat(expr)) |> concat(rbracket) | |
# containerdecl specific | |
containerdecltype = | |
choice([ | |
keyword_struct, | |
keyword_opaque, | |
keyword_enum |> optional(lparen |> concat(expr) |> concat(rparen)), | |
keyword_union | |
|> optional( | |
lparen | |
|> concat( | |
keyword_enum | |
|> choice([optional(lparen |> concat(expr) |> concat(rparen)), expr]) | |
) | |
|> concat(rparen) | |
) | |
]) | |
containerdeclauto = | |
containerdecltype | |
|> concat(lbrace) | |
|> optional(container_doc_comment) | |
|> concat(containermembers) | |
|> concat(rbrace) | |
# alignment | |
bytealign = keyword_align |> concat(lparen) |> concat(expr) |> concat(rparen) | |
# lists | |
identifierlist = | |
repeat(optional(doc_comment) |> concat(identifier) |> concat(comma)) | |
|> optional(optional(doc_comment) |> concat(identifier)) | |
switchpronglist = repeat(switchprong |> concat(comma)) |> optional(switchprong) | |
asmoutputlist = repeat(asmoutputitem |> concat(comma)) |> optional(asmoutputitem) | |
asminputlist = repeat(asminputitem |> concat(comma)) |> optional(asminputitem) | |
stringlist = repeat(stringliteral |> concat(comma)) |> optional(stringliteral) | |
paramdecllist = repeat(paramdecl |> concat(comma)) |> optional(paramdecl) | |
exprlist = repeat(expr |> concat(comma)) |> optional(expr) | |
# *** expression level *** | |
initlist = | |
choice([ | |
lbrace | |
|> concat(fieldinit) | |
|> repeat(comma |> concat(fieldinit)) | |
|> optional(comma) | |
|> concat(rbrace), | |
lbrace | |
|> concat(expr) | |
|> repeat(comma |> concat(expr)) | |
|> optional(comma) | |
|> concat(rbrace), | |
lbrace |> concat(rbrace) | |
]) | |
curlysuffixexpr = typeexpr |> optional(initlist) | |
primaryexpr = | |
choice([ | |
asmexpr, | |
ifexpr, | |
keyword_break |> optional(breaklabel) |> optional(expr), | |
keyword_comptime |> concat(expr), | |
keyword_nosuspend |> concat(expr), | |
keyword_continue |> optional(breaklabel), | |
keyword_resume |> concat(expr), | |
keyword_return |> optional(expr), | |
optional(blocklabel) |> concat(loopexpr), | |
block, | |
curlysuffixexpr | |
]) | |
prefixexpr = repeat(prefixop) |> concat(primaryexpr) | |
multiplyexpr = prefixexpr |> optional(multiplyop |> concat(prefixexpr)) | |
additionexpr = multiplyexpr |> optional(additionop |> concat(multiplyexpr)) | |
bitshiftexpr = additionexpr |> optional(bitshiftop |> concat(additionexpr)) | |
bitwiseexpr = bitshiftexpr |> optional(bitwiseop |> concat(bitshiftexpr)) | |
compareexpr = bitwiseexpr |> optional(compareop |> concat(bitwiseexpr)) | |
boolandexpr = compareexpr |> optional(keyword_and |> concat(compareexpr)) | |
boolorexpr = boolandexpr |> optional(keyword_or |> concat(boolandexpr)) | |
expr = boolorexpr | |
assignexpr = expr |> optional(assignop |> concat(expr)) | |
ifexpr = ifprefix |> concat(expr) |> optional([keyword_else, optional(payload), expr]) | |
block = lbrace |> repeat(statement) |> concat(rbrace) | |
forexpr = forprefix |> concat(expr) |> optional(keyword_else |> concat(expr)) | |
whileexpr = | |
whileprefix |> concat(expr) |> optional(keyword_else |> optional(payload) |> concat(expr)) | |
loopexpr = optional(keyword_inline) |> choice([forexpr, whileexpr]) | |
containerdecl = optional(choice([keyword_extern, keyword_packed])) |> concat(containerdeclauto) | |
errorsetdecl = keyword_error |> concat(lbrace) |> concat(identifierlist) |> concat(rbrace) | |
fnproto = | |
keyword_fn | |
|> optional(identifier) | |
|> concat(lparen) | |
|> concat(paramdecllist) | |
|> concat(rparen) | |
|> optional(bytealign) | |
|> optional(linksection) | |
|> optional(callconv) | |
|> optional(exclamationmark) | |
|> concat(typeexpr) | |
groupedexpr = lparen |> concat(expr) |> concat(rparen) | |
fortypeexpr = forprefix |> concat(typeexpr) |> optional(keyword_else |> concat(typeexpr)) | |
whiletypeexpr = | |
whileprefix | |
|> concat(typeexpr) | |
|> optional(keyword_else |> optional(payload) |> concat(typeexpr)) | |
looptypeexpr = optional(keyword_inline) |> choice([fortypeexpr, whiletypeexpr]) | |
labeledtypeexpr = | |
choice([ | |
blocklabel |> concat(block), | |
optional(blocklabel) |> concat(looptypeexpr) | |
]) | |
iftypeexpr = | |
ifprefix | |
|> concat(typeexpr) | |
|> optional(keyword_else |> optional(payload) |> concat(typeexpr)) | |
switchexpr = | |
keyword_switch | |
|> concat(lparen) | |
|> concat(expr) | |
|> concat(rparen) | |
|> concat(lbrace) | |
|> concat(switchpronglist) | |
|> concat(rbrace) | |
primarytypeexpr = | |
choice([ | |
builtinidentifier |> concat(fncallarguments), | |
char_literal, | |
containerdecl, | |
dot |> concat(identifier), | |
dot |> concat(initlist), | |
errorsetdecl, | |
float, | |
fnproto, | |
groupedexpr, | |
labeledtypeexpr, | |
identifier, | |
iftypeexpr, | |
integer, | |
keyword_comptime |> concat(typeexpr), | |
keyword_error |> concat(dot) |> concat(identifier), | |
keyword_anyframe, | |
keyword_unreachable, | |
stringliteral, | |
switchexpr | |
]) | |
suffixexpr = | |
choice([ | |
keyword_async |> concat(primarytypeexpr) |> repeat(suffixop) |> concat(fncallarguments), | |
primarytypeexpr |> repeat(choice([suffixop, fncallarguments])) | |
]) | |
errorunionexpr = suffixexpr |> optional(exclamationmark |> concat(typeexpr)) | |
typeexpr = repeat(prefixtypeop) |> concat(errorunionexpr) | |
# *** Top level *** | |
testdecl = | |
optional(doc_comment) | |
|> concat(keyword_test) | |
|> concat(optional(stringliteralsingle)) | |
|> concat(block) | |
toplevelcomptime = optional(doc_comment) |> concat(keyword_comptime) |> concat(block) | |
containerdeclarations = | |
choice([ | |
testdecl |> concat(containerdeclarations), | |
toplevelcomptime |> concat(containerdeclarations), | |
optional(doc_comment) | |
|> optional(keyword_pub) | |
|> concat(topleveldecl) | |
|> concat(containerdeclarations) | |
]) | |
containerfield = | |
optional(doc_comment) | |
|> optional(keyword_comptime) | |
|> concat(identifier) | |
|> optional(colon |> concat(typeexpr) |> optional(bytealign)) | |
|> optional(equal |> concat(expr)) | |
containermembers = | |
containerdeclarations | |
|> repeat(containerfield |> concat(comma)) | |
|> choice([containerfield, containerdeclarations]) | |
vardecl = | |
choice([keyword_const, keyword_var]) | |
|> concat(identifier) | |
|> optional(colon |> concat(typeexpr)) | |
|> optional(bytealign) | |
|> optional(linksection) | |
|> optional(equal |> concat(expr)) | |
|> concat(semicolon) | |
topleveldecl = | |
choice([ | |
choice([ | |
keyword_export, | |
keyword_extern |> optional(stringliteralsingle), | |
choice([keyword_inline, keyword_noinline]) | |
]) | |
|> optional | |
|> concat(fnproto) | |
|> choice([semicolon, block]), | |
choice([keyword_export, keyword_extern |> optional(stringliteralsingle)]) | |
|> optional | |
|> optional(keyword_threadlocal) | |
|> concat(vardecl), | |
keyword_usingnamespace |> concat(expr) |> concat(semicolon) | |
]) | |
# *** block level *** | |
blockexpr = optional(blocklabel) |> concat(block) | |
blockexprstatement = choice([blockexpr, assignexpr |> concat(semicolon)]) | |
ifstatement = | |
choice([ | |
ifprefix | |
|> concat(blockexpr) | |
|> optional(keyword_else |> optional(payload) |> concat(statement)), | |
ifprefix | |
|> concat(assignexpr) | |
|> choice([semicolon, keyword_else |> optional(payload) |> concat(statement)]) | |
]) | |
forstatement = | |
choice([ | |
forprefix |> concat(blockexpr) |> optional(keyword_else |> concat(statement)), | |
forprefix |> concat(assignexpr) |> choice([semicolon, keyword_else |> concat(statement)]) | |
]) | |
whilestatement = | |
choice([ | |
whileprefix | |
|> concat(blockexpr) | |
|> optional(keyword_else |> optional(payload) |> concat(statement)), | |
whileprefix | |
|> concat(assignexpr) | |
|> choice([semicolon, keyword_else |> optional(payload) |> concat(statement)]) | |
]) | |
loopstatement = optional(keyword_inline) |> choice([forstatement, whilestatement]) | |
labeledstatement = optional(blocklabel) |> choice([block, loopstatement]) | |
statement = | |
choice([ | |
optional(keyword_comptime) |> concat(vardecl), | |
keyword_comptime |> concat(blockexprstatement), | |
keyword_nosuspend |> concat(blockexprstatement), | |
keyword_suspend |> concat(blockexprstatement), | |
keyword_defer |> concat(blockexprstatement), | |
keyword_errdefer |> optional(payload) |> concat(blockexprstatement), | |
ifstatement, | |
labeledstatement, | |
switchexpr, | |
assignexpr |> concat(semicolon) | |
]) | |
root = skip |> optional(container_doc_comment) |> concat(containermembers) |> concat(eof) | |
defcombinatorp(:expr_parsec, expr, export_metadata: true) | |
defcombinatorp(:typeexpr_parsec, typeexpr, export_metadata: true) | |
defcombinatorp(:assignexpr_parsec, assignexpr, export_metadata: true) | |
defcombinatorp(:stringlist_parsec, stringlist, export_metadata: true) | |
defcombinatorp(:asminputlist_parsec, asminputlist, export_metadata: true) | |
defcombinatorp(:asmoutputlist_parsec, asmoutputlist, export_metadata: true) | |
defcombinatorp(:ifexpr_parsec, ifexpr, export_metadata: true) | |
defcombinatorp(:ptrpayload_parsec, ptrpayload, export_metadata: true) | |
defcombinatorp(:slicetypestart_parsec, slicetypestart, export_metadata: true) | |
defcombinatorp(:bytealign_parsec, bytealign, export_metadata: true) | |
defcombinatorp(:ptrtypestart_parsec, ptrtypestart, export_metadata: true) | |
defcombinatorp(:arraytypestart_parsec, arraytypestart, export_metadata: true) | |
defcombinatorp(:exprlist_parsec, exprlist, export_metadata: true) | |
defcombinatorp(:containermembers_parsec, containermembers, export_metadata: true) | |
defcombinatorp(:loopexpr_parsec, loopexpr, export_metadata: true) | |
defcombinatorp(:block_parsec, block, export_metadata: true) | |
defcombinatorp(:statement_parsec, statement, export_metadata: true) | |
defcombinatorp(:containerdeclarations_parsec, containerdeclarations, export_metadata: true) | |
defcombinatorp(:topleveldecl_parsec, topleveldecl, export_metadata: true) | |
defparsec(:zig_src, root, debug: true) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment