|
@@ -81,6 +81,22 @@ func (parser *Parser) Advance() {
|
|
parser.LogDebug("Next token: %s\n", token.String())
|
|
parser.LogDebug("Next token: %s\n", token.String())
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Skips tokens until a closer ) } ] OEX or EOF is found, to skip parse errors,
|
|
|
|
+ * and to be able to continue parsing despite errors.. */
|
|
|
|
+func (parser *Parser) SkipError() Token {
|
|
|
|
+ parser.Advance()
|
|
|
|
+ for {
|
|
|
|
+ parser.Advance()
|
|
|
|
+ if parser.NextIsErrorSkipped() {
|
|
|
|
+ return parser.current
|
|
|
|
+ }
|
|
|
|
+ if parser.NextIs(TokenKindError, TokenKindNone) {
|
|
|
|
+ parser.Panicf("Cannot recover from parse error. Parse ended.")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return parser.current
|
|
|
|
+}
|
|
|
|
+
|
|
/* Looks at the current token and advances the lexer if the token is of any of
|
|
/* Looks at the current token and advances the lexer if the token is of any of
|
|
the token kinds given in kinds. In this case it will return the accepted
|
|
the token kinds given in kinds. In this case it will return the accepted
|
|
token and advance the parser. Otherwise, it will call panicf with ann
|
|
token and advance the parser. Otherwise, it will call panicf with ann
|
|
@@ -103,52 +119,6 @@ func (parser *Parser) Require(kinds ...TokenKind) Token {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-/* Looks at the current token and advances the lexer if the token is of any of
|
|
|
|
-the token kinds given in kinds. In this case it will return the accepted
|
|
|
|
-token and advance the parser. Otherwise, if no token kind matches, the lexer
|
|
|
|
-does not advance and the current token remains the same, except if that was nil.*/
|
|
|
|
-func (parser *Parser) AcceptDeprecated(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 {
|
|
func (parser *Parser) NewAstError(message string, args ...interface{}) *Ast {
|
|
sv := StringValue(fmt.Sprintf(message+" at token "+parser.current.String(), args))
|
|
sv := StringValue(fmt.Sprintf(message+" at token "+parser.current.String(), args))
|
|
pos := parser.current.Position
|
|
pos := parser.current.Position
|
|
@@ -156,37 +126,6 @@ func (parser *Parser) NewAstError(message string, args ...interface{}) *Ast {
|
|
return NewAst(AstKindError, nil, EmptyAstArray(), tok)
|
|
return NewAst(AstKindError, nil, EmptyAstArray(), tok)
|
|
}
|
|
}
|
|
|
|
|
|
-func (parser *Parser) ParseAnyDeprecated(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) ParseRequireAnyDeprecated(astkind AstKind, parsefuncs ...(func(*Parser) *Ast)) *Ast {
|
|
|
|
- ast := parser.ParseAnyDeprecated(astkind, parsefuncs...)
|
|
|
|
- if ast.IsNone() {
|
|
|
|
- err := parser.NewAstError("Unexpected token in %v", parsefuncs)
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- return ast
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
// Also handles none or error vales of the token
|
|
// Also handles none or error vales of the token
|
|
|
|
|
|
func (parser *Parser) NewAst(kind AstKind, parent * Ast, children []*Ast, value Token) *Ast{
|
|
func (parser *Parser) NewAst(kind AstKind, parent * Ast, children []*Ast, value Token) *Ast{
|
|
@@ -498,6 +437,11 @@ func (parser Parser) NextIsArgument() bool {
|
|
TokenKindSymbol)
|
|
TokenKindSymbol)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (parser Parser) NextIsErrorSkipped() bool {
|
|
|
|
+ return parser.NextIs(TokenKindCloseBlock, TokenKindCloseList, TokenKindCloseParen,
|
|
|
|
+ TokenKindEOX, TokenKindEOF)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
func (parser Parser) NextIsEOX() bool {
|
|
func (parser Parser) NextIsEOX() bool {
|
|
return parser.NextIs(TokenKindEOX)
|
|
return parser.NextIs(TokenKindEOX)
|