ccaaf5e5e5e2660778cbb9390f8cb81a6b245a41 — Martin Angers 5 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 @@ `factor = "lit"
              | 'lat';`,
  		"\ufeff\n\tchars←[\\a-\\r]+",
+ 		`${ ident }`,
  	}
  
  	expect := `


@@ 362,6 363,8 @@ 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