|
@@ -45,12 +45,33 @@ type Parser struct {
|
|
Lexer *Lexer
|
|
Lexer *Lexer
|
|
current Token
|
|
current Token
|
|
LoggerWrapper
|
|
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) {
|
|
func (parser *Parser) SetLogger(logger Logger) {
|
|
parser.LoggerWrapper = LoggerWrapper{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() {
|
|
func (parser *Parser) Advance() {
|
|
token := parser.Lexer.Lex()
|
|
token := parser.Lexer.Lex()
|
|
parser.current = token
|
|
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 {
|
|
func (parser *Parser) ParseStatement() *Ast {
|
|
parser.LogDebug("ParseStatement: %s\n", parser.current.String())
|
|
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 {
|
|
func (parser *Parser) ParseStatements() *Ast {
|
|
@@ -402,7 +479,7 @@ func (parser *Parser) Parse() *Ast {
|
|
}
|
|
}
|
|
|
|
|
|
func NewParser(lexer *Lexer) *Parser {
|
|
func NewParser(lexer *Lexer) *Parser {
|
|
- parser := &Parser{lexer, NoToken(), LoggerWrapper{nil}}
|
|
|
|
|
|
+ parser := &Parser{Lexer: lexer, current: NoToken(), LoggerWrapper: LoggerWrapper{nil}}
|
|
return parser
|
|
return parser
|
|
}
|
|
}
|
|
|
|
|