package muesli import ( _ "bufio" _ "bytes" _ "errors" _ "fmt" _ "io" _ "os" _ "reflect" _ "runtime" _ "strings" _ "unicode" // "gitlab.com/beoran/woe/graphviz" // _ "gitlab.com/beoran/woe/monolog" ) type AstKind int const ( AstKindProgram = AstKind(iota) AstKindStatements AstKindStatement AstKindSet AstKindGet AstKindCommand AstKindArguments AstKindBlock AstKindList AstKindCapture AstKindWordValue AstKindWord AstKindType AstKindValue AstKindEox AstKindError ) type Parser struct { Lexer Lexer Ast next *Token current *Token } func (parser *Parser) Peek() *Token { if parser.next == nil { token := parser.Lexer.Lex() parser.next = &token } return parser.next } func (parser *Parser) Next() *Token { next := parser.Peek() parser.current = next parser.next = nil parser.Peek() return parser.current } func (parser *Parser) Require(wanted TokenKind, astkind AstKind, parent *Ast) *Ast { token := parser.Next() if token.TokenKind == wanted { return parent.NewChild(astkind, token) } return parent.NewChild(AstKindError, token) } func (parser *Parser) ParseMany( astkind AstKind, parsefunc func(*Parser) *Ast) *Ast { ast := NewAst(astkind, nil, nil) for sub := parsefunc(parser); sub != nil && sub.AstKind != AstKindError; sub = parsefunc(parser) { ast.AppendChild(sub) } return ast } func (parser *Parser) NewAstError(message string) *Ast { sv := StringValue(message) pos := parser.current.Position tok := NewToken(TokenKindError, sv, pos) return NewAst(AstKindError, nil, &tok) } func (parser *Parser) ParseAny(astkind AstKind, parsefuncs ...(func(*Parser) *Ast)) *Ast { ast := NewAst(astkind, nil, nil) for _, parsefunc := range parsefuncs { sub := parsefunc(parser) if sub != nil { ast.AppendChild(sub) return ast } } err := parser.NewAstError("Unexpected token") ast.AppendChild(err) return ast } func (parser *Parser) ParseSet() *Ast { return nil } func (parser *Parser) ParseGet() *Ast { return nil } func (parser *Parser) ParseCommand() *Ast { return nil } func (parser *Parser) ParseStatement() *Ast { return parser.ParseAny(AstKindStatement, (*Parser).ParseSet, (*Parser).ParseGet, (*Parser).ParseCommand) } func (parser *Parser) ParseStatements() *Ast { return parser.ParseMany(AstKindStatements, (*Parser).ParseStatement) } func (parser *Parser) ParseProgram() *Ast { ast := NewAst(AstKindProgram, nil, nil) stats := parser.ParseStatements() ast.AppendChild(stats) return ast } func (parser *Parser) Parse() *Ast { ast := parser.ParseProgram() return ast }