Browse Source

Reverted last change.

master
J. David Lee 4 years ago
parent
commit
6f03aa6efa
2 changed files with 31 additions and 25 deletions
  1. +19
    -14
      parser.go
  2. +12
    -11
      parser_test.go

+ 19
- 14
parser.go View File

@ -24,12 +24,14 @@ const (
type Node struct {
Type string // One of List, Ident, Int, Float, Rune, String
Ident string // If type is Ident.
Bool bool // If Type is Bool.
List []Node // If Type is List.
Int int64 // If Type is Int.
Float float64 // If Type is Float.
Rune rune // If Type is Rune.
String string // If Type is Ident or String.
String string // If Type is String.
List []Node // If Type is List.
Paren rune // If Type is List. One of '(', '[', '{'.
}
// Parse takes an input string and returns a tree rooted on a given token.
@ -62,24 +64,24 @@ func Parse(input string) (Node, error) {
"Expected top-level list, but got `%s.`",
s.TokenText())
}
return parseList(s)
return parseList(s, '(')
}
func parseNode(s *scanner.Scanner) (Node, error) {
func parseNode(s *scanner.Scanner, closeParen rune) (Node, error) {
ch := s.Scan()
switch ch {
case scanner.Ident:
text := s.TokenText()
if text == "true" || text == "false" {
return Node{
Type: Ident,
Type: Bool,
Bool: text == "true",
}, nil
}
return Node{
Type: Ident,
String: s.TokenText(),
Type: Ident,
Ident: s.TokenText(),
}, nil
case scanner.Int:
@ -109,10 +111,10 @@ func parseNode(s *scanner.Scanner) (Node, error) {
String: val[1 : len(val)-1],
}, nil
case '(':
return parseList(s)
case '(', '[', '{':
return parseList(s, ch)
case ')':
case closeParen:
return Node{}, errCloseParen
case scanner.EOF:
@ -123,18 +125,21 @@ func parseNode(s *scanner.Scanner) (Node, error) {
}
}
func parseList(s *scanner.Scanner) (Node, error) {
func parseList(s *scanner.Scanner, paren rune) (Node, error) {
closeParen := map[rune]rune{'(': ')', '[': ']', '{': '}'}[paren]
nodes := []Node{}
for {
n, err := parseNode(s)
n, err := parseNode(s, closeParen)
switch err {
case nil:
nodes = append(nodes, n)
case errCloseParen:
return Node{
Type: List,
List: nodes,
Type: List,
List: nodes,
Paren: paren,
}, nil
case io.EOF:


+ 12
- 11
parser_test.go View File

@ -14,23 +14,24 @@ var TestCases = []TestCase{
{
in: `
(
(main (1 "abc" 'a' '世'))
(sub (2 ><xyz 6.0)))
(main {1 "abc" 'a' '世'})
[sub (2 ><xyz 6.0) true])
`,
out: Node{Type: List, List: []Node{
{Type: List, List: []Node{
{Type: Ident, String: "main"},
{Type: List, List: []Node{
out: Node{Type: List, Paren: '(', List: []Node{
{Type: List, Paren: '(', List: []Node{
{Type: Ident, Ident: "main"},
{Type: List, Paren: '{', List: []Node{
{Type: Int, Int: 1},
{Type: String, String: "abc"},
{Type: Rune, Rune: 'a'},
{Type: Rune, Rune: '世'}}}}},
{Type: List, List: []Node{
{Type: Ident, String: "sub"},
{Type: List, List: []Node{
{Type: List, Paren: '[', List: []Node{
{Type: Ident, Ident: "sub"},
{Type: List, Paren: '(', List: []Node{
{Type: Int, Int: 2},
{Type: Ident, String: "><xyz"},
{Type: Float, Float: 6.0}}}}}}},
{Type: Ident, Ident: "><xyz"},
{Type: Float, Float: 6.0}}},
{Type: Bool, Bool: true}}}}},
},
}


Loading…
Cancel
Save