aboutsummaryrefslogtreecommitdiff
path: root/src/urubu/driver/parser/template.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/urubu/driver/parser/template.go')
-rw-r--r--src/urubu/driver/parser/template.go535
1 files changed, 0 insertions, 535 deletions
diff --git a/src/urubu/driver/parser/template.go b/src/urubu/driver/parser/template.go
deleted file mode 100644
index 33d097c..0000000
--- a/src/urubu/driver/parser/template.go
+++ /dev/null
@@ -1,535 +0,0 @@
-package parser
-
-import (
- "bytes"
- _ "embed"
- "fmt"
- "go/ast"
- "go/format"
- "go/parser"
- "go/token"
- goToken "go/token"
- "strconv"
- "strings"
- "text/template"
-
- spec "urubu/spec/grammar"
-)
-
-// go:embed parser.go
-var parserCoreSrc string
-
-// go:embed semantic_action.go
-var semActSrc string
-
-func GenParser(cgram *spec.CompiledGrammar, pkgName string) ([]byte, error) {
- var parserSrc string
- {
- fset := goToken.NewFileSet()
- f, err := parser.ParseFile(fset, "parser.go", parserCoreSrc, parser.ParseComments)
- if err != nil {
- return nil, err
- }
-
- var b strings.Builder
- err = format.Node(&b, fset, f)
- if err != nil {
- return nil, err
- }
-
- parserSrc = b.String()
- }
-
- var grammarSrc string
- {
- t, err := template.New("").Funcs(genGrammarTemplateFuncs(cgram)).Parse(grammarSrcTmplate)
- if err != nil {
- return nil, err
- }
-
- var b strings.Builder
- err = t.Execute(&b, map[string]interface{}{
- "initialState": cgram.Syntactic.InitialState,
- "startProduction": cgram.Syntactic.StartProduction,
- "terminalCount": cgram.Syntactic.TerminalCount,
- "nonTerminalCount": cgram.Syntactic.NonTerminalCount,
- "eofSymbol": cgram.Syntactic.EOFSymbol,
- "errorSymbol": cgram.Syntactic.ErrorSymbol,
- })
- if err != nil {
- return nil, err
- }
-
- grammarSrc = b.String()
- }
-
- var lexerSrc string
- {
- t, err := template.New("").Funcs(genLexerTemplateFuncs(cgram)).Parse(lexerSrcTmplate)
- if err != nil {
- return nil, err
- }
-
- var b strings.Builder
- err = t.Execute(&b, nil)
- if err != nil {
- return nil, err
- }
-
- lexerSrc = b.String()
- }
-
- var src string
- {
- tmpl := `// Code generated by vartan-go. DO NOT EDIT.
-{{ .parserSrc }}
-
-{{ .grammarSrc }}
-
-{{ .lexerSrc }}
-`
- t, err := template.New("").Parse(tmpl)
- if err != nil {
- return nil, err
- }
-
- var b strings.Builder
- err = t.Execute(&b, map[string]string{
- "parserSrc": parserSrc,
- "grammarSrc": grammarSrc,
- "lexerSrc": lexerSrc,
- })
- if err != nil {
- return nil, err
- }
-
- src = b.String()
- }
-
- fset := goToken.NewFileSet()
- f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
- if err != nil {
- return nil, err
- }
-
- f.Name = ast.NewIdent(pkgName)
-
- // Complete an import statement.
- for _, d := range f.Decls {
- gd, ok := d.(*ast.GenDecl)
- if !ok || gd.Tok != token.IMPORT {
- continue
- }
- gd.Specs = append(gd.Specs, &ast.ImportSpec{
- Path: &ast.BasicLit{
- Value: `"io"`,
- },
- })
- break
- }
-
- var b bytes.Buffer
- err = format.Node(&b, fset, f)
- if err != nil {
- return nil, err
- }
-
- return b.Bytes(), nil
-}
-
-const grammarSrcTmplate = `
-type grammarImpl struct {
- recoverProductions []int
- action []int
- goTo []int
- alternativeSymbolCounts []int
- errorTrapperStates []int
- nonTerminals []string
- lhsSymbols []int
- terminals []string
- terminalSkip []int
- astActions [][]int
-}
-
-func NewGrammar() *grammarImpl {
- return &grammarImpl{
- recoverProductions: {{ genRecoverProductions }},
- action: {{ genAction }},
- goTo: {{ genGoTo }},
- alternativeSymbolCounts: {{ genAlternativeSymbolCounts }},
- errorTrapperStates: {{ genErrorTrapperStates }},
- nonTerminals: {{ genNonTerminals }},
- lhsSymbols: {{ genLHSSymbols }},
- terminals: {{ genTerminals }},
- terminalSkip: {{ genTerminalSkip }},
- astActions: {{ genASTActions }},
- }
-}
-
-func (g *grammarImpl) InitialState() int {
- return {{ .initialState }}
-}
-
-func (g *grammarImpl) StartProduction() int {
- return {{ .startProduction }}
-}
-
-func (g *grammarImpl) RecoverProduction(prod int) bool {
- return g.recoverProductions[prod] != 0
-}
-
-func (g *grammarImpl) Action(state int, terminal int) int {
- return g.action[state*{{ .terminalCount }}+terminal]
-}
-
-func (g *grammarImpl) GoTo(state int, lhs int) int {
- return g.goTo[state*{{ .nonTerminalCount }}+lhs]
-}
-
-func (g *grammarImpl) AlternativeSymbolCount(prod int) int {
- return g.alternativeSymbolCounts[prod]
-}
-
-func (g *grammarImpl) TerminalCount() int {
- return {{ .terminalCount }}
-}
-
-func (g *grammarImpl) SkipTerminal(terminal int) bool {
- return g.terminalSkip[terminal] == 1
-}
-
-func (g *grammarImpl) ErrorTrapperState(state int) bool {
- return g.errorTrapperStates[state] != 0
-}
-
-func (g *grammarImpl) NonTerminal(nonTerminal int) string {
- return g.nonTerminals[nonTerminal]
-}
-
-func (g *grammarImpl) LHS(prod int) int {
- return g.lhsSymbols[prod]
-}
-
-func (g *grammarImpl) EOF() int {
- return {{ .eofSymbol }}
-}
-
-func (g *grammarImpl) Error() int {
- return {{ .errorSymbol }}
-}
-
-func (g *grammarImpl) Terminal(terminal int) string {
- return g.terminals[terminal]
-}
-
-func (g *grammarImpl) ASTAction(prod int) []int {
- return g.astActions[prod]
-}
-`
-
-func genGrammarTemplateFuncs(cgram *spec.CompiledGrammar) template.FuncMap {
- return template.FuncMap{
- "genRecoverProductions": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]int{\n")
- c := 1
- for _, v := range cgram.Syntactic.RecoverProductions {
- fmt.Fprintf(&b, "%v, ", v)
- if c == 20 {
- fmt.Fprintf(&b, "\n")
- c = 1
- } else {
- c++
- }
- }
- if c > 1 {
- fmt.Fprintf(&b, "\n")
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- "genAction": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]int{\n")
- c := 1
- for _, v := range cgram.Syntactic.Action {
- fmt.Fprintf(&b, "%v, ", v)
- if c == 20 {
- fmt.Fprintf(&b, "\n")
- c = 1
- } else {
- c++
- }
- }
- if c > 1 {
- fmt.Fprintf(&b, "\n")
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- "genGoTo": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]int{\n")
- c := 1
- for _, v := range cgram.Syntactic.GoTo {
- fmt.Fprintf(&b, "%v, ", v)
- if c == 20 {
- fmt.Fprintf(&b, "\n")
- c = 1
- } else {
- c++
- }
- }
- if c > 1 {
- fmt.Fprintf(&b, "\n")
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- "genAlternativeSymbolCounts": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]int{\n")
- c := 1
- for _, v := range cgram.Syntactic.AlternativeSymbolCounts {
- fmt.Fprintf(&b, "%v, ", v)
- if c == 20 {
- fmt.Fprintf(&b, "\n")
- c = 1
- } else {
- c++
- }
- }
- if c > 1 {
- fmt.Fprintf(&b, "\n")
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- "genErrorTrapperStates": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]int{\n")
- c := 1
- for _, v := range cgram.Syntactic.ErrorTrapperStates {
- fmt.Fprintf(&b, "%v, ", v)
- if c == 20 {
- fmt.Fprintf(&b, "\n")
- c = 1
- } else {
- c++
- }
- }
- if c > 1 {
- fmt.Fprintf(&b, "\n")
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- "genNonTerminals": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]string{\n")
- for _, v := range cgram.Syntactic.NonTerminals {
- fmt.Fprintf(&b, "%v,\n", strconv.Quote(v))
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- "genLHSSymbols": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]int{\n")
- c := 1
- for _, v := range cgram.Syntactic.LHSSymbols {
- fmt.Fprintf(&b, "%v, ", v)
- if c == 20 {
- fmt.Fprintf(&b, "\n")
- c = 1
- } else {
- c++
- }
- }
- if c > 1 {
- fmt.Fprintf(&b, "\n")
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- "genTerminals": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]string{\n")
- for _, v := range cgram.Syntactic.Terminals {
- fmt.Fprintf(&b, "%v,\n", strconv.Quote(v))
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- "genTerminalSkip": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]int{\n")
- c := 1
- for _, v := range cgram.Syntactic.TerminalSkip {
- fmt.Fprintf(&b, "%v, ", v)
- if c == 20 {
- fmt.Fprintf(&b, "\n")
- c = 1
- } else {
- c++
- }
- }
- if c > 1 {
- fmt.Fprintf(&b, "\n")
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- "genASTActions": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[][]int{\n")
- for _, entries := range cgram.ASTAction.Entries {
- if len(entries) == 0 {
- fmt.Fprintf(&b, "nil,\n")
- continue
- }
-
- fmt.Fprintf(&b, "{\n")
- c := 1
- for _, v := range entries {
- fmt.Fprintf(&b, "%v, ", v)
- if c == 20 {
- fmt.Fprintf(&b, "\n")
- c = 1
- } else {
- c++
- }
- }
- if c > 1 {
- fmt.Fprintf(&b, "\n")
- }
- fmt.Fprintf(&b, "},\n")
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- }
-}
-
-const lexerSrcTmplate = `
-type vToken struct {
- terminalID int
- tok *Token
-}
-
-func (t *vToken) TerminalID() int {
- return t.terminalID
-}
-
-func (t *vToken) Lexeme() []byte {
- return t.tok.Lexeme
-}
-
-func (t *vToken) EOF() bool {
- return t.tok.EOF
-}
-
-func (t *vToken) Invalid() bool {
- return t.tok.Invalid
-}
-
-func (t *vToken) BytePosition() (int, int) {
- return t.tok.BytePos, t.tok.ByteLen
-}
-
-func (t *vToken) Position() (int, int) {
- return t.tok.Row, t.tok.Col
-}
-
-var kindToTerminal = {{ genKindToTerminal }}
-
-type tokenStream struct {
- lex *Lexer
- kindToTerminal []int
-}
-
-func NewTokenStream(src io.Reader) (*tokenStream, error) {
- lex, err := NewLexer(NewLexSpec(), src)
- if err != nil {
- return nil, err
- }
-
- return &tokenStream{
- lex: lex,
- }, nil
-}
-
-func (t *tokenStream) Next() (VToken, error) {
- tok, err := t.lex.Next()
- if err != nil {
- return nil, err
- }
- return &vToken{
- terminalID: kindToTerminal[tok.KindID],
- tok: tok,
- }, nil
-}
-`
-
-func genLexerTemplateFuncs(cgram *spec.CompiledGrammar) template.FuncMap {
- return template.FuncMap{
- "genKindToTerminal": func() string {
- var b strings.Builder
- fmt.Fprintf(&b, "[]int{\n")
- c := 1
- for _, v := range cgram.Syntactic.KindToTerminal {
- fmt.Fprintf(&b, "%v, ", v)
- if c == 20 {
- fmt.Fprintf(&b, "\n")
- c = 1
- } else {
- c++
- }
- }
- if c > 1 {
- fmt.Fprintf(&b, "\n")
- }
- fmt.Fprintf(&b, "}")
- return b.String()
- },
- }
-}
-
-func GenSemanticAction(pkgName string) ([]byte, error) {
- var src string
- {
- tmpl := `// Code generated by vartan-go. DO NOT EDIT.
-{{ .semActSrc }}
-`
- t, err := template.New("").Parse(tmpl)
- if err != nil {
- return nil, err
- }
-
- var b strings.Builder
- err = t.Execute(&b, map[string]string{
- "semActSrc": semActSrc,
- })
- if err != nil {
- return nil, err
- }
-
- src = b.String()
- }
-
- fset := goToken.NewFileSet()
- f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
- if err != nil {
- return nil, err
- }
-
- f.Name = ast.NewIdent(pkgName)
-
- var b bytes.Buffer
- err = format.Node(&b, fset, f)
- if err != nil {
- return nil, err
- }
-
- return b.Bytes(), nil
-}