Separated parser into two packages
This commit is contained in:
parent
5b24bdc32b
commit
5f035df827
|
@ -1,6 +1,3 @@
|
|||
// Package parser implements the parsing stage of the FSPL compiler.
|
||||
// The parser takes in a stream of tokens from the lexer and converts them into
|
||||
// an abstract syntax tree (AST), which is assembled out of structures from the
|
||||
// entity package. The parser only fills out fields on the structures that
|
||||
// pertain to position and syntax.
|
||||
// Package parser defines basic parser utilities.
|
||||
// It defines a parser type which may be embedded to create specialized parsers.
|
||||
package parser
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
// Package fsplParser implements the parsing stage of the FSPL compiler.
|
||||
// The parser takes in a stream of tokens from the lexer and converts them into
|
||||
// an abstract syntax tree (AST), which is assembled out of structures from the
|
||||
// entity package. The parser only fills out fields on the structures that
|
||||
// pertain to position and syntax.
|
||||
package fsplParser
|
|
@ -1,4 +1,4 @@
|
|||
package parser
|
||||
package fsplParser
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/fspl/lexer"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/errors"
|
||||
|
@ -15,7 +15,7 @@ var startTokensExpression = []lexer.TokenKind {
|
|||
lexer.String,
|
||||
}
|
||||
|
||||
func (this *parser) parseExpression () (entity.Expression, error) {
|
||||
func (this *treeParser) parseExpression () (entity.Expression, error) {
|
||||
// Steps that this function takes to parse expressions:
|
||||
// 1. Run a decision tree to parse the expression.
|
||||
// 2. After that, test for infix operators (. and =). We will not need
|
||||
|
@ -90,7 +90,7 @@ func (this *parser) parseExpression () (entity.Expression, error) {
|
|||
return expression, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseExpressionRoot () (entity.Expression, error) {
|
||||
func (this *treeParser) parseExpressionRoot () (entity.Expression, error) {
|
||||
err := this.ExpectDesc(descriptionExpression, startTokensExpression...)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
|
@ -103,10 +103,10 @@ func (this *parser) parseExpressionRoot () (entity.Expression, error) {
|
|||
case lexer.Float: return this.parseLiteralFloat()
|
||||
case lexer.String: return this.parseLiteralString()
|
||||
}
|
||||
panic(this.Bug())
|
||||
panic(this.bug())
|
||||
}
|
||||
|
||||
func (this *parser) parseExpressionRootIdent () (entity.Expression, error) {
|
||||
func (this *treeParser) parseExpressionRootIdent () (entity.Expression, error) {
|
||||
err := this.Expect(lexer.Ident)
|
||||
if err != nil { return nil, err }
|
||||
name := this.Value()
|
||||
|
@ -139,7 +139,7 @@ func (this *parser) parseExpressionRootIdent () (entity.Expression, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (this *parser) parseExpressionRootLParen() (entity.Expression, error) {
|
||||
func (this *treeParser) parseExpressionRootLParen() (entity.Expression, error) {
|
||||
err := this.Expect(lexer.LParen)
|
||||
if err != nil { return nil, err }
|
||||
pos := this.Pos()
|
||||
|
@ -150,10 +150,10 @@ func (this *parser) parseExpressionRootLParen() (entity.Expression, error) {
|
|||
case lexer.Star: return this.parseLiteralArrayCore(pos)
|
||||
case lexer.Dot: return this.parseLiteralStructCore(pos)
|
||||
}
|
||||
panic(this.Bug())
|
||||
panic(this.bug())
|
||||
}
|
||||
|
||||
func (this *parser) parseExpressionRootLBracket () (entity.Expression, error) {
|
||||
func (this *treeParser) parseExpressionRootLBracket () (entity.Expression, error) {
|
||||
err := this.Expect(lexer.LBracket)
|
||||
if err != nil { return nil, err }
|
||||
pos := this.Pos()
|
||||
|
@ -166,10 +166,10 @@ func (this *parser) parseExpressionRootLBracket () (entity.Expression, error) {
|
|||
case lexer.Star: return this.parseOperationCore(pos)
|
||||
case lexer.Symbol: return this.parseExpressionRootLBracketSymbol(pos)
|
||||
}
|
||||
panic(this.Bug())
|
||||
panic(this.bug())
|
||||
}
|
||||
|
||||
func (this *parser) parseExpressionRootLBracketIdent (pos errors.Position) (entity.Expression, error) {
|
||||
func (this *treeParser) parseExpressionRootLBracketIdent (pos errors.Position) (entity.Expression, error) {
|
||||
err := this.Expect(lexer.Ident)
|
||||
if err != nil { return nil, err }
|
||||
name := this.Value()
|
||||
|
@ -180,7 +180,7 @@ func (this *parser) parseExpressionRootLBracketIdent (pos errors.Position) (enti
|
|||
}
|
||||
}
|
||||
|
||||
func (this *parser) parseDereferenceOrSubscriptCore (pos errors.Position) (entity.Expression, error) {
|
||||
func (this *treeParser) parseDereferenceOrSubscriptCore (pos errors.Position) (entity.Expression, error) {
|
||||
err := this.Expect(lexer.Dot)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
|
@ -220,7 +220,7 @@ func (this *parser) parseDereferenceOrSubscriptCore (pos errors.Position) (entit
|
|||
}
|
||||
}
|
||||
|
||||
func (this *parser) parseExpressionRootLBracketSymbol (pos errors.Position) (entity.Expression, error) {
|
||||
func (this *treeParser) parseExpressionRootLBracketSymbol (pos errors.Position) (entity.Expression, error) {
|
||||
err := this.ExpectValue (
|
||||
lexer.Symbol,
|
||||
appendCopy(valuesOperator, "\\", "#", "@", "~", "~~")...)
|
||||
|
@ -236,7 +236,7 @@ func (this *parser) parseExpressionRootLBracketSymbol (pos errors.Position) (ent
|
|||
}
|
||||
}
|
||||
|
||||
func (this *parser) parseCallCore (pos errors.Position, module string) (*entity.Call, error) {
|
||||
func (this *treeParser) parseCallCore (pos errors.Position, module string) (*entity.Call, error) {
|
||||
err := this.Expect(lexer.Ident)
|
||||
if err != nil { return nil, err }
|
||||
call := &entity.Call {
|
||||
|
@ -263,7 +263,7 @@ func (this *parser) parseCallCore (pos errors.Position, module string) (*entity.
|
|||
return call, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseMethodCallCore (pos errors.Position, source entity.Expression) (*entity.MethodCall, error) {
|
||||
func (this *treeParser) parseMethodCallCore (pos errors.Position, source entity.Expression) (*entity.MethodCall, error) {
|
||||
err := this.Expect(lexer.LBracket)
|
||||
if err != nil { return nil, err }
|
||||
err = this.ExpectNext(lexer.Ident)
|
||||
|
@ -292,7 +292,7 @@ func (this *parser) parseMethodCallCore (pos errors.Position, source entity.Expr
|
|||
return call, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseReturnOrBreakCore (pos errors.Position) (entity.Expression, error) {
|
||||
func (this *treeParser) parseReturnOrBreakCore (pos errors.Position) (entity.Expression, error) {
|
||||
err := this.ExpectValue(lexer.Ident, "break", "return")
|
||||
if err != nil { return nil, err }
|
||||
name := this.Value()
|
||||
|
@ -325,10 +325,10 @@ func (this *parser) parseReturnOrBreakCore (pos errors.Position) (entity.Express
|
|||
Value: value,
|
||||
}, nil
|
||||
}
|
||||
panic(this.Bug())
|
||||
panic(this.bug())
|
||||
}
|
||||
|
||||
func (this *parser) parseSliceCore (pos errors.Position) (*entity.Slice, error) {
|
||||
func (this *treeParser) parseSliceCore (pos errors.Position) (*entity.Slice, error) {
|
||||
err := this.ExpectValue(lexer.Symbol , "\\")
|
||||
if err != nil { return nil, err }
|
||||
slice := &entity.Slice {
|
||||
|
@ -369,7 +369,7 @@ func (this *parser) parseSliceCore (pos errors.Position) (*entity.Slice, error)
|
|||
return slice, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseLengthCore (pos errors.Position) (*entity.Length, error) {
|
||||
func (this *treeParser) parseLengthCore (pos errors.Position) (*entity.Length, error) {
|
||||
err := this.ExpectValue(lexer.Symbol , "#")
|
||||
if err != nil { return nil, err }
|
||||
length := &entity.Length {
|
||||
|
@ -388,7 +388,7 @@ func (this *parser) parseLengthCore (pos errors.Position) (*entity.Length, error
|
|||
return length, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseReferenceCore (pos errors.Position) (*entity.Reference, error) {
|
||||
func (this *treeParser) parseReferenceCore (pos errors.Position) (*entity.Reference, error) {
|
||||
err := this.ExpectValue(lexer.Symbol , "@")
|
||||
if err != nil { return nil, err }
|
||||
reference := &entity.Reference {
|
||||
|
@ -407,7 +407,7 @@ func (this *parser) parseReferenceCore (pos errors.Position) (*entity.Reference,
|
|||
return reference, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseValueOrBitCastCore (pos errors.Position) (entity.Expression, error) {
|
||||
func (this *treeParser) parseValueOrBitCastCore (pos errors.Position) (entity.Expression, error) {
|
||||
err := this.ExpectValue(lexer.Symbol , "~", "~~")
|
||||
if err != nil { return nil, err }
|
||||
tokValue := this.Value()
|
||||
|
@ -439,7 +439,7 @@ func (this *parser) parseValueOrBitCastCore (pos errors.Position) (entity.Expres
|
|||
Value: value,
|
||||
}, nil
|
||||
}
|
||||
panic(this.Bug())
|
||||
panic(this.bug())
|
||||
}
|
||||
|
||||
var valuesOperator = []string {
|
||||
|
@ -447,7 +447,7 @@ var valuesOperator = []string {
|
|||
"!", "|", "&", "^", "<<", ">>", "<", ">", "<=", ">=", "=",
|
||||
}
|
||||
|
||||
func (this *parser) parseOperationCore (pos errors.Position) (*entity.Operation, error) {
|
||||
func (this *treeParser) parseOperationCore (pos errors.Position) (*entity.Operation, error) {
|
||||
// TODO: maybe come up with a more elegant way of writing this?
|
||||
// possibly make a verion of expectValue that matches a list of kinds
|
||||
// and a list of values. could also make a version that accepts any kind
|
||||
|
@ -483,7 +483,7 @@ func (this *parser) parseOperationCore (pos errors.Position) (*entity.Operation,
|
|||
return operation, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseBlock () (*entity.Block, error) {
|
||||
func (this *treeParser) parseBlock () (*entity.Block, error) {
|
||||
err := this.ExpectDesc("Block", lexer.LBrace)
|
||||
if err != nil { return nil, err }
|
||||
block := &entity.Block {
|
||||
|
@ -511,7 +511,7 @@ func (this *parser) parseBlock () (*entity.Block, error) {
|
|||
var descriptionDeclaration = "declaration"
|
||||
var startTokensDeclaration = []lexer.TokenKind { lexer.Ident }
|
||||
|
||||
func (this *parser) parseDeclaration () (*entity.Declaration, error) {
|
||||
func (this *treeParser) parseDeclaration () (*entity.Declaration, error) {
|
||||
err := this.ExpectDesc(descriptionDeclaration, startTokensDeclaration...)
|
||||
if err != nil { return nil, err }
|
||||
name := this.Value()
|
||||
|
@ -520,7 +520,7 @@ func (this *parser) parseDeclaration () (*entity.Declaration, error) {
|
|||
return this.parseDeclarationCore(pos, name)
|
||||
}
|
||||
|
||||
func (this *parser) parseDeclarationCore (pos errors.Position, name string) (*entity.Declaration, error) {
|
||||
func (this *treeParser) parseDeclarationCore (pos errors.Position, name string) (*entity.Declaration, error) {
|
||||
err := this.Expect(lexer.Colon)
|
||||
if err != nil { return nil, err }
|
||||
this.Next()
|
||||
|
@ -534,7 +534,7 @@ func (this *parser) parseDeclarationCore (pos errors.Position, name string) (*en
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseIfElse () (*entity.IfElse, error) {
|
||||
func (this *treeParser) parseIfElse () (*entity.IfElse, error) {
|
||||
err := this.ExpectValue(lexer.Ident, "if")
|
||||
if err != nil { return nil, err }
|
||||
ifElse := &entity.IfElse {
|
||||
|
@ -563,7 +563,7 @@ func (this *parser) parseIfElse () (*entity.IfElse, error) {
|
|||
return ifElse, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseLoop () (*entity.Loop, error) {
|
||||
func (this *treeParser) parseLoop () (*entity.Loop, error) {
|
||||
err := this.ExpectValue(lexer.Ident, "loop")
|
||||
if err != nil { return nil, err }
|
||||
pos := this.Pos()
|
|
@ -1,10 +1,10 @@
|
|||
package parser
|
||||
package fsplParser
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/fspl/lexer"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/errors"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/entity"
|
||||
|
||||
func (this *parser) parseLiteralInt () (*entity.LiteralInt, error) {
|
||||
func (this *treeParser) parseLiteralInt () (*entity.LiteralInt, error) {
|
||||
err := this.Expect(lexer.Int)
|
||||
if err != nil { return nil, err }
|
||||
defer this.Next()
|
||||
|
@ -18,7 +18,7 @@ func (this *parser) parseLiteralInt () (*entity.LiteralInt, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseLiteralFloat () (*entity.LiteralFloat, error) {
|
||||
func (this *treeParser) parseLiteralFloat () (*entity.LiteralFloat, error) {
|
||||
err := this.Expect(lexer.Float)
|
||||
if err != nil { return nil, err }
|
||||
defer this.Next()
|
||||
|
@ -32,7 +32,7 @@ func (this *parser) parseLiteralFloat () (*entity.LiteralFloat, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseLiteralString () (*entity.LiteralString, error) {
|
||||
func (this *treeParser) parseLiteralString () (*entity.LiteralString, error) {
|
||||
err := this.Expect(lexer.String)
|
||||
if err != nil { return nil, err }
|
||||
defer this.Next()
|
||||
|
@ -43,7 +43,7 @@ func (this *parser) parseLiteralString () (*entity.LiteralString, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseLiteralBoolean () (*entity.LiteralBoolean, error) {
|
||||
func (this *treeParser) parseLiteralBoolean () (*entity.LiteralBoolean, error) {
|
||||
err := this.ExpectValueDesc("boolean", lexer.Ident, "true", "false")
|
||||
if err != nil { return nil, err }
|
||||
defer this.Next()
|
||||
|
@ -54,7 +54,7 @@ func (this *parser) parseLiteralBoolean () (*entity.LiteralBoolean, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseLiteralNil () (*entity.LiteralNil, error) {
|
||||
func (this *treeParser) parseLiteralNil () (*entity.LiteralNil, error) {
|
||||
err := this.ExpectValueDesc("Nil", lexer.Ident, "nil")
|
||||
if err != nil { return nil, err }
|
||||
defer this.Next()
|
||||
|
@ -64,7 +64,7 @@ func (this *parser) parseLiteralNil () (*entity.LiteralNil, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseLiteralArrayCore (pos errors.Position) (*entity.LiteralArray, error) {
|
||||
func (this *treeParser) parseLiteralArrayCore (pos errors.Position) (*entity.LiteralArray, error) {
|
||||
err := this.Expect(lexer.Star)
|
||||
if err != nil { return nil, err }
|
||||
literal := &entity.LiteralArray {
|
||||
|
@ -89,7 +89,7 @@ func (this *parser) parseLiteralArrayCore (pos errors.Position) (*entity.Literal
|
|||
return literal, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseLiteralStructCore (pos errors.Position) (*entity.LiteralStruct, error) {
|
||||
func (this *treeParser) parseLiteralStructCore (pos errors.Position) (*entity.LiteralStruct, error) {
|
||||
err := this.Expect(lexer.Dot)
|
||||
if err != nil { return nil, err }
|
||||
literal := &entity.LiteralStruct {
|
|
@ -1,4 +1,4 @@
|
|||
package parser
|
||||
package fsplParser
|
||||
|
||||
import "strconv"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/lexer"
|
||||
|
@ -7,7 +7,7 @@ import "git.tebibyte.media/sashakoshka/fspl/entity"
|
|||
var descriptionSignature = "signature"
|
||||
var startTokensSignature = []lexer.TokenKind { lexer.LBracket }
|
||||
|
||||
func (this *parser) parseSignature () (*entity.Signature, error) {
|
||||
func (this *treeParser) parseSignature () (*entity.Signature, error) {
|
||||
err := this.ExpectDesc(descriptionSignature, startTokensSignature...)
|
||||
if err != nil { return nil, err }
|
||||
pos := this.Pos()
|
||||
|
@ -43,7 +43,7 @@ func (this *parser) parseSignature () (*entity.Signature, error) {
|
|||
return signature, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseMember () (*entity.Member, error) {
|
||||
func (this *treeParser) parseMember () (*entity.Member, error) {
|
||||
err := this.ExpectDesc("struct member", lexer.Ident)
|
||||
if err != nil { return nil, err }
|
||||
name := this.Value()
|
||||
|
@ -89,3 +89,13 @@ func parseFloat (value string) (float64, error) {
|
|||
if err != nil { return 0, err }
|
||||
return float, nil
|
||||
}
|
||||
|
||||
func prependCopy[ELEMENT any] (item ELEMENT, array []ELEMENT) []ELEMENT {
|
||||
return append([]ELEMENT { item }, array...)
|
||||
}
|
||||
|
||||
func appendCopy[ELEMENT any] (array []ELEMENT, items ...ELEMENT) []ELEMENT {
|
||||
newArray := make([]ELEMENT, len(array) + len(items))
|
||||
copy(newArray[copy(newArray, array):], items)
|
||||
return newArray
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package fsplParser
|
||||
|
||||
import "io"
|
||||
import "fmt"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/lexer"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/parser"
|
||||
|
||||
// parser parses tokens from a lexer into syntax entities, which it places into
|
||||
// a tree.
|
||||
type treeParser struct {
|
||||
parser.Parser
|
||||
tree *Tree
|
||||
}
|
||||
|
||||
// newParser creates a new parser that parses the output of the given lexer.
|
||||
func newParser (lx lexer.Lexer) (*treeParser, error) {
|
||||
return &treeParser {
|
||||
Parser: parser.Parser {
|
||||
Lexer: lx,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// parseInto parses the parser's file into the given syntax tree.
|
||||
func (this *treeParser) parseInto (tree *Tree) error {
|
||||
this.tree = tree
|
||||
err := this.parse()
|
||||
if err == io.EOF { err = nil }
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *treeParser) parse () error {
|
||||
err := this.Next()
|
||||
if err != nil { return err }
|
||||
for this.Token.Kind != lexer.EOF {
|
||||
err = this.parseTopLevel()
|
||||
if err != nil { return err }
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *treeParser) bug () string {
|
||||
return fmt.Sprintln (
|
||||
"Bug detected in the compiler!\n" +
|
||||
"The parser has taken an unexpected control path.",
|
||||
"This could be due to an un-implemented feature.\n" +
|
||||
"Please submit a report with this info and stack trace to:",
|
||||
"https://git.tebibyte.media/sashakoshka/fspl/issues\n" +
|
||||
"The token being parsed was:", this.Token)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package parser
|
||||
package fsplParser
|
||||
|
||||
import "testing"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package parser
|
||||
package fsplParser
|
||||
|
||||
import "io"
|
||||
import "testing"
|
|
@ -1,4 +1,4 @@
|
|||
package parser
|
||||
package fsplParser
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/fspl/lexer"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/errors"
|
||||
|
@ -12,7 +12,7 @@ var startTokensTopLevel = []lexer.TokenKind {
|
|||
lexer.EOF,
|
||||
}
|
||||
|
||||
func (this *parser) parseTopLevel () error {
|
||||
func (this *treeParser) parseTopLevel () error {
|
||||
err := this.ExpectDesc (
|
||||
descriptionTopLevel,
|
||||
startTokensTopLevel...)
|
||||
|
@ -61,12 +61,12 @@ func (this *parser) parseTopLevel () error {
|
|||
typedef, err := this.parseTypedefCore(pos, access, typeName)
|
||||
if err != nil { return err }
|
||||
this.tree.AddDeclaration(typedef)
|
||||
default: this.Bug()
|
||||
default: panic(this.bug())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *parser) parseAccess () (entity.Access, error) {
|
||||
func (this *treeParser) parseAccess () (entity.Access, error) {
|
||||
err := this.ExpectValueDesc (
|
||||
"Access control specifier",
|
||||
lexer.Symbol, "-", "~", "+")
|
||||
|
@ -77,11 +77,11 @@ func (this *parser) parseAccess () (entity.Access, error) {
|
|||
case "-": return entity.AccessPrivate, nil
|
||||
case "~": return entity.AccessRestricted, nil
|
||||
case "+": return entity.AccessPublic, nil
|
||||
default: panic(this.Bug())
|
||||
default: panic(this.bug())
|
||||
}
|
||||
}
|
||||
|
||||
func (this *parser) parseFunctionCore (pos errors.Position, access entity.Access) (*entity.Function, error) {
|
||||
func (this *treeParser) parseFunctionCore (pos errors.Position, access entity.Access) (*entity.Function, error) {
|
||||
signature, err := this.parseSignature()
|
||||
if err != nil { return nil, err }
|
||||
|
||||
|
@ -124,7 +124,7 @@ func (this *parser) parseFunctionCore (pos errors.Position, access entity.Access
|
|||
return function, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseMethodCore (pos errors.Position, access entity.Access, typeName string) (*entity.Method, error) {
|
||||
func (this *treeParser) parseMethodCore (pos errors.Position, access entity.Access, typeName string) (*entity.Method, error) {
|
||||
function, err := this.parseFunctionCore(pos, access)
|
||||
if err != nil { return nil, err }
|
||||
return &entity.Method {
|
||||
|
@ -137,7 +137,7 @@ func (this *parser) parseMethodCore (pos errors.Position, access entity.Access,
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseTypedefCore (pos errors.Position, access entity.Access, typeName string) (*entity.Typedef, error) {
|
||||
func (this *treeParser) parseTypedefCore (pos errors.Position, access entity.Access, typeName string) (*entity.Typedef, error) {
|
||||
pos = pos.Union(this.Pos())
|
||||
ty, err := this.parseType()
|
||||
if err != nil { return nil, err }
|
|
@ -1,4 +1,4 @@
|
|||
package parser
|
||||
package fsplParser
|
||||
|
||||
import "fmt"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/lexer"
|
|
@ -1,4 +1,4 @@
|
|||
package parser
|
||||
package fsplParser
|
||||
|
||||
import "strconv"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/lexer"
|
||||
|
@ -14,7 +14,7 @@ var startTokensType = []lexer.TokenKind {
|
|||
lexer.LParen,
|
||||
}
|
||||
|
||||
func (this *parser) parseType () (entity.Type, error) {
|
||||
func (this *treeParser) parseType () (entity.Type, error) {
|
||||
err := this.ExpectDesc(descriptionType, startTokensType...)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
|
@ -64,12 +64,12 @@ func (this *parser) parseType () (entity.Type, error) {
|
|||
case ".": return this.parseTypeStructCore()
|
||||
case "~": return this.parseTypeInterfaceCore()
|
||||
}
|
||||
panic(this.Bug())
|
||||
panic(this.bug())
|
||||
}
|
||||
panic(this.Bug())
|
||||
panic(this.bug())
|
||||
}
|
||||
|
||||
func (this *parser) parseTypeNamedCore (module string) (entity.Type, error) {
|
||||
func (this *treeParser) parseTypeNamedCore (module string) (entity.Type, error) {
|
||||
err := this.Expect(lexer.TypeIdent)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
|
@ -81,7 +81,7 @@ func (this *parser) parseTypeNamedCore (module string) (entity.Type, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseTypePointerOrSlice () (entity.Type, error) {
|
||||
func (this *treeParser) parseTypePointerOrSlice () (entity.Type, error) {
|
||||
err := this.ExpectDesc("pointer type or slice type", lexer.Star)
|
||||
if err != nil { return nil, err }
|
||||
start := this.Pos()
|
||||
|
@ -109,7 +109,7 @@ func (this *parser) parseTypePointerOrSlice () (entity.Type, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (this *parser) parseTypeArray () (entity.Type, error) {
|
||||
func (this *treeParser) parseTypeArray () (entity.Type, error) {
|
||||
err := this.ExpectDesc("array type", lexer.Int)
|
||||
if err != nil { return nil, err }
|
||||
start := this.Pos()
|
||||
|
@ -130,7 +130,7 @@ func (this *parser) parseTypeArray () (entity.Type, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseTypeStructCore () (entity.Type, error) {
|
||||
func (this *treeParser) parseTypeStructCore () (entity.Type, error) {
|
||||
err := this.Expect(lexer.Dot)
|
||||
if err != nil { return nil, err }
|
||||
ty := &entity.TypeStruct {
|
||||
|
@ -154,7 +154,7 @@ func (this *parser) parseTypeStructCore () (entity.Type, error) {
|
|||
return ty, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseTypeInterfaceCore () (entity.Type, error) {
|
||||
func (this *treeParser) parseTypeInterfaceCore () (entity.Type, error) {
|
||||
err := this.ExpectValue(lexer.Symbol, "~")
|
||||
if err != nil { return nil, err }
|
||||
ty := &entity.TypeInterface {
|
||||
|
@ -178,7 +178,7 @@ func (this *parser) parseTypeInterfaceCore () (entity.Type, error) {
|
|||
return ty, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseTypeInt () (entity.Type, error) {
|
||||
func (this *treeParser) parseTypeInt () (entity.Type, error) {
|
||||
err := this.Expect(lexer.TypeIdent)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
|
@ -196,7 +196,7 @@ func (this *parser) parseTypeInt () (entity.Type, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseTypeWord () (entity.Type, error) {
|
||||
func (this *treeParser) parseTypeWord () (entity.Type, error) {
|
||||
err := this.ExpectValue(lexer.TypeIdent, "Int", "UInt")
|
||||
if err != nil { return nil, err }
|
||||
defer this.Next()
|
||||
|
@ -206,7 +206,7 @@ func (this *parser) parseTypeWord () (entity.Type, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (this *parser) parseTypeFloat () (entity.Type, error) {
|
||||
func (this *treeParser) parseTypeFloat () (entity.Type, error) {
|
||||
err := this.ExpectValue(lexer.TypeIdent, "F16", "F32", "F64", "F128")
|
||||
if err != nil { return nil, err }
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package parser
|
||||
|
||||
import "io"
|
||||
import "fmt"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/lexer"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/errors"
|
||||
|
@ -12,40 +11,6 @@ type Parser struct {
|
|||
Lexer lexer.Lexer
|
||||
}
|
||||
|
||||
// parser parses tokens from a lexer into syntax entities, which it places into
|
||||
// a tree.
|
||||
type parser struct {
|
||||
Parser
|
||||
tree *Tree
|
||||
}
|
||||
|
||||
// newParser creates a new parser that parses the output of the given lexer.
|
||||
func newParser (lx lexer.Lexer) (*parser, error) {
|
||||
return &parser {
|
||||
Parser: Parser {
|
||||
Lexer: lx,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// parseInto parses the parser's file into the given syntax tree.
|
||||
func (this *parser) parseInto (tree *Tree) error {
|
||||
this.tree = tree
|
||||
err := this.parse()
|
||||
if err == io.EOF { err = nil }
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *parser) parse () error {
|
||||
err := this.Next()
|
||||
if err != nil { return err }
|
||||
for this.Token.Kind != lexer.EOF {
|
||||
err = this.parseTopLevel()
|
||||
if err != nil { return err }
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
@ -111,6 +76,7 @@ func (this *Parser) ExpectValueDesc (description string, kind lexer.TokenKind, a
|
|||
return nil
|
||||
}
|
||||
|
||||
// Next consumes a token from the lexer, and sets it as the current token.
|
||||
func (this *Parser) Next () error {
|
||||
token, err := this.Lexer.Next()
|
||||
if err != nil { return err }
|
||||
|
@ -118,16 +84,6 @@ func (this *Parser) Next () error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (this *Parser) Bug () string {
|
||||
return fmt.Sprintln (
|
||||
"Bug detected in the compiler!\n" +
|
||||
"The parser has taken an unexpected control path.",
|
||||
"This could be due to an un-implemented feature.\n" +
|
||||
"Please submit a report with this info and stack trace to:",
|
||||
"https://git.tebibyte.media/sashakoshka/fspl/issues\n" +
|
||||
"The token being parsed was:", this.Token)
|
||||
}
|
||||
|
||||
func (this *Parser) Kind () lexer.TokenKind {
|
||||
return this.Token.Kind
|
||||
}
|
||||
|
@ -171,13 +127,3 @@ func commaList[ELEMENT any] (items ...ELEMENT) string {
|
|||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func prependCopy[ELEMENT any] (item ELEMENT, array []ELEMENT) []ELEMENT {
|
||||
return append([]ELEMENT { item }, array...)
|
||||
}
|
||||
|
||||
func appendCopy[ELEMENT any] (array []ELEMENT, items ...ELEMENT) []ELEMENT {
|
||||
newArray := make([]ELEMENT, len(array) + len(items))
|
||||
copy(newArray[copy(newArray, array):], items)
|
||||
return newArray
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue