Generating Software from Specifications WS 2013/14 - File StatementsSol.fw
@=~ ~p maximum_input_line_length = infinity This file contains the specification of a processor for sequences of expressions. The following file contains correct input for the processor: ~O~<Statements.ok~>~{~- { int i; i = 5; while (i) i = 0; { int x; x = 21; } int j; if (j) j = 1; { int k; k = i; { k = 42; } } { i = 42; } } ~} The following file contains erroneous input for the processor: ~O~<Statements.err~>~{ ~} The following file specifies the concrete syntax: ~O~<Statements.con~>~{ Program: Block. Block: '{' Constructs '}'. Constructs: Constructs Construct / Construct. Construct: Declaration. Construct: Statement. Declaration: 'int' VarNameDef ';'. VarNameDef: Identifier. Statement: VarNameUse '=' Expression ';' / 'while' '(' Expression ')' Statement / 'if' '(' Expression ')' Statement / Block. Expression: VarNameUse / Number . VarNameUse: Identifier. ~} The following file specifies the non-literal tokens: ~O~<Statements.gla~>~{ Identifier: C_IDENTIFIER Number: C_INTEGER C_COMMENT ~} The following file specifies the abstract sxntax. It is recommended not to add computations to these rule instances; rather copy rules to other lido fragments and add computations there. ~O~<Abstract.lido~>~{ RULE: Program ::= Block COMPUTE END; RULE: Block ::= '{' Constructs '}' COMPUTE END; RULE: Constructs ::= Constructs Construct COMPUTE END; RULE: Constructs ::= Construct COMPUTE END; RULE: Construct ::= Declaration COMPUTE END; RULE: Construct ::= Statement COMPUTE END; RULE: Declaration ::= 'int' VarNameDef ';' COMPUTE END; RULE: VarNameDef ::= Identifier COMPUTE END; RULE: Statement ::= VarNameUse '=' Expression ';' COMPUTE END; RULE: Statement ::= 'while' '(' Expression ')' Statement COMPUTE END; RULE: Statement ::= 'if' '(' Expression ')' Statement COMPUTE END; RULE: Statement ::= Block COMPUTE END; RULE: Expression ::= VarNameUse COMPUTE END; RULE: Expression ::= Number COMPUTE END; RULE: VarNameUse ::= Identifier COMPUTE END; ~} The solutions of subtasks are to be inserted into the following macros: Subtask-1: Unique numbers for statements in any order: A count function is implemented in the C module at the end of this file. ~O~<Subtask-1.nolido~>~{ SYMBOL Statement: num: int; SYMBOL Statement COMPUTE SYNT.num = count (); printf ("statement %d in line %d\n", SYNT.num, LINE); END; ~} The output for Statements.ok is ~O~<Statements.out1~>~{~- statement 0 in line 3 statement 1 in line 4 statement 2 in line 4 statement 3 in line 5 statement 4 in line 5 statement 5 in line 7 statement 6 in line 7 statement 7 in line 8 statement 8 in line 9 statement 9 in line 9 statement 10 in line 8 statement 11 in line 11 statement 12 in line 11 ~} Subtask-2: Deactivate the previous solution. Unique numbers for statements in left-to-right order computed by a CHAIN: HEAD.cnt is used in SYMBOL context to address the chain at the left-most nonterminal of the right-hand side of the rule: ~O~<Subtask-2.nolido~>~{ CHAIN cnt: int; SYMBOL Program COMPUTE CHAINSTART HEAD.cnt = 0; END; SYMBOL Statement: num: int; SYMBOL Statement COMPUTE SYNT.num = THIS.cnt; HEAD.cnt = ADD (SYNT.num, 1); printf ("statement %d in line %d\n", SYNT.num, LINE); END; ~} The output for Statements.ok is the same as in subtask 1. Subtask-3: Deactivate the previous solution. Count occurrences of VarNameUse: ~O~<Subtask-3.lido~>~{ SYMBOL Program COMPUTE printf ("Number of occurrences of VarNameUse : %d\n", CONSTITUENTS VarNameUse.one WITH (int, ADD, IDENTICAL, ZERO)); END; SYMBOL VarNameUse: one:int; SYMBOL VarNameUse COMPUTE SYNT.one = 1; END; ~} The output for Statements.ok is ~O~<Statements.out3~>~{~- Number of occurrences of VarNameUse : 10 ~} Subtask-4: Compute nesting depth of blocks and output in the context of a defining occurrence of a variable the depth of the surrounding block: ~O~<Subtask-4.lido~>~{ SYMBOL Block: depth: int; RULE: Program ::= Block COMPUTE Block.depth = 0; END; SYMBOL Block COMPUTE INH.depth = ADD (INCLUDING Block.depth, 1); END; SYMBOL VarNameDef COMPUTE printf ("variable %s defined in line %d on block nesting level %d\n", StringTable (TERM), LINE, INCLUDING Block.depth); END; ~} The output for Statements.ok is ~O~<Statements.out4~>~{~- variable i defined in line 2 on block nesting level 0 variable x defined in line 5 on block nesting level 1 variable j defined in line 6 on block nesting level 0 variable k defined in line 8 on block nesting level 1 Number of occurrences of VarNameUse : 10 ~} Subtask-5: Produce output first at all definig occurrences of variables, then at all applied occurrences: ~O~<Subtask-5.lido~>~{ SYMBOL Program COMPUTE SYNT.done = CONSTITUENTS VarNameDef.done; END; SYMBOL VarNameDef COMPUTE SYNT.done = printf ("%s defined in line %d\n", StringTable (TERM), LINE); END; SYMBOL VarNameUse COMPUTE printf ("%s used in line %d\n", StringTable (TERM), LINE) <- INCLUDING Program.done; END; ~} The output for Statements.ok is ~O~<Statements.out5~>~{~- i defined in line 2 variable i defined in line 2 on block nesting level 0 x defined in line 5 variable x defined in line 5 on block nesting level 1 j defined in line 6 variable j defined in line 6 on block nesting level 0 k defined in line 8 variable k defined in line 8 on block nesting level 1 i used in line 3 i used in line 4 i used in line 4 x used in line 5 j used in line 7 j used in line 7 k used in line 8 i used in line 8 k used in line 9 i used in line 11 Number of occurrences of VarNameUse : 10 ~} The following files makes a module available that defines the datatype CharPtr for strings and functions for string concatenation: ~O~<Post.specs~>~{ $/Tech/Strings.specs ~} The following three files implements some C functions which may be used in the generated processor: ~O~<Statements.HEAD.phi~>==~{ #include "Statements.h" ~} ~O~<Statements.h~>==~{ extern int count (); ~} ~O~<Statements.c~>==~{ #include <stdio.h> #include <string.h> #include "Statements.h" int cnt = 0; int count () { return cnt++;} ~}
Generiert mit Camelot | Probleme mit Camelot? | Geändert am: 24.11.2013