Reference no: EM133391704
Project - Introduction to Compilers
The second project involves modifying the syntactic analyzer for the attached compiler by adding to the existing grammar. The full grammar of the language is shown below. The highlighted portions of the grammar show what you must either modify or add to the existing grammar.
function:
function_header {variable} body
function_header:
FUNCTION IDENTIFIER [parameters] RETURNS type ;
variable:
IDENTIFIER : type IS statement
parameters:
parameter {, parameter}
parameter:
IDENTIFIER : type
type:
INTEGER | REAL | BOOLEAN
body:
BEGIN statement END ;
statement: expression ; |
REDUCE operator {statement} ENDREDUCE ; |
IF expression THEN statement ELSE statement ENDIF ; |
CASE expression IS {case} OTHERS ARROW statement ENDCASE ;
operator:
ADDOP | MULOP
case:
WHEN INT_LITERAL ARROW statement
expression:
( expression ) |
expression binary_operator expression | NOTOP expression |
INT_LITERAL | REAL_LITERAL | BOOL_LITERAL | IDENTIFIER
binary_operator: ADDOP | MULOP | REMOP | EXPOP | RELOP | ANDOP | OROP
In the above grammar, the red symbols are nonterminals, the blue symbols are terminals and the black punctuation are EBNF metasymbols. The braces denote repetition 0 or more times and the brackets denote optional.
You must rewrite the grammar to eliminate the EBNF brace and bracket metasymbols and to incorporate the significance of parentheses, operator precedence and associativity for all operators. Among arithmetic operators the exponentiation operator has highest precedence following by the multiplying operators and then the adding operators. All relational operators have the same precedence. Among the binary logical operators, and has higher precedence than or. Of the categories of operators, the unary logical operator has highest precedence, the arithmetic operators have next highest precedence, followed by the relational operators and finally the binary logical operators. All operators except the exponentiation operator are left associative. The directives to specify precedence and associativity, such as %prec and %left, may not be used
Your parser should be able to correctly parse any syntactically correct program without any problem.
You must modify the syntactic analyzer to detect and recover from additional syntax errors using the semicolon as the synchronization token. To accomplish detecting additional errors an error production must be added to the function header, another to the variable declaration and a final one to the when clause of the case statement.
Your bison input file should not produce any shift/reduce or reduce/reduce errors. Eliminating them can be difficult so the best strategy is not introduce any. That is best achieved by making small incremental additions to the grammar and ensuring that no addition introduces any such errors.
An example of compilation listing output containing syntax errors is shown below:
1 -- Multiple errors 2
3 function main a integer returns real; Syntax Error, Unexpected INTEGER, expecting ':'
4 b: integer is * 2; Syntax Error, Unexpected MULOP
5 c: real is 6.0;
6 begin
7 if a > c then 8 b 3.0;
Syntax Error, Unexpected REAL_LITERAL, expecting ';'
9 else
10 b = 4.;
11 endif;
12 ;
Syntax Error, Unexpected ';', expecting END
Lexical Errors 0
Syntax Errors 4
Semantic Errors 0
You are to submit two files.
• The first is a .zip file that contains all the source code for the project. The .zip file should contain the flex input file, which should be a .l file, the bison file, which should be a .y file, all .cc and .h files and a makefile that builds the project.
• The second is a Word document (PDF or RTF is also acceptable) that contains the documentation for the project, which should include the following:
a. A discussion of how you approached the project
b. A test plan that includes test cases that you have created indicating what aspects of the program each one is testing and a screen shot of your compiler run on that test case
c. A discussion of lessons learned from the project and any improvements that could be madeReport
a. Approach
The given compiler's syntactic analyzer should be changed to consolidate administrator priority and associativity and kill the EBNF support and section meta symbols, then the grammar must be examined to determine what needs to be changed and added to its blunder creations to the capability header, variable announcement, and proviso of the case proclamation in order to identify and recuperate from different language structure mistakes involving the semicolon as the synchronization token. Next, the grammar must be changed so all operators have operator precedence and associativity. Since directives like %prec and %left cannot be used, non-terminals for various levels of precedence and associativity are added to accomplish this.
b. Test Plan
The modified syntactic analyzer can be evaluated using the following test cases:
Test case 1: Simple function call Input:
function add (x: integer, y: integer) -> integer {result = x + y; } function main(a: integer, b: integer) -> integer { sum = add(a, b); return sum; }
Test 1 Passedsuccessfully.
Explanation: This test case determines whether the syntactic analyzer can correctly parse a straightforward function call.
Test case 2: Variable declaration syntax error Input: function subtract(x: integer, y: integer) -> integer { result = x - y; } function main(a: integer, b integer) -> integer { difference = subtract(a, b); return difference; }
Explanation: This test case determines if the syntactic analyzer can detect the variable declaration's syntax and if an appropriate error message can be displayed.
Test case 3: Operator precedence and associativity Input: function calc(a: integer, b: integer, c: integer) -> integer { result = a * b + c; } function main() -> integer { x = calc(3, 4, 5) + 6 * 7 - 8; return x; }
Explanation: This test case determines whether the syntactic analyzer can correctly prioritize and associate an expression with multiple operators.
Test case 4: Case statement syntax error Input:
function display(x: integer) -> boolean { case x of 0: return false; 1: return true; esac } function main() -> boolean { if display(2) then return true; else return false; fi; }
Explanation: This test case aims to determine whether the syntactic analyzer can detect the case statement's syntax and whether an appropriate error message can be displayed.
b. Lessons Learned
Understanding how to modify and add grammar rules to Bison and incorporate operator precedence and associativity into the grammar was helped by this project. It demonstrated how crucial it is to thoroughly test the program using a variety of test cases to guarantee its correct operation. Mistake creations were composed to identify and recuperate from sentence structure blunders.
To further enhance the skills, it is essential to incorporate more complex features into future projects.
Improvements: It is suggested that in future projects, more in-depth error messages with explanations of the error's nature and possible solutions be provided. Additionally, incorporating additional language features can improve the compiler's efficiency. The code should also be made more modular and reusable.
Attachment:- Compiler Theory and Design.rar