@external propSource highlighting from "./highlight.js" @top Program { line* } line { CommandCall semi | expr semi } @skip { space } @tokens { @precedence { Number "-"} space { @whitespace+ } Number { "-"? $[0-9]+ ('.' $[0-9]+)? } Boolean { "true" | "false" } String { '\'' !["]* '\'' } NamedArgPrefix { $[a-z]+ $[a-z0-9\-]* "=" } // matches "lines=", "follow=", etc. fn[@name=keyword] { "fn" } equals[@name=operator] { "=" } ":"[@name=colon] "+"[@name=operator] "-"[@name=operator] "*"[@name=operator] "/"[@name=operator] leftParen[@name=paren] { "(" } rightParen[@name=paren] { ")" } } @external tokens tokenizer from "./tokenizers" { Identifier, Command, CommandPartial } @external tokens argTokenizer from "./tokenizers" { UnquotedArg } @external tokens insertSemicolon from "./tokenizers" { insertedSemi } @precedence { multiplicative @left, additive @left, namedComplete @left, function @right assignment @right } expr { Assignment | Function | BinOp | atom } semi { insertedSemi | ";" } argValue { atom | UnquotedArg } CommandCall { (Command | CommandPartial) (NamedArg | PartialNamedArg | Arg)* } Arg { !namedComplete argValue } NamedArg { NamedArgPrefix !namedComplete argValue } // Required atom, higher precedence PartialNamedArg { NamedArgPrefix } // Just the prefix Assignment { Identifier !assignment equals expr } Function { !function fn Params ":" expr } Params { Identifier* } BinOp { expr !multiplicative "*" expr | expr !multiplicative "/" expr | expr !additive "+" expr | expr !additive "-" expr } ParenExpr { leftParen expr rightParen } atom { Identifier ~command | Number | String | Boolean | ParenExpr }