• Keine Ergebnisse gefunden

Implementation of the Dynamic Semantics

Im Dokument Formal Semantics for SDL (Seite 167-170)

Part 5: RSDL Reference Implementation

5.5 Implementation of the Dynamic Semantics

The dynamic semantics is represented by ASM statements. These statements follow the ASM syntax. They are again analysed using the general methodology. This means, there is a lexis for the ASM part, a grammar and also something to be transformed into. There are several parts of the dynamic semantics. The SAM is plainly represented as ASM and is therefore handled like plain ASM. The same is true for the initialisation modules and the data part.

5.5.1 ASM Abstract Grammar

The remaining parts of the ASM grammar are defined here. The structure of expressions as well as the structure of patterns are already defined within Section 5.4.

An ASM specification is first of all a list of definitions. There are several possible kinds of definitions, namely domain definitions, function definitions, rule definitions and program definitions. Moreover, there could be constraints and initial conditions.

asmSpec: Defs(defList);

defList: list definition;

definition:

DomainDecl(mode casestring)

| DomainDef(casestring domain)

| FunctionDecl(mode casestring domain domain)

| FunctionDef(casestring fargList expr)

| RuleDef(casestring fargList defList rule)

| ProgramDef(casestring defList rule) | Constraint(expr)

| InitialCond(expr) ;

fargList: list farg;

farg: FArg(casestring domain);

For domain declarations and function declarations it is possible to give a mode. Not giving a mode amounts to giving an implicit mode. The modes allowed are declared below.

mode: Static() | Controlled() | Shared() | Monitored() | Derived() ;

The next part to define is how domains can be composed. Apart from plain domains we know (power) set domains, list domains, nonempty list domains, tuple domains and union domains. Moreover, a domain could be empty and in some places the domain is not given (e.g. in a function header).

domain: PlainDomain(casestring) | SetDomain(casestring) | SeqDomain(casestring) | SeqPlusDomain(casestring) | TupleDomain(tupleDomainList) | UnionDomain(unionDomainList) | NoDomain()

| UnknownDomain() ;

tupleDomainList: list domain;

unionDomainList: list domain;

The next part describes how rules are composed as already explained in Part 2. Possible constructors are assignments, if-then-else constructs, parallel composition (do-in-parallel), for all constructions, choose constructions, extend constructions, let rules and calls of rule macros.

rule: Assign(casestring argumentList expr)

| IfThenElse(expr rule rule) | Empty()

| Parallel(ruleList)

| ForAll(casestring expr rule)

| Choose(casestring expr rule)

| Extend(domain nameList rule)

| Let(letStatements rule)

| RuleCall(casestring argumentList) ;

ruleList: list rule;

5.5.2 ASM Grammar

The yacc description of the ASM grammar is really straightforward and not shown in detail here. However, this is a good place to show the use of precedences. We had the following precedences in Section 2.1.6.

Precedence Operators

0 ∃, ∀

1 ⇒, ⇔

2 ∨

3 ∧

4 =, ≠, >, <, ≥, ≤, ⊆, ⊂, ∈, ∉

5 ..

6 +, -, ∪, \,

7 *, /, ∩, mod, rem, ×

8 →

The are represented by the following yacc precedences.

%nonassoc ':' /* for quantified */ '|'

%left IMPLIES IFF

%left OR

%left AND

%nonassoc '=' NEQ '>' '<' GEQ LEQ SUBSETEQ SUBSET ELEMENTOF NOTIN

%nonassoc DOTDOT

%left '+' '-' UNION SETMINUS CONCAT

%left '*' '/' INTERSECT MOD REM TIMES

%nonassoc ARROW

%nonassoc UMINUS

The expressions themselves need not care about conflicts, because the precedences will solve the shift-reduce-conflicts. Please note the use of the %prec for giving a precedence to unary prefix operators in the following partial yacc description of ASM expressions.

/**************** expressions ****************/

formula: primary

| formula '=' formula

{ $$ = BinOp(mkcasestring("="),$1,$3); }

| formula NEQ formula

{ $$ = BinOp(mkcasestring("!="),$1,$3); }

| formula AND formula

{ $$ = BinOp(mkcasestring("&"),$1,$3); }

| formula OR formula

{ $$ = BinOp(mkcasestring("v"),$1,$3); }

| formula IMPLIES formula

{ $$ = BinOp(mkcasestring("->"),$1,$3); }

| formula IFF formula

{ $$ = BinOp(mkcasestring("<->"),$1,$3); }

| NOT formula %prec UMINUS

{ $$ = UnOp(mkcasestring("!"),$2); }

