powr-parser 0.0.1

parses tokens into AST. part of the power project
Documentation
// JavaScript PEG/Pest grammar

WHITESPACE = _{ " " | NEWLINE }

program = { SOI ~ (statement ~ ";"?)* ~ EOI } // FIXME: Everything regarding semicolons is buggy
statement = _{ if_statement | declaration | return_statement | while_statement | expression }
    return_statement = { "return" ~ expression }
    declaration = { ("const" | "let" | "var")? ~ value ~ assignment_operator ~ expression }
    if_statement = {
        "if" ~ "(" ~ expression ~ ")" ~ (("{" ~ statement* ~ "}") | statement)
        ~ (("else" ~ (("{" ~ statement* ~ "}") | statement))
        | ("else" ~ "if" ~ if_statement))?
    }
    while_statement = { "while" ~ "(" ~ expression ~ ")" ~ (("{" ~ statement* ~ "}") | statement) }
expression = _{ ((value ~ operator ~ value) | value) ~ ";"? } // FIXME: semicolon
arguments = { expression ~ ("," ~ expression)* }

// identifiers
identifier = ${ (ASCII_ALPHA | "_" | "$") ~ (ASCII_ALPHANUMERIC | "_" | "$")* }
// ignores keywords
keyword = _{ "return" | "const" | "let" | "var" | "function" }

// punctuators
operator = { binary_operator | assignment_operator }
    binary_operator = _{ bitwise_operator | "+" | "-" | "*" | "/" | "%" | "**" | "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "&&" | "||" }
        bitwise_operator = _{ "&" | "|" | "^" | "<<" | ">>" | ">>>" }
assignment_operator = _{ "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|=" | "**=" }

// literals
literal = { number | string | boolean | nullish }
value = _{ literal | object | function | arrow_function | regex | keyword | identifier | array }
    boolean = { "true" | "false" }
    nullish = { null | undefined }
        null = { "null" }
        undefined = { "undefined" }
    string = { "\"" ~ inner ~ "\"" | "\'" ~ inner ~ "\'" }
        inner = ${ char* }
            char = { !("\"" | "\\") ~ ANY }
    number = @{
        "-"?
        ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*)
        ~ ("." ~ ASCII_DIGIT+)?
        ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)?
    }
    array = { "[" ~ (value ~ ",")*? ~ value? ~ "]" }
    object = { "("? ~ "{" ~ pair* ~ "}" ~ ")"? }
        pair = { pair_key ~ ":" ~ value ~ ","? }
        pair_key = _{ string | number | identifier }
    regex = { "/" ~ inner ~ "/" }
    function = { "function" ~ identifier? ~ "(" ~ arguments? ~ ")" ~ ("{" ~ function_body? ~ "}" | function_body?) }
        function_body = { statement* }
    arrow_function = { "(" ~ arguments? ~ ")" ~ "=>" ~ ("{" ~ function_body? ~ "}" | arrow_function_body?) }
        arrow_function_body = { implicit_return | statement* }
        implicit_return = { expression }