Skip to content

Starting on a parser #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions parse.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package jsonast

import (
"github.com/go-functional/jsonast/parse"
)

type state struct {
inObj bool
inArr bool
Expand All @@ -12,10 +16,10 @@ func newState() state {
return state{}
}

func (s state) addToken(tkn token) error {
func (s state) addToken(tkn parse.Token) error {
// char := tkn.char
switch tkn {
case quoteToken:
case parse.QuoteToken():
if !s.inStr {
// start a new string
} else {
Expand All @@ -33,8 +37,8 @@ func (s state) value() Value {
// Parse parses jsonStr from JSON to a Value. Returns nil and an appropriate
// error if jsonStr was an invalid JSON string
func Parse(jsonStr string) (Value, error) {
tokensCh := make(chan token)
go tokenize(jsonStr, tokensCh)
tokensCh := make(chan parse.Token)
go parse.Tokenize(jsonStr, tokensCh)
st := newState()
for token := range tokensCh {
if err := st.addToken(token); err != nil {
Expand Down
33 changes: 33 additions & 0 deletions parse/pattern.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package parse

// Pattern is the interface to match a token or tokens
type Pattern interface {
IsValid(tkn Token) bool
IsOpen() bool
}

type singleTokenPattern struct {
expected Token
found bool
}

func (s singleTokenPattern) IsValid(tkn Token) bool {
return tkn == s.expected
}

func (s singleTokenPattern) IsOpen() bool {
return !s.found
}

type zeroOrMoreIdenticalTokensPattern struct {
expected Token
}

func (z zeroOrMoreIdenticalTokensPattern) IsValid(tkn Token) bool {
return tkn == z.expected
}

func (z zeroOrMoreIdenticalTokensPattern) IsOpen() bool {
return true
}

33 changes: 33 additions & 0 deletions parse/string_pattern.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package parse

type StringPattern struct {
openQuote bool
closeQuote bool
str string
}

func (s *StringPattern) IsValid(tkn Token) bool {
if !s.openQuote && tkn == QuoteToken() {
// no open quote yet and we found one means string start
s.openQuote = true
s.str += tkn.Char
return true
}
if !s.openQuote && tkn != QuoteToken() {
// no open quote yet and we didn't see one means invalid string
return false
}
if s.openQuote && tkn == QuoteToken() {
// open quote found and we see another means closed quote
s.closeQuote = true
s.str += tkn.Char
return true
}
s.str += tkn.Char
return true
}

func (s *StringPattern) IsOpen() bool {
// pattern is still open if we haven't found the close quote yet
return !s.closeQuote
}
65 changes: 65 additions & 0 deletions parse/token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package parse

// Token represents a single token in the parser
type Token struct {
Char string
}

func (t Token) IsDigit() bool {
r := t.Char
return r == "0" ||
r == "1" ||
r == "2" ||
r == "3" ||
r == "4" ||
r == "5" ||
r == "6" ||
r == "7" ||
r == "8" ||
r == "9"
}

func CommaToken() Token {
return Token{Char: `,`}
}
func QuoteToken() Token {
return Token{Char: `"`}
}

func ArrayStartToken() Token {
return Token{Char: `[`}
}

func ArrayEndToken() Token {
return Token{Char: `]`}
}

func ObjectStartToken() Token {
return Token{Char: `{`}
}
func ObjectEndToken() Token {
return Token{Char: `}`}
}

func Tokenize(str string, ch chan<- Token) {
for _, char := range str {
var tkn Token
if char == ',' {
tkn = CommaToken()
} else if char == '"' {
tkn = QuoteToken()
} else if char == '[' {
tkn = ArrayStartToken()
} else if char == ']' {
tkn = ArrayEndToken()
} else if char == '{' {
tkn = ObjectStartToken()
} else if char == '}' {
tkn = ObjectEndToken()
} else {
tkn = Token{Char: string(char)}
}
ch <- tkn
}
close(ch)
}
14 changes: 14 additions & 0 deletions string.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,17 @@ func newString(str string) String {
str: str,
}
}

func appendStringToValue(v Value, s string) (Value, error) {
switch x := v.(type) {
case stringImpl:
x.str += s
return x, nil
default:
return nil, fmt.Errorf("trying to append a string to a %#v", v)
}
}

// func stringParser() (parsePattern, bool) {
// return newParsePattern(quoteToken, zeroOrMore(charToken), quoteToken)
// }
49 changes: 0 additions & 49 deletions token.go

This file was deleted.