| IF formula THEN formula elsepart { $$ = IfExpr($2,$4,$6); } ...

;

5.5.3 ASM Lexis

For the ASM lexis, the different kinds of identifiers have to be distinguished. In the text this is done using appropriate character styles. However, these styles get lost when generating plain text. Therefore a prefix is generated for the character styles in order to identify them correctly (see also Section 5.2). This is used when lexically analysing the text: after finding such a prefix, lex enters a special start condition for this name kind and accepts then the appropriate name. This is exemplified in the following extract of the ASM lex file.

NAME [A-Za-z_][A-Za-z0-9_]*

PNAME [-A-Za-z0-9_]+

SYNNAME \<[a-z][a-z0-9 ]+\>

...

%x MKN SN KW AN RN DN FN PN

%%

...

mk-d-/{NAME} { BEGIN(MKN); } s-d-/{PNAME} { BEGIN(SN); } s-kw-/{NAME} { BEGIN(SN); } s-/{SYNNAME} { BEGIN(SN); } kw-/{NAME} { BEGIN(KW); } d-/{PNAME} { BEGIN(DN); } p-/{PNAME} { BEGIN(PN); } f-/{PNAME} { BEGIN(FN); } r-/{NAME} { BEGIN(RN); } a-/{NAME} { BEGIN(AN); } ...

<MKN>{PNAME} { BEGIN(0); MakeCASE; return token(MKNAME); }

<SN>{PNAME} { BEGIN(0); MakeCASE; return token(SNAME); }

<SN>{SYNNAME} { BEGIN(0); MakeCASE; return token(SNAME); }

<KW>{NAME} { BEGIN(0); MakeCASE; return token(KEYWORD); }

<DN>{PNAME} { BEGIN(0); MakeCASE; return token(DOMAINNAME); }

<PN>{PNAME} { BEGIN(0); MakeCASE; return token(PROGRAMNAME); }

<FN>{PNAME} { BEGIN(0); MakeCASE; return token(FUNCTIONNAME); }

<RN>{NAME} { BEGIN(0); MakeCASE; return token(RULENAME); }

<AN>{NAME} { BEGIN(0); MakeCASE; return token(ASMNAME); }

5.5.4 Generation of ASM for the ASM workbench

The input format for the ASM workbench is ASM-SL. This is almost the same as the ASM used in Part 4, but there are some problems as already stated in Section 2.3.5.2.

Definition Order

The definition order is implemented using the cross-reference method as already used for the token generation.

Every use of a defined entity is linked to its definition. Whenever a new definition should be generated, it is first checked if its constituent parts were already generated. If not, they are generated before. This method is not applicable if there are cycles within the definitions, but this is not the case for the RSDL formal semantics.

Strong Typing

Most of the semantics definitions are already strongly typed. However, especially for the syntax definitions we use heavily union types. Such types are not supported by the workbench. The solution for this problem is the same as the solution for the similar problem in kimwitu: We regard all syntax definitions as belonging to only one type with many constructors. This avoids type-checking in this case.

Predefined Operators and Types

For all predefined operators and domains that are not present in the workbench we generate the corresponding functions in the workbench. Then the mapping of functions to their workbench representation is almost one-to-one.

Agents

It is a strong restriction that the workbench does not support ASM agents. However, there is a way to emulate at least an interleaving variant of agents, which might be enough for test reasons. This emulation is defined as follows.

First we introduce an unspecified domain AGENT. freetype Agent == { generator_Agent : INT }

The function Self is declared to be external (monitored).

external function Self: Agent

This means that whenever this function is to be evaluated, the user is asked about its current value. That way it is possible to choose the agent to be activated next.

The domain PROGRAM is defined using identifiers for all the available programs, e.g.

freetype Program == { prog1_id, prog2_id, prog3_id }

The function program is a usual controlled ASM function.

dynamic function program: Agent -> Program

It remains to compose the main program for all ASM agents as follows.

transition MainProgram ==

if program(Self) = prog1_id then Prog1 endif if program(Self) = prog2_id then Prog2 endif if program(Self) = prog3_id then Prog3 endif

Shared Functions

Shared functions are implemented as special controlled functions. However, a new agent Env is introduced with a program modifying the shared function. This way a shared function is implemented making the environment an explicit agent, in accordance with the ASM definition.

Extend

The ASM workbench does not support the extend-Primitive. For single extends this can be mapped to choosing an element that is not yet used. However, there is no way known to emulate extend when it is embedded into a do forall loop. This problem is serious. However, for the example we only have single extends. The next version of the workbench is supposed to support extends.

Im Dokument Formal Semantics for SDL (Seite 167-170)