fspl/parser/tree.go

108 lines
2.8 KiB
Go

package parser
import "io"
import "os"
import "fmt"
import "github.com/alecthomas/participle/v2"
import "git.tebibyte.media/sashakoshka/fspl/entity"
import flexer "git.tebibyte.media/sashakoshka/fspl/lexer"
var parser = participle.MustBuild[Tree] (
participle.Union[entity.TopLevel] (
new(entity.Function),
new(entity.Typedef),
new(entity.Method)),
participle.Union[entity.Type] (
new(entity.TypeNamed),
new(entity.TypePointer),
new(entity.TypeInterface),
new(entity.TypeStruct),
new(entity.TypeArray),
new(entity.TypeSlice)),
participle.Union[entity.Expression] (
new(entity.LiteralInt),
new(entity.LiteralFloat),
new(entity.LiteralString),
new(entity.LiteralArray),
new(entity.LiteralStruct),
new(entity.LiteralBoolean),
new(entity.LiteralNil),
new(entity.Break),
new(entity.Return),
new(entity.IfElse),
new(entity.Loop),
new(entity.MethodCall),
new(entity.MemberAccess),
new(entity.Declaration),
new(entity.Subscript),
new(entity.Slice),
new(entity.Length),
new(entity.Dereference),
new(entity.Reference),
new(entity.ValueCast),
new(entity.BitCast),
new(entity.Operation),
new(entity.Call),
new(entity.Variable),
new(entity.Block)),
participle.Union[entity.Statement] (
new(entity.LiteralInt),
new(entity.LiteralFloat),
new(entity.LiteralArray),
new(entity.LiteralStruct),
new(entity.LiteralBoolean),
new(entity.LiteralNil),
new(entity.Break),
new(entity.Return),
new(entity.Assignment),
new(entity.IfElse),
new(entity.Loop),
new(entity.MethodCall),
new(entity.MemberAccess),
new(entity.Declaration),
new(entity.Subscript),
new(entity.Slice),
new(entity.Length),
new(entity.Dereference),
new(entity.Reference),
new(entity.ValueCast),
new(entity.BitCast),
new(entity.Operation),
new(entity.Call),
new(entity.Variable),
new(entity.Block)),
participle.UseLookahead(participle.MaxLookahead),
participle.Lexer(flexer.NewDefinition()))
// Tree represents a parsed abstract syntax tree. It has no constructor and its
// zero value can be used safely.
type Tree struct {
Declarations []entity.TopLevel `parser:" @@* "`
}
func (this *Tree) String () string {
out := ""
for index, declaration := range this.Declarations {
if index > 0 { out += "\n" }
out += fmt.Sprint(declaration)
}
return out
}
// Parse parses the contents of the given io.Reader into the tree.
func (this *Tree) Parse (name string, file io.Reader) error {
parsed, err := parser.Parse(name, file)
if parsed != nil {
this.Declarations = append(this.Declarations, parsed.Declarations...)
}
return err
}
// ParseFile parses the contents of the given file into the tree.
func (this *Tree) ParseFile (name string) error {
file, err := os.Open(name)
if err != nil { return err }
defer file.Close()
return this.Parse(name, file)
}