Task 2
Task 2
Scenario:
You are designing a programming language called CalcScript that supports arithmetic
expressions with addition (+), multiplication (*), parentheses, and variables (id). The
language requires proper precedence (multiplication before addition) and balanced
parentheses.
Non-terminals: {𝐸, 𝑇, 𝐹}
The grammar is:
Start symbol: 𝐸
Terminals: {+,*,(,),𝑖𝑑}
Production rules:
1. E → E + T | T
2. T → T * F | F
3. F → (E) | id
Tasks:
Derivation and Parse Tree:
Derive the string "id + id * (id + id)" using the leftmost derivation.
Draw the corresponding parse tree.
Ambiguity Analysis:
Check if the CFG is ambiguous with examples.
If ambiguous, modify the CFG to resolve ambiguity while preserving precedence and
associativity.
Parser Design:
Choose a parsing technique (top-down or bottom-up) and justify it.
Outline a parser implementation strategy for CalcScript.
1|Page
8. F → (E)
9. E → E + T
10. E → T + T
11. T → F + T
12. F → id + T
13. T → id
Thus, the full derivation is:
id + id * (id + id)
Parse Tree:
The parse tree follows operator precedence (multiplication before addition):
Ambiguity Analysis
A grammar is ambiguous if there exists more than one valid parse tree for the same string.
Checking Ambiguity:
Consider the string:
id + id * id
Two possible parse trees:
1. Parse Tree 1 (Correct Precedence)
2|Page
2. Parse Tree 2 (Incorrect Precedence, Addition First)
Resolving Ambiguity
To enforce multiplication before addition, we rewrite the grammar:
3|Page
E → E + T | T
T → T * F | F
F → id | (E)
By enforcing T * F at a lower level, multiplication is evaluated before addition.
Parser Design
We choose Bottom-Up Parsing (LR Parser) because:
It naturally handles operator precedence.
It constructs the parse tree from leaves to the root.
It works well with left-recursive grammars.
Parser Implementation Strategy:
1. Lexical Analysis:
o Tokenize input (id, +, *, (, ))
2. Syntax Analysis (Parsing):
o Use Shift-Reduce Parsing (LR Parser)
o Reduce expressions using the grammar rules.
3. Evaluation (Semantic Analysis):
o Maintain a stack to evaluate expressions.
4|Page
}
ops.pop(); // Remove '('
}
else if (curr == '+' || curr == '*') {
while (!ops.empty() && ops.top() == '*' && curr == '+') {
applyOperator(ops.top());
ops.pop();
}
ops.push(curr);
}
}
// Apply remaining operators
while (!ops.empty()) {
applyOperator(ops.top());
ops.pop();
}
return values.top();
}
int main() {
string expression = "3+2*(1+4)"; // Example input
cout << "Result: " << evaluate(expression) << endl;
return 0;
}
5|Page