Parsing functions *always* begin on current token, leave trailing one
This commit is contained in:
parent
1b50c8f879
commit
bca9de4106
|
@ -31,31 +31,41 @@ func (this *Parser) ParseInto (tree *Tree) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// expect gets the next token if it matches a list of token kind(s), else it
|
||||
// returns an error describing what it expected.
|
||||
func (this *Parser) expect (allowed ...lexer.TokenKind) (lexer.Token, error) {
|
||||
token, err := this.next()
|
||||
if err != nil { return lexer.Token { }, err }
|
||||
if !token.Is(allowed...) {
|
||||
return lexer.Token { }, errors.Errorf (
|
||||
token.Position, "expected %s",
|
||||
// expect checks the current token to see if it matches a list of token kind(s),
|
||||
// else it returns an error describing what it expected.
|
||||
func (this *Parser) expect (allowed ...lexer.TokenKind) error {
|
||||
if !this.token.Is(allowed...) {
|
||||
return errors.Errorf (
|
||||
this.token.Position, "expected %s",
|
||||
commaList(allowed...))
|
||||
}
|
||||
return token, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// expectDesc is like expect, but the expected entitie(s) are described
|
||||
// manually. This can be helpful when a large syntactical entity is expected and
|
||||
// the first token(s) of it offer insufficient information.
|
||||
func (this *Parser) expectDesc (description string, allowed ...lexer.TokenKind) (lexer.Token, error) {
|
||||
token, err := this.next()
|
||||
if err != nil { return lexer.Token { }, err }
|
||||
if !token.Is(allowed...) {
|
||||
return lexer.Token { }, errors.Errorf (
|
||||
token.Position, "expected %s",
|
||||
func (this *Parser) expectDesc (description string, allowed ...lexer.TokenKind) error {
|
||||
if !this.token.Is(allowed...) {
|
||||
return errors.Errorf (
|
||||
this.token.Position, "expected %s",
|
||||
description)
|
||||
}
|
||||
return token, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// expectNext is like expect, but gets the next token first.
|
||||
func (this *Parser) expectNext (allowed ...lexer.TokenKind) error {
|
||||
err := this.next()
|
||||
if err != nil { return err }
|
||||
return this.expect(allowed...)
|
||||
}
|
||||
|
||||
// expectNextDesc is like expectDesc, but gets the next token first.
|
||||
func (this *Parser) expectNextDesc (description string, allowed ...lexer.TokenKind) error {
|
||||
err := this.next()
|
||||
if err != nil { return err }
|
||||
return this.expectDesc(description, allowed...)
|
||||
}
|
||||
|
||||
// expectValue returns an error if the current token's value does not match the
|
||||
|
@ -80,20 +90,22 @@ func (this *Parser) expectValueDesc (description string, kind lexer.TokenKind, a
|
|||
return nil
|
||||
}
|
||||
|
||||
func (this *Parser) next () (lexer.Token, error) {
|
||||
func (this *Parser) next () error {
|
||||
token, err := this.lexer.Next()
|
||||
if err != nil { return token, err }
|
||||
if err != nil { return err }
|
||||
this.token = token
|
||||
return token, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Parser) parse () error {
|
||||
err := this.next()
|
||||
if err != nil { return err }
|
||||
for {
|
||||
token, err := this.expectDesc (
|
||||
err = this.expectDesc (
|
||||
descriptionTopLevel,
|
||||
startTokensTopLevel...)
|
||||
if err != nil { return err }
|
||||
if token.EOF() { return nil }
|
||||
if this.token.EOF() { return nil }
|
||||
|
||||
err = this.parseTopLevel()
|
||||
if err != nil { return err }
|
||||
|
|
|
@ -13,14 +13,12 @@ var startTokensTopLevel = []lexer.TokenKind {
|
|||
}
|
||||
|
||||
func (this *Parser) parseTopLevel () error {
|
||||
var err error
|
||||
var token lexer.Token
|
||||
|
||||
var err error
|
||||
access := entity.AccessPrivate
|
||||
if this.token.Kind == lexer.Symbol {
|
||||
access, err = this.parseAccess()
|
||||
|
||||
token, err = this.expectDesc (
|
||||
err = this.expectNextDesc (
|
||||
descriptionTopLevel,
|
||||
lexer.Symbol,
|
||||
lexer.LBracket,
|
||||
|
@ -39,20 +37,20 @@ func (this *Parser) parseTopLevel () error {
|
|||
|
||||
// TypeIdent: Method, or Typedef
|
||||
typeName := this.token.Value
|
||||
token, err = this.expect(lexer.Dot, lexer.Colon)
|
||||
err = this.expectNext(lexer.Dot, lexer.Colon)
|
||||
if err != nil { return err }
|
||||
|
||||
switch token.Kind {
|
||||
switch this.token.Kind {
|
||||
case lexer.Dot:
|
||||
// Dot: Method
|
||||
_, err = this.expectDesc(descriptionSignature, startTokensSignature...)
|
||||
err = this.expectNextDesc(descriptionSignature, startTokensSignature...)
|
||||
if err != nil { return err }
|
||||
method, err := this.parseMethod(access, typeName)
|
||||
if err != nil { return err }
|
||||
this.tree.AddDeclaration(method)
|
||||
case lexer.Colon:
|
||||
// Colon: Typedef
|
||||
_, err = this.expect(startTokensType...)
|
||||
err = this.expectNext(startTokensType...)
|
||||
if err != nil { return err }
|
||||
typedef, err := this.parseTypedef(access, typeName)
|
||||
if err != nil { return err }
|
||||
|
@ -81,21 +79,21 @@ func (this *Parser) parseFunction (access entity.Access) (*entity.Function, erro
|
|||
Signature: signature,
|
||||
}
|
||||
|
||||
token, err := this.expectDesc (
|
||||
err = this.expectNextDesc (
|
||||
"Function body, Link name, " + descriptionTopLevel,
|
||||
appendCopy(startTokensTopLevel, lexer.Symbol, lexer.String)...)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
if token.Is(lexer.String) {
|
||||
if this.token.Is(lexer.String) {
|
||||
// String: Link name
|
||||
function.LinkName = token.Value
|
||||
token, err = this.expectDesc (
|
||||
function.LinkName = this.token.Value
|
||||
err = this.expectNextDesc (
|
||||
"Function body, " + descriptionTopLevel,
|
||||
appendCopy(startTokensTopLevel, lexer.Symbol)...)
|
||||
if err != nil { return nil, err }
|
||||
}
|
||||
|
||||
if token.Is(startTokensTopLevel...) {
|
||||
if this.token.Is(startTokensTopLevel...) {
|
||||
// startTokensTopLevel: function has no body and is finished,
|
||||
// move on to next top level declaration or graceful EOF.
|
||||
return function, nil
|
||||
|
@ -106,7 +104,7 @@ func (this *Parser) parseFunction (access entity.Access) (*entity.Function, erro
|
|||
if err != nil { return nil, err }
|
||||
|
||||
// Expression
|
||||
_, err = this.expectDesc(descriptionExpression, startTokensExpression...)
|
||||
err = this.expectNextDesc(descriptionExpression, startTokensExpression...)
|
||||
if err != nil { return nil, err }
|
||||
bodyExpression, err := this.parseExpression()
|
||||
if err != nil { return nil, err }
|
||||
|
@ -127,5 +125,5 @@ func (this *Parser) parseMethod (access entity.Access, typeName string) (*entity
|
|||
}
|
||||
|
||||
func (this *Parser) parseTypedef (access entity.Access, typeName string) (*entity.Typedef, error) {
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue