The minus sign ('-') is use for two different operations in mathematics. Not only does it perform subtraction of two operands, it also negates a single operand:
The same is true in most programming languages. The minus operator is said to be overloaded.
How can we tell apart subtraction from unary minus in a compiler or interpreter?
When scanning expressions, the lexical scanner cannot distinguish between different uses of the same operator. Lexical analysis only distinguishes individual lexemes; it cannot tell the context in which a lexeme was used. To a scanner, all uses of the minus sign are classified as, say, T_MINUS:
The regular expressions used to classify lexemes are too limited to determine which kind of operation is being performed based on the context in which the operation is found. The task must be done by the Parser.
The parser can recognize the difference between subtraction and unary minus by matching the number of operands surrounding the T_MINUS token. If the T_MINUS token has an operand on each side, the use is subtraction, otherwise, it is a unary minus that applies only to the following operand. We can write a grammar production that recognizes the unary minus in its proper context.
Unary minus has high precedence; it is done before most other arithmetic operations. To build this into a grammar, we place it close to the leaves of the parse tree so that its grammar production is applied first (before other arithmetic operations). Here is a two-production grammar containing both subtraction and unary minus:
The above grammar correctly parses expressions with both subtraction and unary minus, such as:
Unary minus and subtraction are distinguished properly. Unary minus is done first, since it appears closest to the leaves of the parse tree.
See the sample code for semantic actions showing how to code a unary minus.
Ian D. Allen CST 8152 Home Page