parser_exp_test.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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 TestSimpleExpressionParsing(t *testing.T) {
  15. // Test error output
  16. input := `"bl\*a"conversion`
  17. if _, err := UnitTestParse("mytest", input); err.Error() !=
  18. "Parse error in mytest: Lexical error (invalid syntax while parsing string) (Line:1 Pos:1)" {
  19. t.Error(err)
  20. return
  21. }
  22. // Test incomplete expression
  23. input = `a *`
  24. if _, err := UnitTestParse("mytest", input); err.Error() !=
  25. "Parse error in mytest: Unexpected end" {
  26. t.Error(err)
  27. return
  28. }
  29. input = `not ==`
  30. if _, err := UnitTestParse("mytest", input); err.Error() !=
  31. "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:5)" {
  32. t.Error(err)
  33. return
  34. }
  35. input = `(==)`
  36. if _, err := UnitTestParse("mytest", input); err.Error() !=
  37. "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:2)" {
  38. t.Error(err)
  39. return
  40. }
  41. input = "5 ( 5"
  42. if _, err := UnitTestParse("mytest", input); err.Error() !=
  43. "Parse error in mytest: Term can only start an expression (() (Line:1 Pos:3)" {
  44. t.Error(err)
  45. return
  46. }
  47. input = "5 + \""
  48. if _, err := UnitTestParse("mytest", input); err.Error() !=
  49. "Parse error in mytest: Lexical error (Unexpected end while reading string value (unclosed quotes)) (Line:1 Pos:5)" {
  50. t.Error(err)
  51. return
  52. }
  53. // Test prefix operator
  54. input = ` + a - -5`
  55. expectedOutput := `
  56. minus
  57. plus
  58. identifier: a
  59. minus
  60. number: 5
  61. `[1:]
  62. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  63. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  64. return
  65. }
  66. }
  67. func TestArithmeticParsing(t *testing.T) {
  68. input := "a + b * 5 /2"
  69. expectedOutput := `
  70. plus
  71. identifier: a
  72. div
  73. times
  74. identifier: b
  75. number: 5
  76. number: 2
  77. `[1:]
  78. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  79. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  80. return
  81. }
  82. // Test brackets
  83. input = "a + 1 * (5 + 6)"
  84. expectedOutput = `
  85. plus
  86. identifier: a
  87. times
  88. number: 1
  89. plus
  90. number: 5
  91. number: 6
  92. `[1:]
  93. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  94. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  95. return
  96. }
  97. // Test needless brackets
  98. input = "(a + 1) * (5 / (6 - 2))"
  99. expectedOutput = `
  100. times
  101. plus
  102. identifier: a
  103. number: 1
  104. div
  105. number: 5
  106. minus
  107. number: 6
  108. number: 2
  109. `[1:]
  110. // Pretty printer should get rid of the needless brackets
  111. res, err := UnitTestParseWithPPResult("mytest", input, "(a + 1) * 5 / (6 - 2)")
  112. if err != nil || fmt.Sprint(res) != expectedOutput {
  113. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  114. return
  115. }
  116. }
  117. func TestLogicParsing(t *testing.T) {
  118. input := "not (a + 1) * 5 and tRue == false or not 1 - 5 != test"
  119. expectedOutput := `
  120. or
  121. and
  122. not
  123. times
  124. plus
  125. identifier: a
  126. number: 1
  127. number: 5
  128. ==
  129. true
  130. false
  131. not
  132. !=
  133. minus
  134. number: 1
  135. number: 5
  136. identifier: test
  137. `[1:]
  138. res, err := UnitTestParseWithPPResult("mytest", input, "not (a + 1) * 5 and true == false or not 1 - 5 != test")
  139. if err != nil || fmt.Sprint(res) != expectedOutput {
  140. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  141. return
  142. }
  143. input = "a > b or a <= p or b hasSuffix 'test' or c hasPrefix 'test' and x < 4 or x >= 10"
  144. expectedOutput = `
  145. or
  146. or
  147. or
  148. or
  149. >
  150. identifier: a
  151. identifier: b
  152. <=
  153. identifier: a
  154. identifier: p
  155. hassuffix
  156. identifier: b
  157. string: 'test'
  158. and
  159. hasprefix
  160. identifier: c
  161. string: 'test'
  162. <
  163. identifier: x
  164. number: 4
  165. >=
  166. identifier: x
  167. number: 10
  168. `[1:]
  169. res, err = UnitTestParseWithPPResult("mytest", input, `a > b or a <= p or b hassuffix "test" or c hasprefix "test" and x < 4 or x >= 10`)
  170. if err != nil || fmt.Sprint(res) != expectedOutput {
  171. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  172. return
  173. }
  174. input = "(a in null or c notin d) and false like 9 or x // 6 > 2 % 1"
  175. expectedOutput = `
  176. or
  177. and
  178. or
  179. in
  180. identifier: a
  181. null
  182. notin
  183. identifier: c
  184. identifier: d
  185. like
  186. false
  187. number: 9
  188. >
  189. divint
  190. identifier: x
  191. number: 6
  192. modint
  193. number: 2
  194. number: 1
  195. `[1:]
  196. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  197. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  198. return
  199. }
  200. }
  201. func TestCompositionStructureParsing(t *testing.T) {
  202. // Assignment of map
  203. input := `x := { z : "foo", y : "bar", z : "zzz" }`
  204. expectedOutput := `
  205. :=
  206. identifier: x
  207. map
  208. kvp
  209. identifier: z
  210. string: 'foo'
  211. kvp
  212. identifier: y
  213. string: 'bar'
  214. kvp
  215. identifier: z
  216. string: 'zzz'
  217. `[1:]
  218. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  219. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  220. return
  221. }
  222. input = `x := { ==`
  223. if _, err := UnitTestParse("mytest", input); err.Error() !=
  224. "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:8)" {
  225. t.Error(err)
  226. return
  227. }
  228. // Statement separator
  229. input = `print(123); x := { z : "foo", y : "bar", z : "zzz" }; foo := y == 1`
  230. expectedOutput = `
  231. statements
  232. identifier: print
  233. funccall
  234. number: 123
  235. :=
  236. identifier: x
  237. map
  238. kvp
  239. identifier: z
  240. string: 'foo'
  241. kvp
  242. identifier: y
  243. string: 'bar'
  244. kvp
  245. identifier: z
  246. string: 'zzz'
  247. :=
  248. identifier: foo
  249. ==
  250. identifier: y
  251. number: 1
  252. `[1:]
  253. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  254. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  255. return
  256. }
  257. input = `print(123); x := { z : "foo", y : "bar", z : "zzz" }; foo £ y == 1`
  258. if _, err := UnitTestParse("mytest", input); err.Error() !=
  259. "Parse error in mytest: Lexical error (Cannot parse identifier '£'. Identifies may only contain [a-zA-Z] and [a-zA-Z0-9] from the second character) (Line:1 Pos:59)" {
  260. t.Error(err)
  261. return
  262. }
  263. input = `x := [1,2]
  264. [a,b] := x`
  265. expectedOutput = `
  266. statements
  267. :=
  268. identifier: x
  269. list
  270. number: 1
  271. number: 2
  272. :=
  273. list
  274. identifier: a
  275. identifier: b
  276. identifier: x
  277. `[1:]
  278. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  279. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  280. return
  281. }
  282. input = `x := [1,2];[a,b] := x`
  283. expectedOutput = `
  284. statements
  285. :=
  286. identifier: x
  287. list
  288. number: 1
  289. number: 2
  290. :=
  291. list
  292. identifier: a
  293. identifier: b
  294. identifier: x
  295. `[1:]
  296. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  297. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  298. return
  299. }
  300. }