I'm currently writing (for fun) a programming language heavily inspired by mathematics.
The operators (and their precedence/associativity) are defined within the language, for example:
let factorial be an operator[int <- int!]
with precedence of 2
and left-to-right associativity;
let factorial(n) = ...;
let abs be an operator[number <- |number|]
with precedence of 2
and no associativity;
let abs(x) = ...;
let not be an operator[bool <- !bool]
with precedence of 2
and right-to-left associativity;
This holds true for more common operators (+
, -
, *
, /
, ...).
NB: the syntax is not definitive
In order to generate a useful AST, I decided to have multiple parsing steps. In the first step, an expression is just a list of terms and symbols (with parenthesis grouping supported), for example:
m! / (n! * (m - n)!)
Will be parsed as (simplified AST here):
["m", "!", "/", ["n", "!", "*", ["m", "-", "n"], "!"]]
After the first step, I know what operators are defined, I know their order of priority, and their associativity.
I'm having difficulties implementing the second step that is supposed to generate a tree (instead of a list) for the expression.
The first step is implemented using a library taking an EBNF syntax as input. For the second step, I'm trying to "find" in the expression the patterns of the operators (using a homemade Parser Combinator):
let factorial be an operator[int <- int!] ...;
# here the pattern is ["int", "!"]
But this method does not respect the precedence nor the associativity.
If anyone has a suggestion on how to proceed from here, or a link to a paper on the subject, it would be very welcome since I'm running out of hairs to pull :)