In compiler design, arithmetic expressions are constructed using grammar rules, typically
represented using context-free grammar (CFG). These grammar rules define how expressions
can be formed from smaller sub-expressions, operators, and operands (like variables and
constants).
🔧 Purpose of Grammar in Arithmetic Expressions
● Syntax definition: It specifies the valid structure of expressions.
● Parser guidance: Helps the parser understand and analyze the expression structure.
● AST construction: Provides the foundation for building Abstract Syntax Trees.
📐 Sample Grammar for Arithmetic Expressions
A simple grammar to construct arithmetic expressions with +, -, *, /, parentheses, and
identifiers/numbers might look like this:
E→E+T|E-T|T
T→T*F|T/F|F
F → (E) | id | num
Where:
● E is an expression
● T is a term
● F is a factor
● id represents an identifier (e.g., variable name)
● num represents a number (e.g., 42, 3.14)
🔄 Explanation of Grammar Rules
● E→E+T|E-T|T
○ An expression can be a sum or difference of two terms, or just a term.
● T→T*F|T/F|F
○ A term can be a product or quotient of two factors, or just a factor.
● F → (E) | id | num
○ A factor can be a parenthesized expression, an identifier, or a number.
📊 Example Derivation
Let's derive:
a + b * (c - d)
Step-by-step using the grammar:
1. E → E + T
2. E → T and T → F and F → id (a)
3. T → T * F
4. T → F and F → id (b)
5. F → (E) where E → E - T, E → F (c), T → F (d)
Derivation Tree (Abstract Syntax Tree):
(+)
/ \
(a) (*)
/ \
(b) (-)
/\
(c) (d)
📌 Operator Precedence and Associativity
This grammar enforces operator precedence:
● * and / bind tighter (higher precedence) than + and -
● Because T is used in E and F in T, multiplication/division must resolve before
addition/subtraction
It also enforces left associativity, e.g., for a - b - c:
E → E - T → (E - T) - T
Evaluated as: (a - b) - c
🛠️ In Practice
In compilers:
● Lexical analyzer identifies tokens: id, num, operators, and parentheses.
● Parser uses the grammar to build the parse tree or AST.
● Semantic analysis ensures types are compatible.
● Code generation translates the AST into machine/intermediate code.
Let me know if you'd like this visualized with a parse tree diagram or converted into a syntax-
directed definition (SDD)!