parser_main_test.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. package parser
  10. import (
  11. "fmt"
  12. "testing"
  13. )
  14. func TestStatementParsing(t *testing.T) {
  15. // Comment parsing without statements
  16. input := `a := 1
  17. b := 2; c:= 3`
  18. expectedOutput := `
  19. statements
  20. :=
  21. identifier: a
  22. number: 1
  23. :=
  24. identifier: b
  25. number: 2
  26. :=
  27. identifier: c
  28. number: 3
  29. `[1:]
  30. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  31. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  32. return
  33. }
  34. }
  35. func TestCommentParsing(t *testing.T) {
  36. // Comment parsing without statements
  37. input := `/* This is a comment*/ a := 1 + 1 # foo bar`
  38. expectedOutput := `
  39. :=
  40. identifier: a # This is a comment
  41. plus
  42. number: 1
  43. number: 1 # foo bar
  44. `[1:]
  45. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  46. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  47. return
  48. }
  49. input = `/* foo */ 1 # foo bar`
  50. expectedOutput = `
  51. number: 1 # foo foo bar
  52. `[1:]
  53. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  54. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  55. return
  56. }
  57. }
  58. func TestSimpleExpressionParsing(t *testing.T) {
  59. // Test error output
  60. input := `"bl\*a"conversion`
  61. if _, err := UnitTestParse("mytest", input); err.Error() !=
  62. "Parse error in mytest: Lexical error (invalid syntax while parsing string) (Line:1 Pos:1)" {
  63. t.Error(err)
  64. return
  65. }
  66. // Test incomplete expression
  67. input = `a *`
  68. if _, err := UnitTestParse("mytest", input); err.Error() !=
  69. "Parse error in mytest: Unexpected end" {
  70. t.Error(err)
  71. return
  72. }
  73. input = `not ==`
  74. if _, err := UnitTestParse("mytest", input); err.Error() !=
  75. "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:5)" {
  76. t.Error(err)
  77. return
  78. }
  79. input = `(==)`
  80. if _, err := UnitTestParse("mytest", input); err.Error() !=
  81. "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:2)" {
  82. t.Error(err)
  83. return
  84. }
  85. input = "5 ( 5"
  86. if _, err := UnitTestParse("mytest", input); err.Error() !=
  87. "Parse error in mytest: Term can only start an expression (() (Line:1 Pos:3)" {
  88. t.Error(err)
  89. return
  90. }
  91. input = "5 + \""
  92. if _, err := UnitTestParse("mytest", input); err.Error() !=
  93. "Parse error in mytest: Lexical error (Unexpected end while reading string value (unclosed quotes)) (Line:1 Pos:5)" {
  94. t.Error(err)
  95. return
  96. }
  97. // Test prefix operator
  98. input = ` + a - -5`
  99. expectedOutput := `
  100. minus
  101. plus
  102. identifier: a
  103. minus
  104. number: 5
  105. `[1:]
  106. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  107. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  108. return
  109. }
  110. }
  111. func TestArithmeticParsing(t *testing.T) {
  112. input := "a + b * 5 /2"
  113. expectedOutput := `
  114. plus
  115. identifier: a
  116. div
  117. times
  118. identifier: b
  119. number: 5
  120. number: 2
  121. `[1:]
  122. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  123. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  124. return
  125. }
  126. // Test brackets
  127. input = "a + 1 * (5 + 6)"
  128. expectedOutput = `
  129. plus
  130. identifier: a
  131. times
  132. number: 1
  133. plus
  134. number: 5
  135. number: 6
  136. `[1:]
  137. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  138. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  139. return
  140. }
  141. // Test needless brackets
  142. input = "(a + 1) * (5 / (6 - 2))"
  143. expectedOutput = `
  144. times
  145. plus
  146. identifier: a
  147. number: 1
  148. div
  149. number: 5
  150. minus
  151. number: 6
  152. number: 2
  153. `[1:]
  154. // Pretty printer should get rid of the needless brackets
  155. res, err := UnitTestParseWithPPResult("mytest", input, "(a + 1) * 5 / (6 - 2)")
  156. if err != nil || fmt.Sprint(res) != expectedOutput {
  157. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  158. return
  159. }
  160. }
  161. func TestLogicParsing(t *testing.T) {
  162. input := "not (a + 1) * 5 and tRue == false or not 1 - 5 != test"
  163. expectedOutput := `
  164. or
  165. and
  166. not
  167. times
  168. plus
  169. identifier: a
  170. number: 1
  171. number: 5
  172. ==
  173. true
  174. false
  175. not
  176. !=
  177. minus
  178. number: 1
  179. number: 5
  180. identifier: test
  181. `[1:]
  182. res, err := UnitTestParseWithPPResult("mytest", input, "not (a + 1) * 5 and true == false or not 1 - 5 != test")
  183. if err != nil || fmt.Sprint(res) != expectedOutput {
  184. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  185. return
  186. }
  187. input = "a > b or a <= p or b hasSuffix 'test' or c hasPrefix 'test' and x < 4 or x >= 10"
  188. expectedOutput = `
  189. or
  190. or
  191. or
  192. or
  193. >
  194. identifier: a
  195. identifier: b
  196. <=
  197. identifier: a
  198. identifier: p
  199. hassuffix
  200. identifier: b
  201. string: 'test'
  202. and
  203. hasprefix
  204. identifier: c
  205. string: 'test'
  206. <
  207. identifier: x
  208. number: 4
  209. >=
  210. identifier: x
  211. number: 10
  212. `[1:]
  213. res, err = UnitTestParseWithPPResult("mytest", input, `a > b or a <= p or b hassuffix "test" or c hasprefix "test" and x < 4 or x >= 10`)
  214. if err != nil || fmt.Sprint(res) != expectedOutput {
  215. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  216. return
  217. }
  218. input = "(a in null or c notin d) and false like 9 or x // 6 > 2 % 1"
  219. expectedOutput = `
  220. or
  221. and
  222. or
  223. in
  224. identifier: a
  225. null
  226. notin
  227. identifier: c
  228. identifier: d
  229. like
  230. false
  231. number: 9
  232. >
  233. divint
  234. identifier: x
  235. number: 6
  236. modint
  237. number: 2
  238. number: 1
  239. `[1:]
  240. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  241. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  242. return
  243. }
  244. }