begin with parser implementation
Этот коммит содержится в:
родитель
832c0999d0
коммит
e7ae301947
2 изменённых файлов: 84 добавлений и 15 удалений
|
@ -19,13 +19,20 @@ func New(r io.Reader) *Lexer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Lexer) Next() (t *Token) {
|
func (l *Lexer) Next(skip ...TokenType) (t *Token) {
|
||||||
if l.peek != nil {
|
if l.peek != nil {
|
||||||
t = l.peek
|
t = l.peek
|
||||||
l.peek = nil
|
l.peek = nil
|
||||||
return
|
} else {
|
||||||
|
t = l.read()
|
||||||
}
|
}
|
||||||
return l.read()
|
|
||||||
|
for _, typ := range skip {
|
||||||
|
if t.Type == typ {
|
||||||
|
return l.Next(skip...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Lexer) Peek() *Token {
|
func (l *Lexer) Peek() *Token {
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
package gherkin
|
package gherkin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/l3pp4rd/behat/gherkin/lexer"
|
||||||
|
)
|
||||||
|
|
||||||
type Tag string
|
type Tag string
|
||||||
|
|
||||||
type Scenario struct {
|
type Scenario struct {
|
||||||
Steps []*Step
|
Steps []*Step
|
||||||
Tags []Tag
|
Tags []Tag
|
||||||
Line string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Background struct {
|
type Background struct {
|
||||||
Steps []*Step
|
Steps []*Step
|
||||||
Line string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type StepType string
|
type StepType string
|
||||||
|
@ -22,7 +28,6 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Step struct {
|
type Step struct {
|
||||||
Line string
|
|
||||||
Text string
|
Text string
|
||||||
Type StepType
|
Type StepType
|
||||||
}
|
}
|
||||||
|
@ -30,17 +35,74 @@ type Step struct {
|
||||||
type Feature struct {
|
type Feature struct {
|
||||||
Tags []Tag
|
Tags []Tag
|
||||||
Description string
|
Description string
|
||||||
Line string
|
|
||||||
Title string
|
Title string
|
||||||
Filename string
|
|
||||||
Background *Background
|
Background *Background
|
||||||
Scenarios []*Scenario
|
Scenarios []*Scenario
|
||||||
}
|
}
|
||||||
|
|
||||||
// func Parse(r io.Reader) (*Feature, error) {
|
var ErrNotFeature = errors.New("expected a file to begin with a feature definition")
|
||||||
// in := bufio.NewReader(r)
|
var ErrEmpty = errors.New("the feature file is empty")
|
||||||
// for line, err := in.ReadString(byte('\n')); err != nil; line, err = in.ReadString(byte('\n')) {
|
var ErrTagsNextToFeature = errors.New("tags must be a single line next to a feature definition")
|
||||||
// ln := strings.TrimFunc(string(line), unicode.IsSpace)
|
var ErrSingleBackground = errors.New("there can only be a single background section")
|
||||||
// }
|
|
||||||
// return nil, nil
|
type parser struct {
|
||||||
// }
|
lx *lexer.Lexer
|
||||||
|
}
|
||||||
|
|
||||||
|
func Parse(r io.Reader) (*Feature, error) {
|
||||||
|
return (parser{lx: lexer.New(r)}).parseFeature()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p parser) parseFeature() (*Feature, error) {
|
||||||
|
var tok *lexer.Token = p.lx.Next(lexer.COMMENT, lexer.NEW_LINE)
|
||||||
|
if tok.Type == lexer.EOF {
|
||||||
|
return nil, ErrEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
ft := &Feature{}
|
||||||
|
if tok.Type == lexer.TAGS {
|
||||||
|
if p.lx.Peek().Type != lexer.FEATURE {
|
||||||
|
return ft, ErrTagsNextToFeature
|
||||||
|
}
|
||||||
|
ft.Tags = p.parseTags(tok.Value)
|
||||||
|
tok = p.lx.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
if tok.Type != lexer.FEATURE {
|
||||||
|
return ft, ErrNotFeature
|
||||||
|
}
|
||||||
|
|
||||||
|
ft.Title = tok.Value
|
||||||
|
var desc []string
|
||||||
|
for ; p.lx.Peek().Type == lexer.TEXT; tok = p.lx.Next() {
|
||||||
|
desc = append(desc, tok.Value)
|
||||||
|
}
|
||||||
|
ft.Description = strings.Join(desc, "\n")
|
||||||
|
|
||||||
|
tok = p.lx.Next(lexer.COMMENT, lexer.NEW_LINE)
|
||||||
|
for ; tok.Type != lexer.EOF; p.lx.Next(lexer.COMMENT, lexer.NEW_LINE) {
|
||||||
|
if tok.Type == lexer.BACKGROUND {
|
||||||
|
if ft.Background != nil {
|
||||||
|
return ft, ErrSingleBackground
|
||||||
|
}
|
||||||
|
ft.Background = p.parseBackground()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ft, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p parser) parseBackground() *Background {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p parser) parseTags(s string) (tags []Tag) {
|
||||||
|
for _, tag := range strings.Split(s, " ") {
|
||||||
|
t := strings.Trim(tag, "@ ")
|
||||||
|
if len(t) > 0 {
|
||||||
|
tags = append(tags, Tag(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче