4 Commits

Author SHA1 Message Date
amery 2ef9315ff2 Unmarshal: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-29 16:38:50 +00:00
amery c1943d4285 Decoder: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-29 16:38:50 +00:00
amery efe48ffcb5 basic: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-29 16:38:50 +00:00
amery 22b372cdb0 parser: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-29 16:38:50 +00:00
5 changed files with 96 additions and 14 deletions
+58
View File
@@ -0,0 +1,58 @@
package parser
import "asciigoat.org/core/lexer"
// Run parses the source
func (p *Parser) Run() error {
p.setDefaults()
p.pos.Reset()
return lexer.Run(p.lexStart)
}
func (p *Parser) lexStart() (lexer.StateFn, error) {
for {
r, _, err := p.src.ReadRune()
switch {
case err != nil:
return p.emitError("", err)
case r == '\n':
// new line
r2, _, err := p.src.ReadRune()
switch {
case err == nil && r2 == '\r':
// MAC new line
case err == nil:
// UNIX new line
p.src.UnreadRune()
}
p.src.Discard()
p.pos.StepLine()
case r == '\r':
// new line
r2, _, err := p.src.ReadRune()
switch {
case err == nil && r2 == '\n':
// DOS new line
case err == nil:
// incomplete CRLN
p.src.UnreadRune()
return p.emitInvalidRune(r2)
}
p.src.Discard()
p.pos.StepLine()
case p.IsSpace(r):
// whitespace
p.src.Discard()
p.pos.Step()
case p.IsCommentStart(r):
// switch to comment lexer
p.src.UnreadRune()
return p.lexComment, nil
}
}
}
func (p *Parser) lexComment() (lexer.StateFn, error)
+19
View File
@@ -0,0 +1,19 @@
package parser
import "asciigoat.org/core/lexer"
func (p *Parser) emitError(content string, err error) (lexer.StateFn, error) {
err2 := p.OnError(p.pos, content, err)
switch {
case err2 != nil:
// return wrapped error
return nil, err2
default:
// return original error
return nil, err
}
}
func (p *Parser) emitInvalidRune(r rune) (lexer.StateFn, error) {
return p.emitError(string([]rune{r}), lexer.ErrUnacceptableRune)
}
+17
View File
@@ -0,0 +1,17 @@
package parser
import "unicode"
func (*Parser) IsSpace(r rune) bool {
return unicode.IsSpace(r)
}
func (*Parser) IsCommentStart(r rune) bool {
// TODO: use Parser options
switch r {
case ';', '#':
return true
default:
return false
}
}
+2 -7
View File
@@ -11,6 +11,8 @@ import (
type Parser struct { type Parser struct {
src *lexer.Reader src *lexer.Reader
pos lexer.Position
OnSection func(pos lexer.Position, name, subname string, hasSubname bool) error OnSection func(pos lexer.Position, name, subname string, hasSubname bool) error
OnField func(pos lexer.Position, key, value string) error OnField func(pos lexer.Position, key, value string) error
OnComment func(pos lexer.Position, comment string) error OnComment func(pos lexer.Position, comment string) error
@@ -48,13 +50,6 @@ func (p *Parser) setDefaults() {
} }
} }
// Run parses the source
func (p *Parser) Run() error {
p.setDefaults()
return lexer.Run(p.initialState)
}
// NewParser creates a dosini-style parser using // NewParser creates a dosini-style parser using
// an [io.Reader] as source // an [io.Reader] as source
func NewParser(r io.Reader) *Parser { func NewParser(r io.Reader) *Parser {
-7
View File
@@ -1,7 +0,0 @@
package parser
import "asciigoat.org/core/lexer"
func (*Parser) initialState() (lexer.StateFn, error) {
return nil, nil
}