This allows for having different tokens mapping to the same mathematical
operator, with potentially different semantics. For example, we can add
`$` as another notation for factorial, but allowing it to be chained:
meaning we can evaluate `3$$` to `720`, and still keep `3!!` as a syntax
error.
To do so, we simply need to add the following line to our operator
table:
```c
POSTOP(UNOP_FACT, 5, ASSOC_LEFT, '$', 0)
```
This change, by not breaking anything, shows that the order of the table
*probably* does not matter to the parsing code.
This also enables a future refactoring to only use the parts of the
tables that are *actually* needed, such as isolating the prefix, infix,
or postfix operators when using the table to check a subset of them
I noted that the `right_prec` and `next_prec` functions taking a
character only work because prefix operators come after infix operators
in the table. We should compare the *actual* operator kind, which would
probably need a single operator enum to make sure there are no
collisions.
The previous version of the algorithm did not take into account the fact
that the main loop should only run while we have postfix or infix
operators. This happened to work because of the small amount of
operators used in the grammar.
The previous version also had prefix operators hard-coded in the operand
parsing function.