#go #antlr4
# #Вперед #antlr4
Вопрос:
Я пытаюсь создать анализатор javascript в golang, используя antlr4. грамматика, которую я использую, это (https://github.com/antlr/grammars-v4/tree/master/javascript/ecmascript ) и я следую инструкциям из этого readme https://github.com/antlr/antlr4/blob/master/doc/go-target.md
итак, я сгенерировал файлы lexer и parser из грамматики, и я пытаюсь протестировать синтаксический анализ программы.
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(amp;ParserListener{}, tree)
}
проблема antlr.ParseTreeWalkerDefault.Walk
в том, что ожидается прослушиватель синтаксического анализа и дерево. но у BaseParser нет функции для генерации объекта типа дерева. https://godoc.org/github.com/antlr/antlr4/runtime/Go/antlr#BaseParser
Ответ №1:
Для каждого нетерминала в грамматике сгенерированный анализатор будет иметь метод с тем же именем, что и нетерминал, который не принимает аргументов и возвращает результат синтаксического анализа данного нетерминала в виде дерева синтаксического анализа. Это дерево, к которому вы должны перейти Walk
.
Итак, поскольку используемая вами грамматика определяет нетерминальное имя program
, вы можете вызвать p.Program()
для синтаксического анализа программу и получить обратно соответствующее дерево синтаксического анализа.
Ответ №2:
Посмотрите на BaseECMAScriptListener
функции в parser/ecmascript_base_listener.go
файле.
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("%vn", 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(amp;echoListener{}, p.Program())
}
func main() {
Parse("function test(a, b) { return a b; }")
}