I am trying to create a parser for a language similar to handlebars, glimmer.
Here is what I have so far
@top Glimmer { Expression* | Text* }
Expression { moustache<SubExpression> | Block | BlockComment }
Block { StartBlock (Expression | Text)* EndBlock }
StartBlock[closedBy="EndBlock"] { "{{#" Function SubExpression? As? "}}" }
As { kw<"as"> "|" list<name> "|" }
EndBlock[openedBy="StartBlock"] { "{{/" name "}}" }
Function { if | let | each | name }
SubExpression { list<Value> NamedArgs? }
Value {
boolean
| null
| undefined
| String
| Number
| Invocation
| PropertyPath
}
Invocation { "(" SubExpression ")" }
Pair { string "=" Value }
NamedArgs { list<Pair> }
Argument { "@" name }
Property { this | Argument | name }
PropertyPath { Property ("." name)}
boolean {
@specialize[@name=BooleanLiteral]<identifier, "true" | "false">
}
if { kw<"if"> }
let { kw<"let"> }
each { kw<"each"> }
this { kw<"this"> }
null { kw<"null"> }
undefined { kw<"undefined"> }
ShortComment { "{{!" Text* "}}" }
LongComment { "{{!--" Text* "--}}" }
BlockComment { LongComment | ShortComment }
String { string }
Number { number }
@tokens {
number { @digit+ | (@digit+ ("." @digit*))}
identifierChar { @asciiLetter | $[_$\u{a1}-\u{10ffff}] }
word { identifierChar (identifierChar | @digit)* }
identifier { word }
name { word }
string {
"\"" !["]* "\"" |
"\'" ![']* "\'"
}
Text { _+ }
@precedence {
Text,
"{{#", "{{/",
"{{", "}}", "{{!",
"{{!--", "--}}",
name,
identifier
}
}
// Helper And Special Things
list<item> { item (" " item)* }
kw<term> { @specialize[@name={term}]<identifier, term> }
moustache<content> { "{{" content "}}" }
@external propSource glimmerHighlighting from './highlight'
but unfortunately, everything is identifies as Text
, rather than anything more specific, even though Iām using @precedence
Whatās going on? and how do I make all the other identifying bits work?
Example tests Iām using
# Long comment
{{!-- text here --}}
==>
Glimmer(
BlockComment
)
# Simple Integer
{{42}}
==>
Glimmer(
Expression(
SubExpression(
Value(Number)
)
)
)