Some of the rules of arithmetic are so familiar that it is hard to imagine an alternative, and others are subtle enough that you may not have thought about them. However, the subtle rules of arithmetic are important, and your user may know them and rely on them.
7.1.1 Conventional Symbols
The most obvious convention for arithmetic is the meaning of the symbols for addition, subtraction, multiplication, and division. Addition and subtraction almost always appear as " + " and " - ". Multiplication varies a little more but most often appears as " * ". One alternative for division is the symbol " ·", although this is giving way to the more popular " / ", which appears on most keyboards. Symbols for exponentiation include " ** ", " ", and " ^ ". As a language developer, you have the choice of using whatever symbols you want to represent arithmetic operations. The remainder of this chapter uses the symbols " + ", " - ", " * ", " / ", and " ^ ".
7.1.2 Conventional Precedence
Regardless of which operators you include in a language for arithmetic, parentheses always take the highest precedence. After parentheses, exponentiation, or "powers," have the highest precedence, followed by multiplication and division, and then addition and subtraction. For example, a parser must evaluate
(5 + 4) * 3 ^ 2 81
7.1.3 Conventional Associativity
Multiplication and division have the same precedence, so a question arises about the order in which to apply the operators if they occur in succession. The conventional answer is to apply the operators left to right. For example,
35 / 7 * 3 / 15
should equal 1 , the result of dividing 35 by 7 , multiplying by 3 , and dividing by 15 . Applying operators in this order means that they "associate" to the left. Similarly, addition and subtraction have the same precedence as each other, and they also associate to the left. Exponentiation, on the other hand, associates to the right.
A grammar can recognize proper precedence and associativity and adopt a conventional set of symbols. If it does, an arithmetic parser follows almost directly from its grammar. The tasks for building the parser are as follows :
Write a grammar.
Write assemblers to build an arithmetic result.
Generate the parser from the grammar, plugging in the assemblers.