The grammar is given in the last section of this document.
dangling.in[1]==C defines that the else belongs to the inner if (i<10). The programmer might have intended to associate it to the outer if (i>=0). Hence the style guide requires to avoid such situations, e.g. by additional curly braces. Your analysis tool shall emit a warning if such a dangling else occurs:This macro is attached to a product file.{ int i, z; i = read(); if (i>=0) if (i<10) z = 5+i; else z = 0; print (z); }
dangling.out[2]==The following questions may help to focus your attention on the significant aspects of this problem:This macro is attached to a product file."dangling.in", line 5:3 WARNING: beware of dangling else!
1. Which are the adjacent tree contexts that will cause the warning?
2. In which context is the warning issued, and what is its precondition?
1.1 Solution
Fill in the description of your solution here.
dangling else computations[3]==This macro is invoked in definition 4./* Fill in your Lido specification here. */
2. Reconsider your solution when you have learned about
SYMBOL computations. How can you use them to simplify
your solution?
1.3 Output files
dangling.lido[4]==This macro is attached to a product file.dangling else computations[3]
You decide to suggest to your manager that this requirement should be removed, because today's C compiler automatically translate sparse switch cases into cascades of conditional jumps.
In order to strengthen your argument by figures, your analysis tool will compute the number of the case labels in a switch statement and the range of their values.
For a program like
switch.in[5]==the tool will produce the output:This macro is attached to a product file.{ int i, z; i = read(); switch (i) { case 0: z = 1; break; case 99: case 100: z = 2; break; default: z = 0; } print (z); }
switch.out[6]==The following questions may help to focus your attention on the significant aspects of this problem:This macro is attached to a product file.switch in line 3 has 3 case labels in the range 0 to 100
1. How do you access the case label values from the switch statement context?
2. Which functions do you need to combine the values?
3. How do you handle nested switch statements?
2.1 Solution
Fill in the description of your solution here.
Switch case label computation[7]==This macro is invoked in definition 9./* Fill in your Lido specification here. */
Cpp macro definitions[8]==This macro is invoked in definition 10./* Fill in your cpp macros here. */
2. Explain why the f0 functions are needed (look at the grammar).
3. Can you make any assumption about the order in which the functions are called?
4. Reconsider your solution when you have learned about
SYMBOL computations. How can you use them to simplify
your solution?
2.3 Output files
switch.lido[9]==This macro is attached to a product file.Switch case label computation[7]
switch.head[10]==This macro is attached to a product file.Cpp macro definitions[8]
For example the following program
loops.in[11]==shall produce output likeThis macro is attached to a product file.{ int i, k, j, s; s = 0; for (i=1; i<10; i=i+1) for (j=i; j<10; j=j+1) s = s + j; for (k=0; k<5; k=k+2) s = s - k; print (s); }
loops.out[12]==The following questions may help to focus your attention on the significant aspects of this problem:This macro is attached to a product file.for loop number 1 in line 4 has depth 1 for loop number 2 in line 5 has depth 2 for loop number 3 in line 7 has depth 1
What is the computational pattern for left-to-right enumeration? In which context and with which value do you start the enumeration?
What is the computational pattern for nesting depth?
How is the recursive nesting being founded?
3.1 Solution
Decompose your solution into 3 parts:
Loop enumeration, loop nesting depth, and printing the information.
Fill in the description of your loop enumeration solution here.
Loop enumeration[13]==Fill in the description of your loop nesting depth solution here.This macro is invoked in definition 16./* Fill in your Lido specification here. */
Loop nesting depth[14]==Fill in the description of your printing solution here.This macro is invoked in definition 16./* Fill in your Lido specification here. */
Loop information[15]==This macro is invoked in definition 16./* Fill in your Lido specification here. */
loops.lido[16]==This macro is attached to a product file.Loop enumeration[13] Loop nesting depth[14] Loop information[15]
You decide to suggest to your manager that the programmers should use lint before they release their programs. Inspite of that you try to let your analysis tool check these requirements, and compare the results with those of lint.
For the program
vars.in[17]==your analysis tool shall produce messages likeThis macro is attached to a product file.{ int a, b, c, d, e; int f; int a; a = read (x); b = a + c; c = a * c; e = d + a; print (e); }
vars.out[18]==The following questions may help to focus your attention on the significant aspects of this problem:This macro is attached to a product file."vars.in", line 5:13 ERROR: variable is not defined "vars.in", line 1:7 ERROR: variable is multiply defined "vars.in", line 2:7 WARNING: variable is never used "vars.in", line 3:7 ERROR: variable is multiply defined "vars.in", line 5:13 WARNING: variable is used before set "vars.in", line 6:11 WARNING: variable is used before set "vars.in", line 7:11 WARNING: variable is used before set "vars.in", line 8:7 WARNING: variable is used before set
1. Decompose the whole task into subproblems: a name analysis task and several single tasks which need to compute a property of variables each. Solve the tasks separately.
2. How do you solve the name analysis task?
3. For each property subtask answer the following questions: What are the property values? In which contexts is the property to be set? In which contexts is the property to be read? What is the sequencing relation between setting and reading the property.
4. Discuss the write before read subproblem for the
statement c = a * c;.
4.1 Solution
Name Analysis:
Fill in the description of your solution here.
Name analysis module instance[19]==This macro is invoked in definition 29./* Fill in your module instantiation here. */
Name analysis module roles[20]==Check Variable Definitions:This macro is invoked in definition 30./* Fill in your Lido specification here. */
Fill in the description of your solution here.
Undefined variables[21]==This macro is invoked in definition 30./* Fill in your Lido specification here. */
Multiple definitions property[22]==This macro is invoked in definition 31./* Fill in your PDL specification here. */
Definition state macros[23]==This macro is invoked in definition 32./* Fill in cpp macro definitions here */
Multiple definitions[24]==Used Variables:This macro is invoked in definition 30./* Fill in your Lido specification here. */
Fill in the description of your solution here.
Used property[25]==This macro is invoked in definition 31./* Fill in your PDL specification here. */
Uses of variables[26]==Read before Write:This macro is invoked in definition 30./* Fill in your Lido specification here. */
Fill in the description of your solution here.
Is written property[27]==This macro is invoked in definition 31./* Fill in your PDL specification here. */
Variable access computation[28]==This macro is invoked in definition 30./* Fill in your Lido specification here. */
2. Do you know a library module that supports the check for multiple definitions?
3. How did you solve the problem that a variable use in the
right-hand side of an assignment has to be considered
before the left-hand side? Do you see alternative solutions?
4.3 Output files
vars.specs[29]==This macro is attached to a product file.Name analysis module instance[19]
vars.lido[30]==This macro is attached to a product file.Name analysis module roles[20] Undefined variables[21] Multiple definitions[24] Uses of variables[26] Variable access computation[28]
vars.pdl[31]==This macro is attached to a product file.Multiple definitions property[22] Used property[25] Is written property[27]
vars.head[32]==This macro is attached to a product file.Definition state macros[23]
A program is a block that consists of possibly empty sequences of declarations and statements.
Program[33]==A declaration defines one or more variables of type int. Each declaration is terminated by a ';'. The symbol VarDecl distinguishes this defining occurrence of Ident from other occurrences. Several identifiers are separated by ','.This macro is invoked in definition 44.Prog ::= Block . Block ::= '{' Decl* Stmt* '}' .
Declarations[34]==There are several forms of statements: assignments, conditionals, switch statements, break statements, for loops, blocks, and expression statements. Statements, except blocks and switch statements are terminated by ';'.This macro is invoked in definition 44.Decl ::= 'int' VarDecls ';' . VarDecls::= VarDecl // ',' . VarDecl ::= Ident .
Statements[35]==An assignment has the usual notation. The Assign symbol is introduced, because for loops contain assignments without terminating ';'.This macro is invoked in definition 44.Stmt ::= Block / Expr ';' / 'break' ';' / Assign ';' / ForStmt .
Assignments[36]==for statements consist of the initial assignment, the iteration condition, the assignment executed after each iteration, and the iterated statement.This macro is invoked in definition 44.Assign ::= VarUse '=' Expr . VarUse ::= Ident .
For loop[37]==The else branch of an if statement is optional. The dangling else ambiguity is resolved such that an else branch is bound to the innermost if statement. The $'else' modification instructs the parser generator not to reduce that production if an else token follows.This macro is invoked in definition 44.ForStmt ::= 'for' '(' Assign ';' Expr ';' Assign ')' Stmt .
If statement[38]==Switch statements have the same structure as in C.This macro is invoked in definition 44.Stmt ::= 'if' '(' Expr ')' Stmt $'else' . Stmt ::= 'if' '(' Expr ')' Stmt 'else' Stmt .
Switch statement[39]==The following expression syntax specifies precedence and associativity of operators: MulOpr have highest precedence, CmpOpr have lowest precedence. AddOpr and MulOpr are left-associative, and CmpOpr are not associative.This macro is invoked in definition 44.Stmt ::= SwStmt . SwStmt ::= 'switch' '(' Expr ')' '{' Case* '}' . Case ::= CaseLab Stmt* . CaseLab ::= 'case' CaseLit ':' . CaseLab ::= 'default' ':' . CaseLit ::= Number .
Expressions[40]==The precedence and associativity rules are only relevant for the construction of the tree. The then constructed tree need not distinguish between Expr, Sum, Fact, and Operand. They are all represented by an Expr node. Similarly all operators are represented by an Opr node in the tree:This macro is invoked in definition 44.Expr ::= Sum CmpOpr Sum / Sum . Sum ::= Sum AddOpr Fact / Fact . Fact ::= Fact MulOpr Operand / Operand . CmpOpr ::= '<' / '>' / '==' / '!=' / '<=' / '>=' . AddOpr ::= '+' / '-' . MulOpr ::= '*' / '/' . Operand ::= '(' Expr ')' .
Equivalent nonterminals[41]==Operands are integral numbers, identifiers that denote access of a variable value, or calls of predefined functions. The latter may have an arbitrary number of arguments.This macro is invoked in definition 45.Expr ::= Sum Fact Operand . Opr ::= CmpOpr AddOpr MulOpr .
Operands[42]==The notation for numbers, identifiers, and comments are specified as in C using canned token specifications:This macro is invoked in definition 44.Operand ::= Number . Operand ::= VarUse . Operand ::= Ident '(' Params ')' . Params ::= . Params ::= Expr // ',' .
Tokens[43]==This macro is invoked in definition 46.Number: C_INTEGER Ident: C_IDENTIFIER C_COMMENT
tree.con[44]==This macro is attached to a product file.Program[33] Declarations[34] Statements[35] Assignments[36] For loop[37] If statement[38] Switch statement[39] Expressions[40] Operands[42]
tree.sym[45]==This macro is attached to a product file.Equivalent nonterminals[41]
tree.gla[46]==This macro is attached to a product file.Tokens[43]