Yacc/Bison tool overview in Compiler Design - Time & Space Complexity
When using Yacc or Bison to generate parsers, it's important to understand how the parsing process scales with input size.
We want to know how the time to parse grows as the input code gets longer or more complex.
Analyze the time complexity of the parser generated by Yacc/Bison for a simple grammar.
%token NUMBER PLUS MINUS
%%
expr: expr PLUS expr
| expr MINUS expr
| NUMBER
;
%%
int main() { return yyparse(); }
This code defines a simple arithmetic grammar and uses Yacc/Bison to generate a parser that processes expressions.
The parser repeatedly reads tokens and applies grammar rules to build the parse tree.
- Primary operation: Scanning tokens and applying grammar rules to parse expressions.
- How many times: Once per token in the input, with some backtracking or lookahead depending on grammar complexity.
As the input expression length increases, the parser processes more tokens and applies more rules.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 token reads and rule applications |
| 100 | About 100 token reads and rule applications |
| 1000 | About 1000 token reads and rule applications |
Pattern observation: The number of operations grows roughly in direct proportion to the input size.
Time Complexity: O(n)
This means the parser's work grows linearly with the length of the input code.
[X] Wrong: "The parser always takes the same time no matter how long the input is."
[OK] Correct: The parser must read and analyze each token, so longer inputs naturally take more time.
Understanding how parser time grows helps you explain how compilers handle code efficiently and why grammar design matters.
"What if the grammar had ambiguous rules causing backtracking? How would the time complexity change?"
Practice
Solution
Step 1: Understand Yacc/Bison role
Yacc/Bison are tools that take grammar rules and produce code that can parse input based on those rules.Step 2: Compare options with purpose
Only To convert grammar rules into code that parses language syntax describes converting grammar rules into parsing code, which matches Yacc/Bison's function.Final Answer:
To convert grammar rules into code that parses language syntax -> Option CQuick Check:
Yacc/Bison = grammar to parser code [OK]
- Confusing Yacc/Bison with code optimizers
- Thinking Yacc/Bison create user interfaces
- Assuming Yacc/Bison handle memory management
Solution
Step 1: Recall Yacc/Bison token syntax
Tokens in Yacc/Bison are declared using the %token directive followed by the token name.Step 2: Check each option
Only %token NUMBER uses the correct %token syntax. Others are invalid in Yacc/Bison files.Final Answer:
%token NUMBER -> Option AQuick Check:
Token declaration uses %token [OK]
- Using C or other language syntax for tokens
- Omitting the % sign before token
- Confusing token declaration with variable declaration
%token NUMBER
%%
expr: expr '+' NUMBER { printf("Sum\n"); };
What will happen when parsing the input "3 + 4"?Solution
Step 1: Analyze grammar rule
The rule expr: expr '+' NUMBER triggers action printing "Sum" when matched.Step 2: Parse input "3 + 4"
Input matches expr '+' NUMBER once, so action runs once printing "Sum".Final Answer:
The parser will print "Sum" once -> Option DQuick Check:
One matching rule triggers one print [OK]
- Assuming multiple prints for single input
- Thinking input causes syntax error
- Ignoring action code in grammar
%token NUMBER
%%
expr: expr '+' NUMBER { printf("Sum\n"); }
| NUMBER;
Solution
Step 1: Check rule syntax
Each grammar rule must end with a semicolon. The first rule lacks a semicolon after the action block.Step 2: Verify other parts
Token declaration is correct, %start is optional if default is used, and printf is allowed in actions.Final Answer:
Missing semicolon after first rule action -> Option BQuick Check:
Rules end with semicolon [OK]
- Forgetting semicolon after action block
- Confusing token syntax errors
- Assuming printf is disallowed in actions
Solution
Step 1: Understand operator precedence in Yacc/Bison
Yacc/Bison uses %left, %right, and %nonassoc directives to declare operator precedence and associativity.Step 2: Evaluate options
Define separate rules for addition and multiplication and declare precedence using %left and %right directives correctly uses separate rules and precedence declarations. Options B and C ignore precedence, causing incorrect parsing. Handle precedence in the lexer instead of grammar is incorrect because lexer does not handle precedence.Final Answer:
Define separate rules for addition and multiplication and declare precedence using %left and %right directives -> Option AQuick Check:
Precedence via %left/%right = correct parsing [OK]
- Ignoring precedence causing wrong parse trees
- Trying to handle precedence in lexer
- Declaring tokens without precedence directives
Ready to prove it?
Pass the test and this pattern moves unknown
