124 lines
2.6 KiB
Go
124 lines
2.6 KiB
Go
package lexer
|
|
|
|
import "fmt"
|
|
import "testing"
|
|
import "strings"
|
|
import "github.com/alecthomas/participle/v2"
|
|
import "github.com/alecthomas/participle/v2/lexer"
|
|
|
|
func tok (ty lexer.TokenType, value string) lexer.Token {
|
|
return lexer.Token {
|
|
Type: ty,
|
|
Value: value,
|
|
}
|
|
}
|
|
|
|
func testString (
|
|
test *testing.T,
|
|
input string,
|
|
correct ...lexer.Token,
|
|
) {
|
|
testStringErr(test, "", 0, 0, input, correct...)
|
|
}
|
|
|
|
func testStringErr (
|
|
test *testing.T,
|
|
errMessage string,
|
|
errLine int,
|
|
errColumn int,
|
|
input string,
|
|
correct ...lexer.Token,
|
|
) {
|
|
testError := func (err error) bool {
|
|
got := err.(participle.Error)
|
|
gotMessage := got.Message()
|
|
gotLine := got.Position().Line
|
|
gotColumn := got.Position().Column
|
|
correct :=
|
|
gotMessage == errMessage &&
|
|
gotLine == errLine &&
|
|
gotColumn == errColumn
|
|
if !correct {
|
|
test.Log("errors do not match")
|
|
test.Logf("got:\n%v:%v: %v", gotLine, gotColumn, gotMessage)
|
|
test.Logf("correct:\n%v:%v: %v", errLine, errColumn, errMessage)
|
|
test.Fail()
|
|
}
|
|
return correct
|
|
}
|
|
|
|
reader := strings.NewReader(input)
|
|
lx, err := NewDefinition().Lex("stream0.fspl", reader)
|
|
if err != nil {
|
|
if errMessage == "" {
|
|
test.Error("lexer returned error: ", err)
|
|
return
|
|
} else {
|
|
if !testError(err) { return }
|
|
}
|
|
}
|
|
|
|
var tokens []lexer.Token
|
|
for {
|
|
got, err := lx.Next()
|
|
tokens = append(tokens, got)
|
|
if got.EOF() { break }
|
|
if err != nil {
|
|
if errMessage == "" {
|
|
test.Error("lexer returned error: ", err)
|
|
return
|
|
} else {
|
|
if !testError(err) { return }
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
printColumns := func (left, right string) {
|
|
test.Logf("%-40v | %-40v", left, right)
|
|
}
|
|
|
|
dumpToken := func (token lexer.Token) string {
|
|
return fmt.Sprintf("%4v: \"%s\"", token.Type, token.Value)
|
|
}
|
|
|
|
compareTokens := func () {
|
|
length := len(tokens)
|
|
if len(correct) > length { length = len(correct) }
|
|
|
|
printColumns("CORRECT", "GOT")
|
|
for index := 0; index < length; index ++ {
|
|
left := "..."
|
|
right := "..."
|
|
|
|
if index < len(correct) {
|
|
left = dumpToken(correct[index])
|
|
}
|
|
if index < len(tokens) {
|
|
right = dumpToken(tokens[index])
|
|
}
|
|
|
|
printColumns(left, right)
|
|
}
|
|
}
|
|
|
|
if len(tokens) != len(correct) {
|
|
test.Logf (
|
|
"len(correct) and len(got) do not match (%v, %v)",
|
|
len(correct), len(tokens))
|
|
compareTokens()
|
|
test.Fail()
|
|
return
|
|
}
|
|
|
|
for index, token := range correct {
|
|
gotToken := tokens[index]
|
|
if token.Type != gotToken.Type || token.Value != gotToken.Value {
|
|
test.Logf("correct and got do not match at %v", index)
|
|
compareTokens()
|
|
test.Fail()
|
|
return
|
|
}
|
|
}
|
|
}
|