summaryrefslogtreecommitdiff
path: root/literals.go
diff options
context:
space:
mode:
Diffstat (limited to 'literals.go')
-rw-r--r--literals.go65
1 files changed, 62 insertions, 3 deletions
diff --git a/literals.go b/literals.go
index 241dd93..5dd9fef 100644
--- a/literals.go
+++ b/literals.go
@@ -2,11 +2,12 @@ package goparsify
import (
"bytes"
+ "strconv"
"unicode/utf8"
)
func StringLit(allowedQuotes string) Parser {
- return NewParser("string", func(ps *State) Node {
+ return NewParser("string literal", func(ps *State) Node {
ps.AutoWS()
for i := 0; i < len(allowedQuotes); i++ {
@@ -61,10 +62,10 @@ func StringLit(allowedQuotes string) Parser {
if buf == nil {
result := ps.Input[ps.Pos+1 : end]
ps.Pos = end + 1
- return Node{Token: result}
+ return Node{Result: result}
}
ps.Pos = end + 1
- return Node{Token: buf.String()}
+ return Node{Result: buf.String()}
default:
r, w := utf8.DecodeRuneInString(ps.Input[end:])
end += w
@@ -79,6 +80,64 @@ func StringLit(allowedQuotes string) Parser {
})
}
+func NumberLit() Parser {
+ return NewParser("number literal", func(ps *State) Node {
+ ps.AutoWS()
+ end := ps.Pos
+ float := false
+ inputLen := len(ps.Input)
+
+ if end < inputLen && (ps.Input[end] == '-' || ps.Input[end] == '+') {
+ end++
+ }
+
+ for end < inputLen && ps.Input[end] >= '0' && ps.Input[end] <= '9' {
+ end++
+ }
+
+ if end < inputLen && ps.Input[end] == '.' {
+ float = true
+ end++
+ }
+
+ for end < inputLen && ps.Input[end] >= '0' && ps.Input[end] <= '9' {
+ end++
+ }
+
+ if end < inputLen && (ps.Input[end] == 'e' || ps.Input[end] == 'E') {
+ end++
+ float = true
+
+ if end < inputLen && (ps.Input[end] == '-' || ps.Input[end] == '+') {
+ end++
+ }
+
+ for end < inputLen && ps.Input[end] >= '0' && ps.Input[end] <= '9' {
+ end++
+ }
+ }
+
+ if end == ps.Pos {
+ ps.ErrorHere("number")
+ return Node{}
+ }
+
+ var result interface{}
+ var err error
+ if float {
+ result, err = strconv.ParseFloat(ps.Input[ps.Pos:end], 10)
+ } else {
+ result, err = strconv.ParseInt(ps.Input[ps.Pos:end], 10, 64)
+ }
+ if err != nil {
+ ps.ErrorHere("number")
+ return Node{}
+ }
+ ps.Pos = end
+ return Node{Result: result}
+ })
+}
+
func stringContainsByte(s string, b byte) bool {
for i := 0; i < len(s); i++ {
if b == s[i] {