begin with parser implementation

Этот коммит содержится в:
gedi 2015-06-07 11:18:46 +03:00
родитель 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 {
t = l.peek
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 {

Просмотреть файл

@ -1,16 +1,22 @@
package gherkin
import (
"errors"
"io"
"strings"
"github.com/l3pp4rd/behat/gherkin/lexer"
)
type Tag string
type Scenario struct {
Steps []*Step
Tags []Tag
Line string
}
type Background struct {
Steps []*Step
Line string
}
type StepType string
@ -22,7 +28,6 @@ const (
)
type Step struct {
Line string
Text string
Type StepType
}
@ -30,17 +35,74 @@ type Step struct {
type Feature struct {
Tags []Tag
Description string
Line string
Title string
Filename string
Background *Background
Scenarios []*Scenario
}
// func Parse(r io.Reader) (*Feature, error) {
// in := bufio.NewReader(r)
// for line, err := in.ReadString(byte('\n')); err != nil; line, err = in.ReadString(byte('\n')) {
// ln := strings.TrimFunc(string(line), unicode.IsSpace)
// }
// return nil, nil
// }
var ErrNotFeature = errors.New("expected a file to begin with a feature definition")
var ErrEmpty = errors.New("the feature file is empty")
var ErrTagsNextToFeature = errors.New("tags must be a single line next to a feature definition")
var ErrSingleBackground = errors.New("there can only be a single background section")
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
}