As a long-time C programmer, I am immediately urged to consider the simplification
b = parseExpressionAtPrecedence(op.precedence + !op.rightAssociative)
...and IMHO those variable names are a bit longer than useful --- expr(prec), atom(), and op() would be my choice, as it shows the structure more clearly, which I think is definitely the most important thing to see here: it's a loop with a recursive call inside it, and an ending condition based on the precedence.
This technique (called precedence climbing) makes parsing these sorts of arithmetic expressions a lot less painful.
This article is a more detailed explanation of this technique:
https://www.engr.mun.ca/~theo/Misc/exp_parsing.htm#climbing
It also naturally leads to being table-driven, whereby adding/removing operators and adjusting their precedences becomes extremely easy.