way better lex function
This commit is contained in:
parent
6f7adc0789
commit
65cecb3647
7 changed files with 60 additions and 37 deletions
Binary file not shown.
|
|
@ -9,6 +9,6 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
PrintSExpression(Lex(scanner.Text()))
|
shsh.PrintSExpression(shsh.Lex(scanner.Text()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func FmtToken(arg *Token) string {
|
func FmtToken(arg *Token) string {
|
||||||
suffix := ""
|
suffix := "->"
|
||||||
if arg.next != nil {
|
if arg.next == nil {
|
||||||
suffix = "->"
|
suffix = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg.tag {
|
switch arg.tag {
|
||||||
|
|
@ -37,6 +37,10 @@ func GetTagAsStr(tag token_t) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrintSExpression(arg *Token) {
|
func PrintSExpression(arg *Token) {
|
||||||
|
if arg == nil {
|
||||||
|
return //TODO: Handle error here?
|
||||||
|
}
|
||||||
|
|
||||||
var lists TokenStack;
|
var lists TokenStack;
|
||||||
lists.Push(arg)
|
lists.Push(arg)
|
||||||
|
|
||||||
|
|
@ -47,10 +51,20 @@ loop:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for iter := i; iter != nil; iter = i.next {
|
for iter := i; iter != nil; iter = iter.next {
|
||||||
|
if iter.tag == LIST {
|
||||||
|
lists.Push(iter._inner.(*Token))
|
||||||
|
constructor.WriteString(FmtToken(&Token{
|
||||||
|
next: iter.next,
|
||||||
|
tag: STRING,
|
||||||
|
position: iter.position,
|
||||||
|
_inner: "[LIST]"}))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
constructor.WriteString(FmtToken(iter))
|
constructor.WriteString(FmtToken(iter))
|
||||||
}
|
}
|
||||||
|
|
||||||
print(constructor.String())
|
println(constructor.String())
|
||||||
goto loop
|
goto loop
|
||||||
}
|
}
|
||||||
|
|
@ -21,15 +21,44 @@ type Token struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Lex(input string) *Token {
|
func Lex(input string) *Token {
|
||||||
ret := new(Token)
|
if len(input) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret *Token
|
||||||
iter := &ret
|
iter := &ret
|
||||||
delim := ' '
|
delim := ' '
|
||||||
var tok strings.Builder
|
var tok strings.Builder
|
||||||
iter_alloced := false
|
|
||||||
is_list := false
|
is_list := false
|
||||||
is_str := false
|
is_str := false
|
||||||
is_num := true
|
is_num := true
|
||||||
|
|
||||||
|
tokenBuilder := func (pos int, tok string) {
|
||||||
|
*iter = new(Token)
|
||||||
|
(*iter).position = pos
|
||||||
|
|
||||||
|
if is_list {
|
||||||
|
(*iter)._inner = Lex(tok)
|
||||||
|
(*iter).tag = LIST
|
||||||
|
is_list = false
|
||||||
|
|
||||||
|
} else {
|
||||||
|
(*iter)._inner = tok
|
||||||
|
if is_str {
|
||||||
|
(*iter).tag = STRING
|
||||||
|
is_str = false
|
||||||
|
|
||||||
|
} else if is_num {
|
||||||
|
(*iter).tag = NUMBER
|
||||||
|
|
||||||
|
} else {
|
||||||
|
(*iter).tag = SYMBOL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = &(*iter).next
|
||||||
|
}
|
||||||
|
|
||||||
for pos, char := range input {
|
for pos, char := range input {
|
||||||
switch char {
|
switch char {
|
||||||
// TODO: User configurable delimiters
|
// TODO: User configurable delimiters
|
||||||
|
|
@ -41,43 +70,23 @@ func Lex(input string) *Token {
|
||||||
delim = ')'
|
delim = ')'
|
||||||
|
|
||||||
case delim:
|
case delim:
|
||||||
*iter = new(Token)
|
delim = ' '
|
||||||
(*iter).position = pos
|
if tok.Len() == 0 {
|
||||||
|
continue
|
||||||
if is_list {
|
|
||||||
(*iter)._inner = Lex(tok.String())
|
|
||||||
is_list = false
|
|
||||||
(*iter)._inner = LIST
|
|
||||||
|
|
||||||
} else {
|
|
||||||
(*iter)._inner = tok.String()
|
|
||||||
if is_str {
|
|
||||||
(*iter).tag = STRING
|
|
||||||
is_str = false
|
|
||||||
|
|
||||||
} else if is_num {
|
|
||||||
(*iter).tag = NUMBER
|
|
||||||
|
|
||||||
} else {
|
|
||||||
(*iter).tag = SYMBOL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iter_alloced = true
|
tokenBuilder(pos, tok.String())
|
||||||
delim = ' '
|
tok.Reset()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
is_num = is_num && unicode.IsDigit(char)
|
is_num = is_num && unicode.IsDigit(char)
|
||||||
tok.WriteRune(char)
|
tok.WriteRune(char)
|
||||||
}
|
}
|
||||||
|
|
||||||
if iter_alloced {
|
|
||||||
iter = &((*iter).next)
|
|
||||||
iter_alloced = false
|
|
||||||
tok.Reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Throw parsing error here if there is leftover in tok
|
if tok.Len() > 0 {
|
||||||
|
tokenBuilder(len(input), tok.String())
|
||||||
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue