Universität Paderborn - Home Universität Paderborn
Die Universität der Informationsgesellschaft

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