parser_exp_test.go 7.5 KB

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