{"id":17761377,"url":"https://github.com/miromannino/mexpr","last_synced_at":"2025-09-05T05:34:23.938Z","repository":{"id":3608449,"uuid":"4673369","full_name":"miromannino/MExpr","owner":"miromannino","description":"C++ library which parses human-like arithmetic expressions","archived":false,"fork":false,"pushed_at":"2015-05-25T20:43:54.000Z","size":226,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-01T01:51:08.452Z","etag":null,"topics":["compiler","cpp","interpreter","mathematical-expressions","parser","parsing","parsing-library"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/miromannino.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-06-15T09:18:06.000Z","updated_at":"2023-02-07T08:18:31.000Z","dependencies_parsed_at":"2022-09-01T04:21:16.977Z","dependency_job_id":null,"html_url":"https://github.com/miromannino/MExpr","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miromannino%2FMExpr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miromannino%2FMExpr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miromannino%2FMExpr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miromannino%2FMExpr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/miromannino","download_url":"https://codeload.github.com/miromannino/MExpr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253805411,"owners_count":21967050,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler","cpp","interpreter","mathematical-expressions","parser","parsing","parsing-library"],"created_at":"2024-10-26T19:35:13.631Z","updated_at":"2025-05-12T18:55:42.003Z","avatar_url":"https://github.com/miromannino.png","language":"C++","readme":"# MExpr\n\nC++ library which parses human-like arithmetic expressions like the following:\n\n\t-3xy^2 - 3(xy + 3)(-5x + y)\n\nTo understand better, let's make some examples comparing them to the more traditional computer-like notation:\n\n\u003ctable class=\"table\"\u003e\n\t\u003ctr\u003e\u003cth\u003eMExpr notation\u003c/th\u003e\u003cth\u003eTraditional computer-like notation\u003c/th\u003e\u003c/tr\u003e\n\t\u003ctr\u003e\u003ctd\u003e3xy\u003c/td\u003e\u003ctd\u003e3 * x * y\u003c/td\u003e\u003c/tr\u003e\n\t\u003ctr\u003e\u003ctd\u003e-3(x + y)\u003c/td\u003e\u003ctd\u003e-3 * (x + y)\u003c/td\u003e\u003c/tr\u003e\n\t\u003ctr\u003e\u003ctd\u003e(x + y)(x + 4)\u003c/td\u003e\u003ctd\u003e(x + y) * (x + 4)\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n\n## Features\n\n### Implicit multiplications\n\nThe parser interprets the text to detect implicit multiplication. For example the expression `xy` is interpreted as `x * y`, and the expression `-3(x + y)(x + 4)` as `-3 * (x + y) * (x + 4)`.\n\n### One character variables\n\nLike the arithmetic expression which we are used to write in a sheet of paper, the variables are single-character words like: `x`, `y`, etc.\n\nThat has opened the possibility to recognize implicit multiplications in a expression like: `xy^2`.\n\nThat is also an assumption which we have in our minds, and that allow us to interprets `xy` as a multiplication between the variables `x` and `y`, rather than the single variable `xy`.\n\n### Bytecode compilation\n\nThe library parses the input string and then it builds an abstract syntax tree. For example, with the expression \u003ccode\u003e-3xy^2\u003c/code\u003e, the parser builds the following abstract syntax tree:\n\n\t[ * ]─[ -1 ]\n\t  └───[ * ]─[ 3 ]\n\t        └───[ * ]─[ x ]\n\t              └───[ ^ ]─[ y ]\n\t                    └───[ 2 ]\n\n\u003cbr/\u003e\n\n\u003cp\u003eAt this point, the library can directly evaluate the expression using the tree (browsing it recursively).\u003c/p\u003e\n\n\u003cp\u003eIn some cases, for example when you want to draw a plot, you need to evaluate the same expression changing only the value of a variable. For this reason, the library can \"compile\" the AST to have a more efficient representation of the expression. The generated code is a simple bytecode, that uses a stack to compute operations (similarly to the Java bytecode).\u003c/p\u003e\n\n\u003cp\u003eThis is the representation of the bytecode generated using the previous expression:\u003c/p\u003e\n\n\tVAL: -1\n\tVAL: 3\n\tVAR: x\n\tVAR: y\n\tVAL: 2\n\tPOW\n\tMUL\n\tMUL\n\tMUL\n\n\u003cbr/\u003e\n\n### Functions\n\nMExpr has the possibility to use functions inside the expression.\n\nThe library comes with all the functions of _math.h_. Furthermore, one can also\ninsert new custom functions that can do almost anything!\n\nAll the function names starts with the underscore character, for example `_f(x)`. This notation is important\nbecause it allows to disambiguate expressions like `f(x)`. In fact, that could be interprets as a multiplication\nbetween the variables `f` and `x`, or as the call of the function `f` passing `x` as argument. On the contrary\n`_f(x)` has only one interpretation.\n\n#### Function overloading\n\nThe functions can be overloaded. For example, one can define the function `_sum(a,b)` that adds two numbers.\nFurthermore, one can also define `_sum(a,b,c)`. The parser can manage overloaded functions distinguishing\nthe functions by the number of parameters.\u003c/p\u003e\n\n\n### Dynamic environment\n\nThe parser has a dynamic environment, that maintains all the value associated to a variable symbol. Moreover, for each function symbol, it maintains a pointer to the associated function.\n\nThis approach allows one to define a variable or a function even after the expression parsing (as well as the expression compilation). For the same reason one can redefine a previously defined function, or change the value of a variable (useful if one is drawing a plot).\n\n\n## How to use it\n\nThe following examples introduces how to use MExpr in your own project. Those examples are also available in the `test` folder and compiled in the `build/test/` folder.\n\n### Example 1\n\nThis example shows how to create an expression, assign some values to its variables and print its value.\n\n    Expression* e = new Expression(\"-3(4xy^2x-2x)(8x^-(3x)+2y^-2)\");\n    e-\u003esetVariable('x', 4);\n    e-\u003esetVariable('y', -5);\n\n    cout \u003c\u003c e-\u003eevaluate() \u003c\u003c endl;\n\n\u003cbr/\u003e\n\n### Example 2\n\nThis example shows how MExpr could be used to repeatedly evaluate the same expression, only changing the value of a variable.\nThe expression is previously compiled, to allow a faster evaluation.\n\n    Expression* e = new Expression(\"x^2\");\n    e-\u003ecompile(); //To allow a faster evaluations (e.g. to draw a plot)\n\n    for (int i = 0; i \u003c 10; i++) {\n        e-\u003esetVariable('x', i);\n        cout \u003c\u003c e-\u003eevaluate() \u003c\u003c ' ';\n    }\n    cout \u003c\u003c endl;\n\n\u003cbr/\u003e\n\n### Example 3\n\nThis example shows how to print in the console the tree representation and the bytecode representation of the expression.\n\n\tExpression* e = new Expression(\"-3xy^2\");\n\n    cout \u003c\u003c \"Expression AST: \" \u003c\u003c endl;\n    string* s = e-\u003egetExprTreeString();\n    cout \u003c\u003c *s;\n    delete s;\n\n    e-\u003ecompile();\n\n    cout \u003c\u003c endl \u003c\u003c \"Compiled expression: \" \u003c\u003c endl;\n    s = e-\u003egetExprCodeString();\n    cout \u003c\u003c *s;\n    delete s;\n\n\u003cbr/\u003e\n\n### Example 4\n\nThis example shows how to create and use a custom function inside the expression.\n\n\t // myDiv(a, b) = a / b\n\tvoid myDiv(MExpr::StackType* s) {\n\t    MExpr::ValueType arg1, arg2;\n\t    arg1 = s-\u003estack[s-\u003estp - 2];\n\t    arg2 = s-\u003estack[s-\u003estp - 1];\n\t    s-\u003estack[s-\u003estp - 2] = arg1 / arg2;\n\t    s-\u003estp--;\n\t}\n\n\tint main(void) {\n\t    Expression* e = new Expression(\"_div(16,4)\");\n\t    e-\u003esetFunction(\"_div\", \u0026myDiv, 2);\n\n\t    cout \u003c\u003c e-\u003eevaluate() \u003c\u003c endl;\n\n\t    return 0;\n\t}\n\n\u003cbr/\u003e\n\n### Compile your code that uses MExpr\n\nThe Makefile is configured to create a shared library, you can use it with your C++ programs dynamically linking this library.\n\n\tg++ -o myExample -lmexpr myExample.cpp\n\n\u003cbr/\u003e\n\n## How to compile MExpr\n\n - Ensure that you satisfy the requirements.\n - Open the Makefile and set your OS changing the `OperatingSystem` variable.\n\nRun the command you need \n\n - `make all` to compile the library\n - `make run-tests` to run the tests\n - `make clean-gtest` to remove the GoogleTest library folder\n - `make install` to install the library in `/usr/local/lib`\n\t\n\n### Common issues\n\n- Mac OS X, by default, doesn't have the `/usr/local/lib` and `/usr/local/include` folders, check that you have these folders.\n- You can have some problems compiling your examples if you don't install it before. If you don't want to install it, ensure that the `DYLD_LIBRARY_PATH` (or the `LD_LIBRARY_PATH`) was proudly configured.\n- Ensure that you have installed `wget`, that is used to download the GoogleTest library\n\n\n## Requirements\n\nTested operating systems: OSX, Linux\n\nTo compile the library you need: bison, flex and g++.\n\nGoogleTests library: but is automatically downloaded in the `gtest` folder during the building process (i.e. `make all`).\n\n## License\n\nThis project is licensed under the MIT license\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiromannino%2Fmexpr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmiromannino%2Fmexpr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiromannino%2Fmexpr/lists"}