Repository navigation
HTML Parser not working #438
|
I'm building something like an HTML template parser, but I can't it to work. // ast.go type Component struct {
HTML []Node `parser:"@@*"`
}
type Node interface{ node() }
type TextNode struct {
Value string `parser:"@Text"`
}
func (TextNode) node() {}
type ExpressionNode struct {
Value string `parser:"LeftCurlyB @@ RightCurlyB"`
}
type ElementNode struct {
Tag string `parser:"LeftAngleB @Ident"`
Attribute []Attribute `parser:"@@*"`
SelfClose bool `parser:"( SelfCloseTag"`
Children []Node `parser:"| RightAngleB @@* CloseTag @Ident RightAngleB )"`
}
func (ElementNode) node() {}
type Attribute struct {
Name string `parser:"@Ident"`
Value string `parser:"Equals @String"`
}// lexer.go var componentLexer = lexer.MustSimple([]lexer.SimpleRule{
{Name: "CloseTag", Pattern: `</`},
{Name: "SelfCloseTag", Pattern: `/>`},
{Name: "Float", Pattern: `[-+]?(?:\d+\.\d*|\.\d+)(?:[eE][-+]?\d+)?`},
{Name: "Int", Pattern: `[-+]?\d+`},
{Name: "String", Pattern: `"(\\"|[^"])*"`},
{Name: "Equals", Pattern: `=`},
{Name: "Comma", Pattern: `,`},
{Name: "SemiColon", Pattern: `;`},
{Name: "Colon", Pattern: `:`},
{Name: "LeftSquareB", Pattern: `\[`},
{Name: "RightSquareB", Pattern: `\]`},
{Name: "LeftCurlyB", Pattern: `\{`},
{Name: "RightCurlyB", Pattern: `\}`},
{Name: "LeftAngleB", Pattern: `<`},
{Name: "RightAngleB", Pattern: `>`},
{Name: "Ident", Pattern: `[a-zA-Z_]\w*`},
{Name: "Text", Pattern: `[^<>{}]+`},
{Name: "Whitespace", Pattern: `[ \t\r\n]+`},
})// parser.go func Parse(filename, code string) (*Component, error) {
parser, err := participle.Build[Component](
participle.Union[Node](TextNode{}, ElementNode{}),
participle.Elide("Whitespace", "SemiColon"),
participle.Unquote("String"),
participle.Lexer(componentLexer),
)
if err != nil {
return nil, err
}
return parser.ParseString(filename, code)
}// main.go func main() {
componentFile := "./sample.html"
code, _ := os.ReadFile(componentFile)
blocks, err := Parse(componentFile, string(code))
if err != nil {
fmt.Println(err)
return
}
fmt.Println(gelt.Prettify(blocks))
}// sample.html <p>Hello <b>world</b></p>I keep getting this error |
Answered by
alecthomas
May 25, 2025
Replies: 2 comments 2 replies
|
I can't really tell because I can't reproduce it without the lexer, but this is incorrect: Children []Node `parser:"| RightAngleB @@* CloseTag @Ident RightAngleB )"`You can only use |
1 reply
|
The issue is that two of your tokens have overlapping regex patterns: Ident and Text. You're matching "Text" in TextNode, but Ident has higher precedence in the lexer rules, so Text will never be produced. You can fix this by either changing TextNode to this: Value string `parser:"(@Ident | @Text)"`Or fixing your lexer rules to remove the ambiguity. I'd suggest doing this. |
1 reply
Answer selected by
alecthomas
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The issue is that two of your tokens have overlapping regex patterns: Ident and Text.
You're matching "Text" in TextNode, but Ident has higher precedence in the lexer rules, so Text will never be produced. You can fix this by either changing TextNode to this:
Or fixing your lexer rules to remove the ambiguity. I'd suggest doing this.