/* Based on: https://github.com/R167/lezer-lua */ @precedence { call, power @right, prefix, times @left, plus @left, concat @right, shift @left, bitand @left, xor @left, bitor @left, compare @left, and @left, or @left } @top Chunk { Block } kw { @specialize[@name={term}] } ckw { @extend[@name={term}] } list { term ("," term)* } Block { statement* ReturnStatement? } ReturnStatement { kw<"return"> ExpList? ";"?} @skip { newline | space | Comment } statement[@isGroup=Statement] { ";" | Label | kw<"break"> | Goto{ kw<"goto"> Name } | Scope { kw<"do"> Block kw<"end"> } | WhileStatement { kw<"while"> exp kw<"do"> Block kw<"end"> } | RepeatStatement { kw<"repeat"> Block kw<"until"> exp } | IfStatement | ForStatement | Function { kw<"function"> FuncName FuncBody } | LocalFunction { kw<"local"> kw<"function"> Name FuncBody } | Assign { VarList "=" ExpList } | Local { kw<"local"> AttNameList ("=" ExpList)? } | FunctionCall ~fcall } IfStatement { kw<"if"> exp kw<"then"> Block (kw<"elseif"> exp kw<"then"> Block)* (kw<"else"> Block)? kw<"end"> } ForNumeric { Name "=" exp "," exp ("," exp)? } ForGeneric { NameList kw<"in"> ExpList } ForStatement { kw<"for"> (ForNumeric | ForGeneric) kw<"do"> Block kw<"end"> } FuncName { Name ("." Name)* (":" Name)? } FuncBody { "(" ArgList ")" Block kw<"end"> } NameList { list } ExpList { list } VarList { list } ArgList { (list)? } AttNameList { list } AttName { Name Attrib } Attrib { ( "<" Name ">" )? } exp { kw<"nil"> | kw<"true"> | kw<"false"> | "..." | Number | LiteralString | prefixexp | BinaryExpression | UnaryExpression | TableConstructor | FunctionDef { kw<"function"> FuncBody } | Query } Query { kw<"query"> "[[" QueryClause* "]]" } QueryClause { FromClause | WhereClause | OrderByClause | SelectClause | LimitClause } FromClause { ckw<"from"> (Name "=")? exp } WhereClause { ckw<"where"> exp } LimitClause { ckw<"limit"> exp ("," exp)? } OrderByClause { ckw<"order"> ckw<"by"> list } OrderBy { exp ckw<"desc">? } SelectClause { ckw<"select"> exp } field[@isGroup=Field] { FieldDynamic { "[" exp "]" "=" exp } | FieldProp { Name "=" exp } | FieldExp { exp } } prefixexp { var | Parens { "(" exp ")" ~parens } | FunctionCall ~fcall } FunctionCall { prefixexp (":" Name)? !call args } args { LiteralString | TableConstructor | funcParams[@dynamicPrecedence=1] { "(" list? ")" ~parens } } var { Name | Property { (prefixexp "." Name) } | MemberExpression { (prefixexp "[" exp "]") } } Name { identifier } Label { "::" Name "::" } LiteralString { simpleString } BinaryExpression { exp !or kw<"or"> exp | exp !and kw<"and"> exp | exp !compare CompareOp exp | exp !bitor BitOp{"|"} exp | exp !bitand BitOp{"&"} exp | exp !xor BitOp{"~"} exp | exp !shift BitOp{"<<" | ">>"} exp | exp !concat ".." exp | exp !plus ArithOp{"+" | minus} exp | exp !times ArithOp{"*" | "/" | "%" | "//"} exp | exp !power ArithOp{"^"} exp } UnaryExpression { !prefix kw<"not"> exp | !prefix (ArithOp{"+" | minus} | BitOp{"~"} | LenOp{"#"}) exp } TableConstructor { "{" (field (fieldsep field)* fieldsep?)? "}" } @tokens { CompareOp { "<" | ">" | $[<>=~/!] "=" } identifier { (std.asciiLetter | "_") (std.digit | std.asciiLetter | "_")* } stringEscape { "\\" ($[abfnz"'\\] | digit digit? digit?) | "\\x" hex hex | "\\u{" hex+ "}" } // Any sequence of characters except two consecutive ]] longStringContent { (![\]] | $[\]] ![\]])* } longDelimStringContent { (![\]] | $[\]] ![=]+ ![\]])* } simpleString { "'" (stringEscape | ![\r\n\\'])* "'" | '"' (stringEscape | ![\r\n\\"])* '"' | '[[' longStringContent ']]' | '[' '='+ '[' longDelimStringContent ']' '='+ ']' } hex { $[0-9a-fA-F] } digit { std.digit } Number { digit+ ("." digit+)? ($[eE] $[+\-] digit+)? | "0" $[xX] hex+ ("." hex+)? ($[pP] $[+/-] digit+)? } Comment { "--" ![\n\r]* } space { ($[ \t\f] | "\\" $[\n\r])+ } newline { $[\n\r] | "\n\r" | "\r\n" } "..."[@name=Ellipsis] ".."[@name=Concat] @precedence { Comment, minus } minus {"-"} fieldsep { $[,;] } "(" ")" "[" "]" "{" "}" "." "," ";" ":" "::" }