Generating Software from Specifications WS 2013/14 - File QualNames.fw
@=~
~p maximum_input_line_length = infinity
This file contains the specification of a processor
for structured types and qualified names.
The following tasks are to be solved:
1. Read and understand name analysis and type analysis as
specified below. The specification is NOT explained.
Insert explanations according to your understanding.
2. A processor can be generated from this specification.
However, it does not work as expected. Compare its results
at least for the given examples to the expected results.
The author of this specification has failed to specify
necessary preconditions explicily for several computations.
Add those necessary dependences, and test the corrected analysis.
The following file contains correct input for the processor.
Under Algol-like scope rules the order of declarations and uses
of identifiers is irrelevant:
~O~<QualNames.ok~>~{~-
{
l.a = 42; l.next = l;
b.a = l.next.next.a;
b.left = nil; b.right = nil;
list l;
btree b;
type list = (int a; list next;)
type btree = (int a; btree left; btree right;)
}
~}
The following file contains erroneous input for the processor:
~O~<QualNames.err~>~{~-
{
type list = (int a; list next;)
list l;
l.a = nil;
l.next = 42;
v.a = 42;
l.next = b;
type btree = (int a; btree left; btree right;)
btree b;
int b;
type xlist = (int a; list next; list a;)
}
~}
The following file contains the messages expected for the above example
~O~<QualNames.msg~>~{~-
"QualNames.err", line 9:9 ERROR: multiply defined: b
"QualNames.err", line 10:7 ERROR: multiply defined: b
"QualNames.err", line 11:21 ERROR: multiply defined: a
"QualNames.err", line 11:40 ERROR: multiply defined: a
"QualNames.err", line 4:3 ERROR: wrong type in assignment
"QualNames.err", line 5:3 ERROR: wrong type in assignment
"QualNames.err", line 6:3 ERROR: identifier is not defined: v
"QualNames.err", line 6:5 ERROR: identifier is not defined: a
"QualNames.err", line 7:3 ERROR: wrong type in assignment
~}
The following file specifies the concrete syntax:
~O~<QualNames.con~>~{
Program: '{' Constructs '}'.
Constructs: Constructs Construct / Construct.
Construct: TypeDecl.
Construct: VariableDecl.
Construct: Assignment.
TypeDecl: 'type' TypeDefName '=' Record.
TypeDefName: Identifier.
Record: '(' Fields ')'.
Fields: Fields Field / Field.
Field: Type FieldDefName ';'.
FieldDefName: Identifier.
Type: 'int' / TypeUseName.
TypeUseName: Identifier.
VariableDecl: Type VarDefName ';'.
VarDefName: Identifier.
QualifiedName: VarUseName / QualifiedName '.' FieldUseName.
VarUseName: Identifier.
FieldUseName: Identifier.
Assignment: QualifiedName '=' Expression ';'.
Expression: QualifiedName / Number / 'nil'.
~}
The following file specifies the non-literal tokens:
~O~<QualNames.gla~>~{
Identifier: C_IDENTIFIER
Number: C_INTEGER
C_COMMENT
~}
Basic Name Analysis
-------------------
The following file instantiates the basic name analysis module
from Eli's specification modules which establishes
bindings according to Algol-like scope rules:
~O~<Name.specs~>~{
$/Name/AlgScope.gnrc:inst
$/Tech/Strings.specs
~}
EXPLAIN:
~O~<IdentOcc.lido~>~{
CLASS SYMBOL IdentOcc: Sym: int;
CLASS SYMBOL IdentOcc COMPUTE
SYNT.Sym = TERM;
END;
SYMBOL Program INHERITS RootScope END;
SYMBOL Record INHERITS RangeScope END;
SYMBOL TypeDefName INHERITS IdentOcc, IdDefScope END;
SYMBOL VarDefName INHERITS IdentOcc, IdDefScope END;
SYMBOL FieldDefName INHERITS IdentOcc, IdDefScope END;
SYMBOL TypeUseName INHERITS IdentOcc, IdUseEnv, ChkIdUse END;
SYMBOL VarUseName INHERITS IdentOcc, IdUseEnv, ChkIdUse END;
~}
EXPLAIN:
~O~<UniqueDefs.pdl~>~{~-
Defs: int;
~}
~O~<UniqueDefs.lido~>~{~-
CLASS SYMBOL UniqueDefName COMPUTE
SYNT.GotDefs = SetDefs (THIS.Key, 1, 2);
IF (GT (GetDefs (THIS.Key, 0), 1),
message (ERROR, CatStrStr ("multiply defined: ", StringTable (THIS.Sym)),
0, COORDREF));
END;
SYMBOL TypeDefName INHERITS UniqueDefName END;
SYMBOL VarDefName INHERITS UniqueDefName END;
SYMBOL FieldDefName INHERITS UniqueDefName END;
~}
Name Analysis for Qualified Names
---------------------------------
EXPLAIN:
~O~<ScopeProperty.pdl~>~{~-
Scope: Environment; "envmod.h"
~}
~O~<ScopeProperty.lido~>~{~-
ATTR Env: Environment;
RULE: TypeDecl ::= 'type' TypeDefName '=' Record COMPUTE
TypeDefName.Env = Record.Env;
END;
SYMBOL TypeDefName COMPUTE
SYNT.GotScope = ResetScope (THIS.Key, THIS.Env);
END;
RULE: QualifiedName ::= QualifiedName '.' FieldUseName COMPUTE
FieldUseName.Env = GetScope (QualifiedName[2].Type, NoEnv);
IF (EQ (QualifiedName[2].Type, intType),
message (ERROR, "wrong type of qualifier", 0, COORDREF));
END;
SYMBOL FieldUseName INHERITS IdentOcc, ChkIdUse COMPUTE
THIS.Key = KeyInScope (THIS.Env, THIS.Sym);
END;
~}
Type Analysis
-------------
EXPLAIN:
~O~<TypeProperty.pdl~>~{~-
Type: DefTableKey;
intType;
nilType;
~}
~O~<TypeProperty.lido~>~{~-
ATTR Type: DefTableKey;
RULE: Field ::= Type FieldDefName ';' COMPUTE
FieldDefName.Type = Type.Type;
END;
RULE: VariableDecl ::= Type VarDefName ';' COMPUTE
VarDefName.Type = Type.Type;
END;
RULE: Type ::= 'int' COMPUTE
Type.Type = intType;
END;
RULE: Type ::= TypeUseName COMPUTE
Type.Type = TypeUseName.Key;
END;
SYMBOL VarDefName COMPUTE
SYNT.GotType = ResetType (THIS.Key, THIS.Type);
END;
SYMBOL FieldDefName COMPUTE
SYNT.GotType = ResetType (THIS.Key, THIS.Type);
END;
SYMBOL VarUseName COMPUTE
SYNT.Type = GetType (THIS.Key, NoKey);
END;
SYMBOL FieldUseName COMPUTE
SYNT.Type = GetType (THIS.Key, NoKey);
END;
RULE: QualifiedName ::= VarUseName COMPUTE
QualifiedName.Type = VarUseName.Type;
END;
RULE: QualifiedName ::= QualifiedName '.' FieldUseName COMPUTE
QualifiedName[1].Type = FieldUseName.Type;
END;
RULE: Assignment ::= QualifiedName '=' Expression ';' COMPUTE
IF (
NOT (OR (OR (OR (EQ (QualifiedName.Type, NoKey),
EQ (Expression.Type, NoKey)),
EQ (QualifiedName.Type, Expression.Type)),
AND (EQ (Expression.Type, nilType),
NE (QualifiedName.Type, intType)))),
message (ERROR, "wrong type in assignment", 0, COORDREF));
END;
RULE: Expression ::= QualifiedName COMPUTE
Expression.Type = QualifiedName.Type;
END;
RULE: Expression ::= Number COMPUTE
Expression.Type = intType;
END;
RULE: Expression ::= 'nil' COMPUTE
Expression.Type = nilType;
END;
~}
Generiert mit Camelot | Probleme mit Camelot? | Geändert am: 18.12.2013


