PHPackages                             macfja/lexer-expression - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. macfja/lexer-expression

ActiveLibrary[Database &amp; ORM](/categories/database)

macfja/lexer-expression
=======================

Library to transform a Doctrine lexer into a RPN expression and solve it

1.1.0(10y ago)03.3kMITPHP

Since Sep 28Pushed 10y ago1 watchersCompare

[ Source](https://github.com/MacFJA/LexerExpression)[ Packagist](https://packagist.org/packages/macfja/lexer-expression)[ RSS](/packages/macfja-lexer-expression/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (3)Used By (0)

Lexer Expression
================

[](#lexer-expression)

1. Description
2. What is Shunting Yard algorithm
3. The Shunting Yard implementation
4. The RPN expression Solver
5. The AST Tree builder
6. Install
7. Usage
8. Similar projects
9. Documentations

Description
-----------

[](#description)

The main goal of this library is to transform an expression into a computer understandable expression, by using

1. Doctrine Lexer
2. The Shunting Yard algorithm

As the input of the Shunting Yard is a Doctrine Lexer, the library is not limited to mathematics expression.

The library provide an "evaluator" of the Shunting Yard algorithm output, or transform it into a AST Tree

What is Shunting Yard algorithm
-------------------------------

[](#what-is-shunting-yard-algorithm)

The best explanation can by found on [Wikipedia](https://en.wikipedia.org/wiki/Shunting-yard_algorithm), or on this [article](https://igor.io/2013/12/03/stack-machines-shunting-yard.html) of [@igorw](https://github.com/igorw).

But to make simple, the main idea is to transform a list of chars into multiple of small group.

Simple example: `(1 + 2) * 3` is really simple for us (human) to process, but a computer can do it, it need to split it into small chunk. And evaluate it piece by piece. For a computer, the expression need to be evaluate like this:

```
        *
       / \
      +   3
     / \
    1   2

```

This a binary tree, and yes it's also a kind of AST. So to solve the expression a computer first evaluate the group (we will name the result as **(a)**):

```
      +
     / \
    1   2

```

And then it evaluate the group:

```
   *
  / \
(a)  3

```

The Shunting Yard algorithm transform your expression into an intermediate expression: a RPN expression. The RPN expression of `(1 + 2) * 3` is `1 2 + 3 *`.

This expression can be read as:

- Parameter `1`
- Parameter `2`
- Operator `+` (that take 2 parameters: the two previous parameters)
- Parameter `3`
- Operator `*` (that take 2 parameters: the result of the operation and the previous parameter)

The Shunting Yard implementation
--------------------------------

[](#the-shunting-yard-implementation)

Like most of Shunting Yard implementation, it can parse "simple" expression (with simple operator) and make parenthesis reduction. It can parse unary, and binary functions (like `sin(x)`, `max(x,y)`) but also any functions (ex: `fct(a,b,c,x,y,z)`).

But the main "feature" it's the use of Doctrine Lexer.

The RPN expression Solver
-------------------------

[](#the-rpn-expression-solver)

The RPN solver allow you to solve a RPN expression (a list of Doctrine Lexer token). It support Operator/Function with any arity.

The AST Tree builder
--------------------

[](#the-ast-tree-builder)

The AST Tree builder can transform the RPN expression (a list of Doctrine Lexer token) into an AST Tree.
The tree root is a node, the last(final) node (in the **What is Shunting Yard algorithm**, it's the `*` operator). This root node is composed of values (leafs of a tree) and nodes (branches).

### Limitation

[](#limitation)

The Solver can not solver function with variable arity (or optional parameters)

Install
-------

[](#install)

To install with composer:

```
composer require macfja/lexer-expression

```

Usage
-----

[](#usage)

### Very simple Doctrine DQL

[](#very-simple-doctrine-dql)

```
use \Doctrine\ORM\Query\Lexer;

$dql = 'SELECT u FROM User u WHERE u.id = MAX(5, 7)';
$lexer = new Lexer($dql);
$sy = new ShuntingYard();
$sy->setLexer($lexer);
$sy->setOpenParenthesis(Lexer::T_OPEN_PARENTHESIS);
$sy->setCloseParenthesis(Lexer::T_CLOSE_PARENTHESIS);
$sy->setOperators(array(
    new ShuntingYardOperator(Lexer::T_MAX,    10, ShuntingYardOperator::ASSOCIATIVITY_LEFT),
    new ShuntingYardOperator(Lexer::T_SELECT, 10, ShuntingYardOperator::ASSOCIATIVITY_LEFT),
    new ShuntingYardOperator(Lexer::T_FROM,   10, ShuntingYardOperator::ASSOCIATIVITY_LEFT),
    new ShuntingYardOperator(Lexer::T_WHERE,  2,  ShuntingYardOperator::ASSOCIATIVITY_LEFT),
    new ShuntingYardOperator(Lexer::T_DOT,    10, ShuntingYardOperator::ASSOCIATIVITY_LEFT),
    new ShuntingYardOperator(Lexer::T_EQUALS, 10, ShuntingYardOperator::ASSOCIATIVITY_LEFT)
));
$sy->setArgumentSeparator(Lexer::T_COMMA);
var_dump($sy->parse());
```

### Very simple Mathematics expression

[](#very-simple-mathematics-expression)

3 examples are available in the `test` directory. The expression is `(1 + 2) / ((3 + 4 * 5) - 6)`.

- `test/MathRPN.php`: Just an expression to RPN example
- `test/MathSolve.php`: An example with the solver
- `test/MathAST.php`: An example with the tree builder

The tree of the expression is:

```
          "/"
         /   \
        /     \
       /      "-"
      /      /   \
     /     "+"    6
    /     /   \
  "+"    3    "*"
 /   \       /   \
1     2     4     5

```

Similar projects
----------------

[](#similar-projects)

- [droptable/php-shunting-yard](https://github.com/droptable/php-shunting-yard)
- [ircmaxell/php-math-parser](https://github.com/ircmaxell/php-math-parser)
- [ngorchilov/psy](https://github.com/ngorchilov/psy)
- [rbnvrw/PHPShuntingMathParser](https://github.com/rbnvrw/PHPShuntingMathParser)
- [Isinlor/php-shunting-yard](https://github.com/Isinlor/php-shunting-yard)
- [igorw/rpn](https://github.com/igorw/rpn)
- [mephir/rpn](https://github.com/mephir/rpn)
- [rn0/php-calc](https://github.com/rn0/php-calc)
- [pear/Math\_RPN](https://github.com/pear/Math_RPN)

Documentations
--------------

[](#documentations)

- [http://rosettacode.org/wiki/Parsing/Shunting-yard\_algorithm](http://rosettacode.org/wiki/Parsing/Shunting-yard_algorithm)
- [https://en.wikipedia.org/wiki/Shunting-yard\_algorithm](https://en.wikipedia.org/wiki/Shunting-yard_algorithm)
-
-

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity17

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

2

Last Release

3880d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1475671?v=4)[MacFJA](/maintainers/MacFJA)[@MacFJA](https://github.com/MacFJA)

---

Top Contributors

[![MacFJA](https://avatars.githubusercontent.com/u/1475671?v=4)](https://github.com/MacFJA "MacFJA (3 commits)")

---

Tags

doctrinelexershunting yardRPNReverse Polish Notation

### Embed Badge

![Health badge](/badges/macfja-lexer-expression/health.svg)

```
[![Health](https://phpackages.com/badges/macfja-lexer-expression/health.svg)](https://phpackages.com/packages/macfja-lexer-expression)
```

###  Alternatives

[doctrine/common

PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.

5.8k363.3M1.2k](/packages/doctrine-common)[gedmo/doctrine-extensions

Doctrine behavioral extensions

4.1k118.8M366](/packages/gedmo-doctrine-extensions)[symfony/property-info

Extracts information about PHP class' properties using metadata of popular sources

2.2k256.7M854](/packages/symfony-property-info)[scienta/doctrine-json-functions

A set of extensions to Doctrine that add support for json query functions.

58723.9M36](/packages/scienta-doctrine-json-functions)[beberlei/doctrineextensions

A set of extensions to Doctrine 2 that add support for additional query functions available in MySQL, Oracle, PostgreSQL and SQLite.

2.1k75.1M146](/packages/beberlei-doctrineextensions)[ramsey/uuid-doctrine

Use ramsey/uuid as a Doctrine field type.

90440.3M211](/packages/ramsey-uuid-doctrine)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
