123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- /*
- * ECAL
- *
- * Copyright 2020 Matthias Ladkau. All rights reserved.
- *
- * This Source Code Form is subject to the terms of the MIT
- * License, If a copy of the MIT License was not distributed with this
- * file, You can obtain one at https://opensource.org/licenses/MIT.
- */
- package parser
- import (
- "fmt"
- "testing"
- )
- func TestSimpleExpressionParsing(t *testing.T) {
- // Test error output
- input := `"bl\*a"conversion`
- if _, err := UnitTestParse("mytest", input); err.Error() !=
- "Parse error in mytest: Lexical error (invalid syntax while parsing string) (Line:1 Pos:1)" {
- t.Error(err)
- return
- }
- // Test incomplete expression
- input = `a *`
- if _, err := UnitTestParse("mytest", input); err.Error() !=
- "Parse error in mytest: Unexpected end" {
- t.Error(err)
- return
- }
- input = `not ==`
- if _, err := UnitTestParse("mytest", input); err.Error() !=
- "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:5)" {
- t.Error(err)
- return
- }
- input = `(==)`
- if _, err := UnitTestParse("mytest", input); err.Error() !=
- "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:2)" {
- t.Error(err)
- return
- }
- input = "5 ( 5"
- if _, err := UnitTestParse("mytest", input); err.Error() !=
- "Parse error in mytest: Term can only start an expression (() (Line:1 Pos:3)" {
- t.Error(err)
- return
- }
- input = "5 + \""
- if _, err := UnitTestParse("mytest", input); err.Error() !=
- "Parse error in mytest: Lexical error (Unexpected end while reading string value (unclosed quotes)) (Line:1 Pos:5)" {
- t.Error(err)
- return
- }
- // Test prefix operator
- input = ` + a - -5`
- expectedOutput := `
- minus
- plus
- identifier: a
- minus
- number: 5
- `[1:]
- if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- }
- func TestArithmeticParsing(t *testing.T) {
- input := "a + b * 5 /2"
- expectedOutput := `
- plus
- identifier: a
- div
- times
- identifier: b
- number: 5
- number: 2
- `[1:]
- if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- // Test brackets
- input = "a + 1 * (5 + 6)"
- expectedOutput = `
- plus
- identifier: a
- times
- number: 1
- plus
- number: 5
- number: 6
- `[1:]
- if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- // Test needless brackets
- input = "(a + 1) * (5 / (6 - 2))"
- expectedOutput = `
- times
- plus
- identifier: a
- number: 1
- div
- number: 5
- minus
- number: 6
- number: 2
- `[1:]
- // Pretty printer should get rid of the needless brackets
- res, err := UnitTestParseWithPPResult("mytest", input, "(a + 1) * 5 / (6 - 2)")
- if err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- }
- func TestLogicParsing(t *testing.T) {
- input := "not (a + 1) * 5 and tRue == false or not 1 - 5 != test"
- expectedOutput := `
- or
- and
- not
- times
- plus
- identifier: a
- number: 1
- number: 5
- ==
- true
- false
- not
- !=
- minus
- number: 1
- number: 5
- identifier: test
- `[1:]
- res, err := UnitTestParseWithPPResult("mytest", input, "not (a + 1) * 5 and true == false or not 1 - 5 != test")
- if err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- input = "a > b or a <= p or b hasSuffix 'test' or c hasPrefix 'test' and x < 4 or x >= 10"
- expectedOutput = `
- or
- or
- or
- or
- >
- identifier: a
- identifier: b
- <=
- identifier: a
- identifier: p
- hassuffix
- identifier: b
- string: 'test'
- and
- hasprefix
- identifier: c
- string: 'test'
- <
- identifier: x
- number: 4
- >=
- identifier: x
- number: 10
- `[1:]
- res, err = UnitTestParseWithPPResult("mytest", input, `a > b or a <= p or b hassuffix "test" or c hasprefix "test" and x < 4 or x >= 10`)
- if err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- input = "(a in null or c notin d) and false like 9 or x // 6 > 2 % 1"
- expectedOutput = `
- or
- and
- or
- in
- identifier: a
- null
- notin
- identifier: c
- identifier: d
- like
- false
- number: 9
- >
- divint
- identifier: x
- number: 6
- modint
- number: 2
- number: 1
- `[1:]
- if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- }
- func TestCompositionStructureParsing(t *testing.T) {
- // Assignment of map
- input := `x := { z : "foo", y : "bar", z : "zzz" }`
- expectedOutput := `
- :=
- identifier: x
- map
- kvp
- identifier: z
- string: 'foo'
- kvp
- identifier: y
- string: 'bar'
- kvp
- identifier: z
- string: 'zzz'
- `[1:]
- if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- input = `x := { ==`
- if _, err := UnitTestParse("mytest", input); err.Error() !=
- "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:8)" {
- t.Error(err)
- return
- }
- // Statement separator
- input = `print(123); x := { z : "foo", y : "bar", z : "zzz" }; foo := y == 1`
- expectedOutput = `
- statements
- identifier: print
- funccall
- number: 123
- :=
- identifier: x
- map
- kvp
- identifier: z
- string: 'foo'
- kvp
- identifier: y
- string: 'bar'
- kvp
- identifier: z
- string: 'zzz'
- :=
- identifier: foo
- ==
- identifier: y
- number: 1
- `[1:]
- if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- input = `print(123); x := { z : "foo", y : "bar", z : "zzz" }; foo £ y == 1`
- if _, err := UnitTestParse("mytest", input); err.Error() !=
- "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)" {
- t.Error(err)
- return
- }
- input = `x := [1,2]
- [a,b] := x`
- expectedOutput = `
- statements
- :=
- identifier: x
- list
- number: 1
- number: 2
- :=
- list
- identifier: a
- identifier: b
- identifier: x
- `[1:]
- if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- input = `x := [1,2];[a,b] := x`
- expectedOutput = `
- statements
- :=
- identifier: x
- list
- number: 1
- number: 2
- :=
- list
- identifier: a
- identifier: b
- identifier: x
- `[1:]
- if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
- t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
- return
- }
- }
|