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 hidden or 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