~mna/fastpeg

ccaaf5e5e5e2660778cbb9390f8cb81a6b245a41 — Martin Angers 8 months ago 3a53f16
internal/ast: start designing ast
A internal/ast/ast.go => internal/ast/ast.go +94 -0
@@ 0,0 1,94 @@
package ast

import (
	"git.sr.ht/~mna/fastpeg/internal/bootstrap/token"
)

type Expression interface{}

// Grammar represents a parsed fastpeg grammar.
type Grammar struct {
	Definitions []*Definition
}

type Definition struct {
	// Ident is the required identifier in a definition, i.e.:
	// identifier <- expression
	Ident *Identifier

	// Arrow indicates the location and type of arrow in the
	// definition.
	Arrow *Punctuation

	// Expr is the expression associated with this definition's
	// identifier.
	Expr Expression

	// EOS is the end-of-statement if present for this
	// definition, nil otherwise.
	EOS *Punctuation
}

type Choice struct {
	// Exprs is the list of options, one expression for each
	// choice.
	Exprs []Expression

	// Seps is the list of choice separators between each option.
	Seps []*Punctuation
}

type Sequence struct {
	// Exprs is the list of expressions in this sequence.
	Exprs []Expression
}

type Coderef struct {
	Pos   token.Pos
	Type  token.Token
	Ident string
}

type Label struct {
	Ident *Identifier
	Colon *Punctuation
	Expr  Expression
}

type Prefix struct {
	Prefix *Punctuation
	Expr   Expression
}

type Suffix struct {
	Suffix *Punctuation
	Expr   Expression
}

type Ruleref struct {
	Ident *Identifier
}

type Literal struct {
}

type CharClass struct {
}

type Any struct {
	Dot *Punctuation
}

type Identifier struct {
	Pos   token.Pos
	Value string
}

type Punctuation struct {
	// Pos is the FileSet-dependent position of the start of
	// this punctuation.
	Pos token.Pos

	// Value is the representation of this punctuation.
	Value string
}

A internal/bootstrap/parser/parser.go => internal/bootstrap/parser/parser.go +43 -0
@@ 0,0 1,43 @@
// Package parser implements a parser for the fastpeg language.
// Input may be provided in a variety of forms, the output is
// an abstract syntax tree (AST) representing the parsed grammar.
// The parser is invoked through one of the Parse* functions.
package parser

import (
	"errors"
	"io/ioutil"

	"git.sr.ht/~mna/fastpeg/internal/ast"
	"git.sr.ht/~mna/fastpeg/internal/bootstrap/token"
)

// ParseFiles parses the content of the provided filenames in a single
// Grammar AST node.
func ParseFiles(filenames ...string) (*ast.Grammar, error) {
	inputs := make(map[string][]byte, len(filenames))
	for _, filename := range filenames {
		b, err := ioutil.ReadFile(filename)
		if err != nil {
			return nil, err
		}
		inputs[filename] = b
	}
	return ParseInputs(inputs)
}

// ParseInputs parses the provided inputs in a single Grammar AST node.
// The key of the map is the corresponding filename used for error
// reporting.
func ParseInputs(inputs map[string][]byte) (*ast.Grammar, error) {
	fs := token.NewFileSet()
	for file, input := range inputs {
		f := fs.AddFile(file, -1, len(input))
		_ = f
		// TODO: parse f...
	}
	return nil, errors.New("not implemented")
}

type parser struct {
}

M internal/bootstrap/scanner/scanner_test.go => internal/bootstrap/scanner/scanner_test.go +3 -0
@@ 334,6 334,7 @@ expression <- factor (_ factor)?
		`factor = "lit"
            | 'lat';`,
		"\ufeff\n\tchars←[\\a-\\r]+",
		`${ ident }`,
	}

	expect := `


@@ 362,6 363,8 @@ test-2:2:7:10: Arrow[←]
test-2:2:10:13: CharClass[[\a-\r]]
test-2:2:17:20: +[]
test-2:2:18:21: EOF[]
test-3:1:1:0: StateCoderef[ident]
test-3:1:11:10: EOF[]
`

	var s Scanner