Skip to content

bhmj/xpression

Repository files navigation

Expression parser/evaluator in Go

What is it?

This project is a renewed version of expression parser/evaluator used in jsonslice. It is still work in progress so use it with caution.

Check it out

git clone https://github.com/bhmj/xpression.git

cd xpression

make build

./build/xpression "1+2"

Expression examples:

1+2
2**1**2
3 + 4 * 2 / (1-5) ** 2 ** 3
5 + -5
1/(3 & 5)
'a' > 'b'
'abc' =~ /a.c/i
!((false))

Operators and data types supported

Operators  
Arithmetic + - * / ** %
Bitwise | & ^ ~ << >>
Logical && || !
Comparison == != === !== >= > <= <
Regexp =~ !=~ !~
Parentheses ( )
Data types  
String constants 'string' or "string"
Numeric 64-bit integers or floats
Boolean true or false. Comparison results in boolean value.
Regexp /expression/ with modifiers:
i (case-insensitive), m (multiline), s (single-line), U (ungreedy)
Other null

Test coverage

Tests cover the majority of cases described in ECMAScript Language definition (specifically ECMAScript Language: Expressions reference and Testing and Comparison Operations).

Benchmarks

Evaluate (2) + (2) == (4)

$ go test -bench=. -benchmem -benchtime=4s
goos: darwin
goarch: amd64
pkg: github.com/bhmj/xpression
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Benchmark_ModifiedNumericLiteral_WithParsing-16        2714204    1853 ns/op    1272 B/op   26 allocs/op
Benchmark_ModifiedNumericLiteral_WithoutParsing-16    31129712   143.9 ns/op     128 B/op    2 allocs/op
PASS
ok      github.com/bhmj/xpression       12.363s

The same expression evaluated with github.com/Knetic/govaluate :

$ go test -bench='LiteralModifiers' -benchmem -benchtime=4s
goos: darwin
goarch: amd64
pkg: github.com/Knetic/govaluate
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
BenchmarkEvaluationLiteralModifiers_WithParsing-16     1000000    4019 ns/op    2208 B/op    43 allocs/op
BenchmarkEvaluationLiteralModifiers-16                30173640   147.2 ns/op       8 B/op     1 allocs/op
PASS
ok      github.com/Knetic/govaluate     9.810s

Changelog

0.7.x (2021-11-11) -- WIP
0.7.0 (2021-11-10) -- project renamed to xpression
0.6.0 (2021-11-05) -- a remainder operator % added. Benchmarks added. Some optimization done.
0.5.0 (2021-11-04) -- Tests added. Multiple bugs fixed.
0.4.0 (2021-11-02) -- Expression evaluation.
0.3.0 (2021-11-01) -- MVP.

Roadmap

  • arithmetic operators: + - * / ** %
  • bitwise operators: | & ^ ~
  • logical operators: || && !
  • comparison operators: > < >= <= == === != !==
  • full support of parentheses
  • regular expressions for strings
  • unary minus supported
  • expression evaluation
  • parser test coverage
  • expression evaluation
  • evaluator test coverage
  • refactor: operatorSpelling + operatorDetails -> map[spelling]{code, assoc, prec, args}. Store pointer to struct in Operand.
  • add external reference type (node reference in jsonslice)
  • Unicode support!

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :)

Licence

MIT

Author

Michael Gurov aka BHMJ