Project 3 Approach
Project 3 Approach
1) Study the skeleton project provided, build it and run it so that you understand how semantic
actions are used to perform the evaluation needed to interpret programs in our language.
2) You should incorporate the new features that are in the skeleton into your version of project 2
and be sure that it builds and runs just as the skeleton did. Then confirm that test cases
test1.txt - test4.txt that were provided as test cases for the skeleton code produce the
correct output. Note that changes are required to both parser.y and scanner.l. You are likely
to get type clash warnings from bison initially. These will be resolved once the entire project is
completed.
3) Make additions as defined by the specification incrementally. Start with adding the code to
evaluate real literals and the hexadecimal integer literals. These changes involve modifications to
scanner.l. There is a predefined C++ function atof that will convert a string containing a real
literal to a double. But you will need to write a function that converts a string containing a
hexadecimal integer to an int. Once you have made these modifications use test5.txt test
them. Shown below is the output that should result when using that test case as input:
Compiled Successfully
Result = 115.57
4) Next, add the code to scanner.l to evaluate character literals that includes both ordinary
character literals and the escape characters. As with the hexadecimal integer literals, you will
need to write a function to perform this conversion. Once you have made this modification use
test6.txt test it. Shown below is the output that should result when using that test case as
input:
Compiled Successfully
Result = 12
5) Next add the necessary semantic actions for each of the new arithmetic operators. Create
individual test cases to test each new operator. Once you have verified that the operators are
evaluated correctly in those cases, use test7.txt, which will test all of them along with their
precedence. Modifications to scanner.l, parser.y, values.h and values.cc are required
Shown below is the output that should result when using that test case as input:
Compiled Successfully
Result = 5
6). Do the relational operators next. As before it is a good idea to create individual test cases to
test each new operator. Finally the two logical operators | and ! testing each with separate test
cases. Once you have added all the new operators use test8.txt to test them. Shown below is
the output that should result when using that test case as input:
Compiled Successfully
Result = 0
7) The if statement would be a good next step. Study how the when statement is implemented
using the conditional expression operator. A similar approach should be used here. Also study
how the case statements are implemented. The elsif statements should be done in a similar
fashion. Use test9.txt to test it. Shown below is the output that should result when using that
test case as input:
Compiled Successfully
Result = 3
To ensure all cases work correctly, modify the value of the variable a, so each case is tested.
8) Test multiple variable declarations next. No modifications should be needed provided you are
using the grammar from project 2. Use test10.txt to confirm that they work correctly. Shown
below is the output that should result when using that test case as input:
Compiled Successfully
Result = 10
9) Next make the changes necessary for programs that contain parameters. The parameters are in
the command line arguments, argv. The prototoype of main is:
Declare a global array, which is dynamically allocated based on argc, at the top of parser.y. In
main convert each command line argument to a double and store it into that global array. The
function atof will do the conversion of a char* to a double. In the semantic action for the
parameter production, retrieve the value of the corresponding parameter from the global array
and store its value in the symbol table.
Use test11.txt and test12.txt to test that change. Shown below is the output that should
result when using both test cases as input:
$ ./compile < test11.txt 6.8
Compiled Successfully
Result = 8.3
Compiled Successfully
Result = 14.9
10) Save the fold statement for last. It is likely the most unfamiliar statement. Be sure to read
the description in the requirements on how such statements are evaluated. Creating a new
function in values.cc to evaluate the fold statement is the best approach.
Use test13.txt to test the right fold statement using a list variable.. Shown below is the output
that should result when using that test case as input:
Compiled Successfully
Result = 2
Use test14.txt to test the left fold statement using a list literal. . Shown below is the output
that should result when using that test case as input:
$ ./compile < test14.txt
Compiled Successfully
Result = 0
11) The final test cases, test15.txt contains all the statements in the language. Shown below is
the output that should result when using that test case as input:
Compiled Successfully
Result = 1
All of the test cases discussed above are included in the attached .zip file.
You are certainly encouraged to create any other test cases that you wish to incorporate in your
test plan. Keep in mind that your compiler should produce the correct output for all syntactically
correct programs, so it is recommended that you choose some different test cases as a part of
your test plan. Your instructor may use a comparable but different set of test cases when testing
your project.