flexer_test.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package flexer
  2. import "testing"
  3. const (
  4. tWord = Kind(-1 - iota)
  5. tArrow
  6. tSpace
  7. tString
  8. tPlus = Kind('+')
  9. tEos = Kind('.')
  10. )
  11. func TestFlexer(t *testing.T) {
  12. pos := Position{}
  13. expected := []Token{
  14. MakeToken(pos, tSpace, "\t "),
  15. MakeToken(pos, tWord, "PROGRAM"),
  16. MakeToken(pos, tSpace, " "),
  17. MakeToken(pos, tArrow, "->"),
  18. MakeToken(pos, tSpace, " "),
  19. MakeToken(pos, tWord, "STATEMENT"),
  20. MakeToken(pos, tPlus, "+"),
  21. MakeToken(pos, tSpace, " "),
  22. MakeToken(pos, tEos, ".\n"),
  23. MakeToken(pos, tWord, "say"),
  24. MakeToken(pos, tSpace, " "),
  25. MakeToken(pos, tString, "hello\nworld"),
  26. MakeToken(pos, tEos, "."),
  27. }
  28. f := NewFlexer(`test`, "\t PROGRAM -> STATEMENT+ .\nsay \"hello\\nworld\".")
  29. f.Rule(tSpace, `[ \t]+`, "", nil)
  30. f.Rule(tWord, `[A-Za-z_]+`, "", nil)
  31. f.Rule(tArrow, `\->`, "", nil)
  32. f.Rule(tPlus, `\+`, "", nil)
  33. f.Rule(tEos, `\.[\n\r]*`, "", nil)
  34. f.Rule(SkipKind, `"`, "", ContextAction("string"))
  35. f.Rule(tString, `"`, "string", PopAction(tString))
  36. f.Rule(SkipKind, `\\[etnru][0-9a-f]*`, "string", EscapeAction('"'))
  37. f.Rule(SkipKind, `.`, "string", StoreAction())
  38. toks := LexAll(f)
  39. for i, e := range expected {
  40. tok := toks[i]
  41. t.Logf("toks: %d, %v", i, tok)
  42. ko := tok.Kind()
  43. ke := e.Kind()
  44. if ko != ke {
  45. t.Errorf("error: kind:%d|%d|", ko, ke)
  46. }
  47. to := tok.Text()
  48. te := e.Text()
  49. if to != te {
  50. t.Errorf("error: text:%s|%s|", to, te)
  51. }
  52. }
  53. if !f.EOF() {
  54. t.Errorf("error: should be EOF")
  55. }
  56. }