简体   繁体   中英

antlr4 how to create a Tree in golang to parse javascript

I'm trying to create a javascript parser in golang using antlr4. the grammar I'm using is this one ( https://github.com/antlr/grammars-v4/tree/master/javascript/ecmascript ) and I'm following instructions from this readme https://github.com/antlr/antlr4/blob/master/doc/go-target.md

so I've generated the lexer and parser files from the grammar, and I'm trying to test parsing a program.

func Parse(program string) {

    is := antlr.NewInputStream(program)

    lexer := parser.NewECMAScriptLexer(is)
    stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)

    p := parser.NewECMAScriptParser(stream)
    antlr.ParseTreeWalkerDefault.Walk(&ParserListener{}, tree)

}

the problem is antlr.ParseTreeWalkerDefault.Walk expect a parser listener and a tree. but BaseParser has no function to generate a tree type object. https://godoc.org/github.com/antlr/antlr4/runtime/Go/antlr#BaseParser

Look at BaseECMAScriptListener functions in parser/ecmascript_base_listener.go file.

package main

import (
    "./parser"
    "fmt"
    "github.com/antlr/antlr4/runtime/Go/antlr"
)

type echoListener struct {
    *parser.BaseECMAScriptListener
}

// Example
func (s *echoListener) VisitTerminal(node antlr.TerminalNode) {
    fmt.Printf("%v\n", node.GetText())
}

func Parse(program string) {
    is := antlr.NewInputStream(program)

    lexer := parser.NewECMAScriptLexer(is)
    stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)

    p := parser.NewECMAScriptParser(stream)

    antlr.ParseTreeWalkerDefault.Walk(&echoListener{}, p.Program())
}

func main() {
    Parse("function test(a, b) { return a + b; }")
}

For every non-terminal in the grammar, the generated parser will have a method with the same name as the non-terminal which takes no arguments and returns the result of parsing the given non-terminal as a parse tree. That's the tree you should pass to Walk .

So since the grammar you're using defines a non-terminal named program , you can call p.Program() to parse a program and get back an appropriate parse tree.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM