As we all know, one can define custom operators in Swift like this:
infix operator +- { associativity left precedence 140 }
The Swift Programming Language Specification tells us about this that
New operators are declared at a global level using the operator keyword
What I am wondering about this is what they mean by 'global level', and how the Swift compiler figures out the operators at syntactical analysis. Does the Swift compiler use a custom parser that requires to know these operator definitions at use site or does it have some special OPERATOR_PRECEDENCE
compiler phase (or something like that)? Or something completely different that I am missing here?
I don't know how swift does it, but it's not that difficult.
One approach is to first construct an AST in which an expressions is just a list of operands (including parenthesized subexpressions) and operators. Once the initial parse is complete and operators are declared, precedence (and fixity, if necessary) can be attached to each operator, and the AST is rescanned, rebuilding each expression list as an expression tree using a simplified form of the shunting-yard algorithm.
In the case of Swift, it appears that white-space is used to distinguish between prefix, postfix and infix operators (shades of Fortress!). It's not clear to me whether a sequence of operators would need to be rescanned once all operator names are known, but I can't see any other way of doing it since the whitespace rules do not allow a prefix operator (for example) to be followed by a space in order to separate it from a following prefix operator. That doesn't complicate the above algorithm much, since operators, operands and parentheses do not share any common characters. So even if it is not clear where every operator token starts, the worst that can happen is that you end up having to split an operator token into several actual operators.