Browse Source

Reworking the parser somewhat.

Beoran 6 years ago
parent
commit
ef782fc63c
2 changed files with 108 additions and 8 deletions
  1. 24 1
      go.mod
  2. 84 7
      parser.go

+ 24 - 1
go.mod

@@ -2,7 +2,30 @@ module muesli
 
 require gitlab.com/beoran/monolog v0.0.0
 
-require gitlab.com/beoran/gdast v0.0.0
+require (
+	github.com/cosiner/argv v0.0.1 // indirect
+	github.com/cpuguy83/go-md2man v1.0.10 // indirect
+	github.com/go-delve/delve v1.2.0 // indirect
+	github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
+	github.com/mattn/go-colorable v0.1.1 // indirect
+	github.com/mattn/go-isatty v0.0.7 // indirect
+	github.com/mattn/go-runewidth v0.0.4 // indirect
+	github.com/peterh/liner v1.1.0 // indirect
+	github.com/pkg/profile v1.3.0 // indirect
+	github.com/russross/blackfriday v2.0.0+incompatible // indirect
+	github.com/sirupsen/logrus v1.4.0 // indirect
+	github.com/spf13/cobra v0.0.3 // indirect
+	github.com/spf13/pflag v1.0.3 // indirect
+	github.com/stretchr/testify v1.3.0 // indirect
+	gitlab.com/beoran/gdast v0.0.0
+	golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c // indirect
+	golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c // indirect
+	golang.org/x/net v0.0.0-20190328230028-74de082e2cca // indirect
+	golang.org/x/sys v0.0.0-20190329044733-9eb1bfa1ce65 // indirect
+	golang.org/x/tools v0.0.0-20190330180304-aef51cc3777c // indirect
+	gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
+	gopkg.in/yaml.v2 v2.2.2 // indirect
+)
 
 replace gitlab.com/beoran/monolog => ../monolog
 

+ 84 - 7
parser.go

@@ -45,12 +45,33 @@ type Parser struct {
 	Lexer   *Lexer
 	current Token
 	LoggerWrapper
+    Errors []ParserError
+}
+
+// panic with this type on errors that would prevent the parser 
+// from making progress.
+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
@@ -367,14 +388,70 @@ func (parser *Parser) ParseEmptyStatement() *Ast {
   
 }
 
+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())
-    
-	ast := parser.ParseAny(AstKindStatement,
-        (*Parser).ParseClosed,
-        (*Parser).ParseExpressionStatement,
-        (*Parser).ParseEmptyStatement)
-	return ast
+    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 {
@@ -402,7 +479,7 @@ func (parser *Parser) Parse() *Ast {
 }
 
 func NewParser(lexer *Lexer) *Parser {
-	parser := &Parser{lexer, NoToken(), LoggerWrapper{nil}}
+	parser := &Parser{Lexer: lexer, current: NoToken(), LoggerWrapper: LoggerWrapper{nil}}
 	return parser
 }