warpack-lua-parser 0.0.1

A Lua parser library used by Warpack.
Documentation

WHITESPACE = _{ " " | "\t" | "\r" | "\n" }

COMMENT = _{
    CommentStart ~ LongBracketStart ~ StringContentLong ~ LongBracketEnd |
    // CommentStart ~ PreprocessDirective |
    CommentStart ~ SimpleCommentContent
}

keyword = _{
    "and"   | "break" | "do"       | "elseif" | "else" | "end"    |
    "false" | "for  " | "function" | "goto"   | "if"   | "in"     |
    "local" | "nil"   | "not"      | "or"   | "repeat" | "return" |
    "then"  | "true"  | "until"    | "while"
}

CommentStart = _{ "--" }
LongBracketContent = _{ "="* }
LongBracketStart = _{ "[" ~ PUSH(LongBracketContent) ~ "[" }
LongBracketEnd = _{ "]" ~ POP ~ "]" }
LongBracketEndPeek = _{ "]" ~ PEEK ~ "]" }
SimpleCommentContent = { (!("\n") ~ ANY)* }
StringContentLong = { (!(LongBracketEndPeek) ~ ANY)* }

Ident = @{
    !(ASCII_DIGIT | WHITESPACE) ~ !(keyword ~ (!ASCII_ALPHA ~ ANY)) ~ (!(WHITESPACE) ~ (ASCII_ALPHA | "_" | ASCII_DIGIT))+
}

DecimalExponent = @{ (^"e" ~ ("-" | "+")? ~ ASCII_DIGIT+) }
BinaryExponent = @{ (^"p" ~ ("-" | "+")? ~ ASCII_HEX_DIGIT+) }

NumberNormal = {ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT*)?}
NumberFractionalOnly = {"." ~ ASCII_DIGIT+}

HexNormal = {ASCII_HEX_DIGIT+ ~ ("." ~ ASCII_HEX_DIGIT*)?}
HexFractionalOnly = {"." ~ ASCII_HEX_DIGIT+}

LiteralNumberDec = @{ ("-")? ~ (NumberNormal | NumberFractionalOnly) ~ DecimalExponent? }
LiteralNumberHex = @{ ("-")? ~ "0" ~ ^"x" ~ (HexNormal | HexFractionalOnly) ~ (DecimalExponent | BinaryExponent)? }

LiteralNumber = _{
    LiteralNumberHex | LiteralNumberDec
}

LiteralString = ${
    "'" ~ StringContentSQ ~ "'" |
    "\"" ~ StringContentDQ ~ "\"" |
    LongBracketStart ~ StringContentLong ~ LongBracketEnd
}

StringEscape = @{ "\\" ~ ANY }

StringContentSQ = @{ (!("\'" | "\\") ~ ANY)* ~ (StringEscape ~ StringContentSQ)? }
StringContentDQ = @{ (!("\"" | "\\") ~ ANY)* ~ (StringEscape ~ StringContentDQ)? }

LiteralNil = { "nil" }
LiteralFalse = { "false" }
LiteralTrue = { "true" }

Chunk = {SOI ~ Block ~ EOI}
Block = {Stmt* ~ StmtReturn?}

StmtAssign = { VarList ~ "=" ~ ExpList }
StmtFuncCall = { Var ~ Call+ }
StmtLabel = { "::" ~ Ident ~ "::" }
StmtBreak = { "break" }
StmtGoto = { "goto" ~ Ident }
StmtDo = { "do" ~ Block ~ "end"}
StmtWhile = { "while" ~ Exp ~ "do" ~ Block ~ "end" }
StmtRepeat = { "repeat" ~ Block ~ "until" ~ Exp }
StmtIf = { "if" ~ Exp ~ "then" ~ Block ~ ("elseif" ~ Exp ~ "then" ~ Block)* ~ ("else" ~ Block)? ~ "end" }
StmtForIndex = { "for" ~ Ident ~ "=" ~ Exp ~ "," ~ Exp ~ ("," ~ Exp)? ~ "do" ~ Block ~ "end" }
StmtForEach = { "for" ~ IdentList ~ "in" ~ ExpList ~ "do" ~ Block ~ "end" }
StmtFuncDef = { "function" ~ FuncName ~ FuncBody }
StmtLocalFuncDef = { "local" ~ "function" ~ Ident ~ FuncBody }
StmtLocalDef = { "local" ~ IdentList ~ ("=" ~ ExpList)? }

StmtReturn = { "return" ~ (ExpList)? ~ (";")? }

Stmt = {
    ";" |
    StmtAssign |
    StmtFuncCall |
    StmtLabel |
    StmtBreak |
    StmtGoto |
    StmtDo |
    StmtWhile |
    StmtRepeat |
    StmtIf |
    StmtForIndex |
    StmtForEach |
    StmtLocalDef |
    StmtFuncDef |
    StmtLocalFuncDef
}

FuncName = { Ident ~ ("." ~ Ident)* ~ (":" ~ Ident)? }
VarList = { Var ~ ("," ~ Var)* }
IdentList = { Ident ~ ("," ~ Ident)* }
ExpList = { Exp ~ ("," ~ Exp)* }

VarArg = { "..." }

ExpAtom = _{
    LiteralNil |
    LiteralTrue |
    LiteralFalse |
    LiteralNumber |
    LiteralString |
    VarArg |
    AnonFuncDef |
    Value |
    TableConstructor |
    UnaryOpExp 
}

UnaryOpExp = {
    UnaryOp ~ ExpAtom
}

Exp = {
    ExpAtom ~ (BinaryOp ~ ExpAtom)*
}

AtomicExp = {
    Ident |
    "(" ~ Exp ~ ")"
}

Index = {
    "[" ~ Exp ~ "]" |
    "." ~ Ident
}

SimpleCall = { Args }
MethodCall = { ":" ~ Ident ~ Args }

Call = {
    SimpleCall |
    MethodCall
}

Var = {
    AtomicExp ~ (
        Call* ~ Index |
        Index
    )*
}

Value = {
    Var ~ Call*
}

Args = { "(" ~ ExpList? ~ ")" | TableConstructor | LiteralString }

AnonFuncDef = { "function" ~ FuncBody }

FuncBody = { "(" ~ ParList? ~ ")" ~ Block ~ "end" }

ParList = { IdentList ~ ("," ~ "...")? | "..." }

TableConstructor = { "{" ~ (FieldList)* ~ "}" }

FieldList = { Field ~ (FieldSep ~ Field)* ~ FieldSep? }

Field = { "[" ~ Exp ~ "]" ~ "=" ~ Exp | Ident ~ "=" ~ Exp | Exp}

FieldSep = { "," | ";" }
UnaryOp = { "-" | "not" | "#" | (!("~=") ~ "~") }
BinaryOp = @{
    ">>" |
    "<<" |
    "<=" |
    ">=" |
    "==" |
    "~=" |
    "//" |
    "+" |
    "-" |
    "*" |
    "/" |
    "^" |
    "%" |
    "&" |
    "~" |
    "|" |
    ".." |
    "<" |
    ">" |
    "and" |
    "or"
}