123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- package muesli
- import (
- _ "bufio"
- _ "bytes"
- _ "errors"
- "fmt"
- _ "io"
- _ "os"
- _ "reflect"
- _ "runtime"
- _ "strings"
- _ "unicode"
-
-
- )
- type Parser struct {
- Lexer *Lexer
- current Token
- LoggerWrapper
- Errors []ParserError
- }
- type ParserError struct {
- *Parser
- *Token
- Error error
- }
- func (parser *Parser) SetLogger(logger Logger) {
- parser.LoggerWrapper = LoggerWrapper{logger}
- }
- func (parser *Parser) Errorf(message string, args ...string) ParserError {
- err := fmt.Errorf(message+" at token "+parser.current.String(), args)
- pe := ParserError { Parser: parser, Token:&parser.current, Error: err }
- parser.Errors = append(parser.Errors, pe)
- return pe
- }
- func (parser *Parser) Panicf(message string, args ...string) {
- pe := parser.Errorf(message, args...)
- panic(pe)
- }
- func (parser *Parser) Advance() {
- token := parser.Lexer.Lex()
- parser.current = token
- parser.LogDebug("Next token: %s\n", token.String())
- }
- func (parser *Parser) Accept(kinds ...TokenKind) Token {
- if parser.current.IsNone() {
- parser.Advance()
- }
-
- for _, kind := range kinds {
- if kind == parser.current.TokenKind {
- accepted := parser.current
- parser.Advance()
- parser.LogDebug("Accept: Accepted token: %s\n", accepted.String())
- return accepted
- }
- }
-
- if parser.current.TokenKind == TokenKindEOF {
- parser.LogDebug("Unexpected EOF\n")
- return parser.Lexer.MakeErrorfToken("Unexpected EOF in Accept")
- }
-
- parser.LogDebug("Accept: No Token: no %s in %v.", parser.current.TokenKind, kinds)
- return NoToken()
- }
- func (parser *Parser) ParseMany(kind AstKind, parent *Ast, parsefunc func(*Parser) *Ast) *Ast {
- children := EmptyAstArray()
- for sub := parsefunc(parser); parser.current.TokenKind != TokenKindEOF &&
- !sub.IsNone() && !sub.IsError(); sub = parsefunc(parser) {
- children = append(children, sub)
- }
- if kind == AstKindFlatten {
- if parent == nil {
- panic("Why nil?")
- }
- parent.AppendChildren(children...)
- return parent
- } else {
- return NewAst(kind, parent, children, NoToken())
- }
- }
- func (parser *Parser) NewAstError(message string, args ...interface{}) *Ast {
- sv := StringValue(fmt.Sprintf(message+" at token "+parser.current.String(), args))
- pos := parser.current.Position
- tok := NewToken(TokenKindError, sv, pos)
- return NewAst(AstKindError, nil, EmptyAstArray(), tok)
- }
- func (parser *Parser) ParseAny(astkind AstKind, parsefuncs ...(func(*Parser) *Ast)) *Ast {
- var ast * Ast
- if astkind != AstKindFlatten {
- ast = NewEmptyAst(astkind)
- }
- for _, parsefunc := range parsefuncs {
- parser.LogDebug("ParseAny: %s: trying: %s", astkind, GetFunctionName(parsefunc))
- sub := parsefunc(parser)
- if !sub.IsNone() {
- if astkind == AstKindFlatten {
- return sub
- } else if sub.IsFlatten() {
- return ast
- } else {
- ast.AppendChild(sub)
- }
- return ast
- }
- }
- return NewAstNone()
- }
- func (parser *Parser) ParseRequireAny(astkind AstKind, parsefuncs ...(func(*Parser) *Ast)) *Ast {
- ast := parser.ParseAny(astkind, parsefuncs...)
- if ast.IsNone() {
- err := parser.NewAstError("Unexpected token in %v", parsefuncs)
- return err
- }
- return ast
- }
- func (parser *Parser) NewAst(kind AstKind, parent * Ast, children []*Ast, value Token) *Ast{
- if value.IsNone() {
- return NewAstNone()
- }
- if value.IsError() {
- return NewAst(AstKindError, parent, children, value)
- }
- return NewAst(kind, parent, children, value)
- }
- func (parser *Parser) ParseValue() *Ast {
- parser.LogDebug("ParseValue: %s\n", parser.current.String())
- value := parser.Accept(TokenKindInteger, TokenKindString,
- TokenKindBoolean, TokenKindNil, TokenKindFloat, TokenKindSymbol)
- return parser.NewAst(AstKindValue, nil, EmptyAstArray(), value)
- }
- func (parser *Parser) ParseWordValue() *Ast {
- parser.LogDebug("ParseWordValue: %s\n", parser.current.String())
- value := parser.Accept(TokenKindInteger, TokenKindString,
- TokenKindBoolean, TokenKindNil, TokenKindFloat, TokenKindSymbol,
- TokenKindType, TokenKindWord)
- return parser.NewAst(AstKindWordValue, nil, EmptyAstArray(), value)
- }
- func (parser *Parser) ParseArgument() *Ast {
- parser.LogDebug("ParseArgument: %s\n", parser.current.String())
- return parser.ParseAny(AstKindArgument,
- (*Parser).ParseGet,
- (*Parser).ParseSet,
- (*Parser).ParseClosed,
- (*Parser).ParseWordValue)
- }
- func (parser *Parser) ParseArguments() *Ast {
- parser.LogDebug("ParseArgument: %s\n", parser.current.String())
- return parser.ParseMany(AstKindArguments, nil, (*Parser).ParseArgument)
- }
- func (parser *Parser) ParseList() *Ast {
- parser.LogDebug("ParseList: %s\n", parser.current.String())
- op := parser.Accept(TokenKindOpenList)
- if op.IsNone() {
- return NewAstNone()
- }
- if op.IsError() {
- return parser.NewAstError("Unexpected value.")
- }
- ast := NewAstWithToken(AstKindList, op)
- args := parser.ParseArguments()
- if AstIsError(args) {
- return args
- }
- if cp := parser.Accept(TokenKindCloseList); cp.IsNone() || cp.IsError() {
- return parser.NewAstError("expected closing brackets")
- }
- ast.AppendChild(args)
- return ast
- }
- func (parser *Parser) ParseParenthesis() *Ast {
- parser.LogDebug("ParseParenthesis: %s\n", parser.current.String())
- op := parser.Accept(TokenKindOpenParen)
- if op.IsNone() {
- return NewAstNone()
- }
- if op.IsError() {
- return parser.NewAstError("Unexpected value.")
- }
- ast := NewAstWithToken(AstKindParenthesis, op)
- expr := parser.ParseExpression()
- if expr.IsNone() {
- return parser.NewAstError("expected expression")
- }
- if AstIsError(expr) {
- return expr
- }
- if cp := parser.Accept(TokenKindCloseParen); cp.IsNone() || cp.IsError() {
- return parser.NewAstError("expected closing parenthesis")
- }
- ast.AppendChild(expr)
- return ast
- }
- func (parser *Parser) ParseBlock() *Ast {
- parser.LogDebug("ParseBlock: %s\n", parser.current.String())
- op := parser.Accept(TokenKindOpenBlock)
- if op.IsNone() {
- return NewAstNone()
- }
- if op.IsError() {
- return parser.NewAstError("Unexpected value.")
- }
- ast := NewAstWithToken(AstKindBlock, op)
- stats := parser.ParseStatements()
- if stats.IsNone() {
- return parser.NewAstError("expected expression")
- }
- if AstIsError(stats) {
- return stats
- }
- if cp := parser.Accept(TokenKindCloseBlock); cp.IsNone() || cp.IsError() {
- return parser.NewAstError("expected closing block")
- }
- ast.AppendChild(stats)
- return ast
- }
- func (parser *Parser) ParseTarget() *Ast {
- parser.LogDebug("ParseTarget: %s\n", parser.current.String())
- target := parser.Accept(TokenKindWord, TokenKindType, TokenKindSymbol)
- ast := NewAstWithToken(AstKindTarget, target)
- if target.IsNone() {
- paren := parser.ParseParenthesis()
- if paren.IsNone() {
- return parser.NewAstError("expected word, symbol or parenthesis")
- }
- ast.AppendChild(paren)
- }
- return ast
- }
- func (parser *Parser) ParseSet() *Ast {
- parser.LogDebug("ParseSet: %s\n", parser.current.String())
-
- set := parser.Accept(TokenKindSet)
- if set.IsNone() {
- return NewAstNone()
- }
- ast := NewAstWithToken(AstKindSet, set)
- target := parser.ParseTarget()
- ast.AppendChild(target)
- argument := parser.ParseArgument()
- if argument.IsNone() {
- return parser.NewAstError("Expected argument to set")
- }
- ast.AppendChild(argument)
- return ast
- }
- func (parser *Parser) ParseGet() *Ast {
- parser.LogDebug("ParseGet: %s\n", parser.current.String())
- get := parser.Accept(TokenKindGet)
- if get.IsNone() {
- return NewAstNone()
- }
- ast := NewAstWithToken(AstKindGet, get)
- target := parser.ParseTarget()
- ast.AppendChild(target)
- return ast
- }
- func (parser *Parser) ParseCommand() *Ast {
- parser.LogDebug("ParseCommand: %s\n", parser.current.String())
- word := parser.Accept(TokenKindWord, TokenKindType)
- if word.IsNone() {
- return NewAstNone()
- }
- arguments := parser.ParseArguments()
- command := NewAstWithToken(AstKindCommand, word)
- command.AppendChild(arguments)
- return command
- }
- func (parser *Parser) ParseClosed() *Ast {
- parser.LogDebug("ParseClosed: %s\n", parser.current.String())
- exp := parser.ParseAny(AstKindClosed, (*Parser).ParseParenthesis,
- (*Parser).ParseBlock, (*Parser).ParseList)
- return exp
- }
- func (parser *Parser) ParseExpression() *Ast {
- parser.LogDebug("ParseExpression: %s\n", parser.current.String())
- exp := parser.ParseRequireAny(AstKindExpression, (*Parser).ParseCommand,
- (*Parser).ParseSet,
- (*Parser).ParseGet, (*Parser).ParseValue )
- return exp
- }
- func (parser *Parser) ParseExpressionStatement() *Ast {
- parser.LogDebug("ParseExpressionStatement: %s\n", parser.current.String())
- expr := parser.ParseExpression()
- if expr.IsNone() {
- return NewAstNone()
- }
-
- if eox := parser.Accept(TokenKindEOX); eox.IsNone() {
- return parser.NewAstError("expected end of statement")
- }
-
- return NewAstNone()
- }
- func (parser *Parser) ParseEmptyStatement() *Ast {
- parser.LogDebug("ParseEmptyStatement: %s\n", parser.current.String())
- if eox := parser.Accept(TokenKindEOX); eox.IsNone() {
- return parser.NewAstError("expected end of statement")
- }
- return NewAstWithToken(AstKindStatement, parser.current)
-
- }
- func (parser Parser) NextIs(kinds ...TokenKind) bool {
- for _, kind := range kinds {
- if kind == parser.current.TokenKind {
- return true
- }
- }
- return false
- }
- func (parser Parser) NextIsClosed() bool {
- return parser.NextIs(TokenKindOpenBlock, TokenKindOpenList, TokenKindOpenParen)
- }
- func (parser Parser) NextIsWord() bool {
- return parser.NextIs(TokenKindWord)
- }
- func (parser Parser) NextIsGetter() bool {
- return parser.NextIs(TokenKindGet)
- }
- func (parser Parser) NextIsSetter() bool {
- return parser.NextIs(TokenKindSet)
- }
- func (parser Parser) NextIsValue() bool {
- return parser.NextIs(TokenKindString, TokenKindType,
- TokenKindInteger, TokenKindFloat, TokenKindBoolean,
- TokenKindSymbol)
- }
- func (parser Parser) NextIsEOX() bool {
- return parser.NextIs(TokenKindEOX)
- }
- func (parser Parser) NextIsEOF() bool {
- return parser.NextIs(TokenKindEOF)
- }
- func (parser Parser) NextIsExpression() bool {
- return parser.NextIs(TokenKindWord,
- TokenKindGet,
- TokenKindSet,
- TokenKindString,
- TokenKindType,
- TokenKindInteger,
- TokenKindFloat,
- TokenKindBoolean,
- TokenKindSymbol)
- }
- func (parser *Parser) ParseStatement() *Ast {
- parser.LogDebug("ParseStatement: %s\n", parser.current.String())
- switch {
- case parser.NextIsClosed(): return parser.ParseClosed()
- case parser.NextIsExpression(): return parser.ParseExpressionStatement()
- case parser.NextIsEOX(): return parser.ParseEmptyStatement()
- case parser.NextIsEOF(): return NewAstNone()
- default:
- parser.Panicf("Unexpected token in statement")
- return parser.NewAstError("Unexpected token in statement")
- }
- }
- func (parser *Parser) ParseStatements() *Ast {
- parser.LogDebug("ParseStatements: %s\n", parser.current.String())
- return parser.ParseMany(AstKindStatements, nil, (*Parser).ParseStatement)
- }
- func (parser *Parser) ParseProgram() *Ast {
- parser.LogDebug("ParseProgram: %s\n", parser.current.String())
- stats := parser.ParseStatements()
-
- eof := parser.Accept(TokenKindEOF)
- aeof := NewAstWithToken(AstKindEnd, eof)
- if eof.IsNone() {
- aeof = parser.NewAstError("Expceted EOF, have: %s", parser.current.String())
- }
- children := []*Ast{stats, aeof}
- return NewAst(AstKindProgram, nil, children, NoToken())
- }
- func (parser *Parser) Parse() *Ast {
- ast := parser.ParseProgram()
- return ast
- }
- func NewParser(lexer *Lexer) *Parser {
- parser := &Parser{Lexer: lexer, current: NoToken(), LoggerWrapper: LoggerWrapper{nil}}
- return parser
- }
- func NewParserFromString(input string) *Parser {
- lexer := NewLexerFromString(input)
- return NewParser(lexer)
- }
- func NewParserFromFilename(filename string) (*Parser, error) {
- lexer, err := NewLexerFromFilename(filename)
- if err != nil {
- return nil, err
- }
- return NewParser(lexer), nil
- }
|