shrimp/src/parser/shrimp.grammar
2025-10-03 08:15:02 -07:00

80 lines
1.7 KiB
Plaintext

@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 }