Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC: The Select Case statement for TTCN-3 v2.3.x /a little bit long/

The Select Case statement for TTCN-3 v2.3.x /a little bit long/ 20 Jan 2003 11:50 #6379

Hi,

1. In example in "Agreed New Features for TTCN-3 CORE Language (v2.3.x)" the first two branches have the same case expressions "firstValue". Although "Never more than one of the branches is executed." may sounds as only the first branch will be executed but it is strange and as I expect this construct should not compile correctly in many languages. I suppose it is an editorial error.

select (MyModulePar) // where tsp_MyModulePar is of charstring type
case ("firstValue")
{
log ("The first branch is chosen");
}
case ("firstValue")
{
log ("The second branch is chosen");
}
(...)

2. The BNF for case statement seems to be not perfect.

I did a simplification of BNF for understanding purposes:

SelectCaseConstruct ::= select "("SingleExpression ")"
{
case ( "("SingleExpression {","SingleExpression} ")" | ElseKeyword )
StatementBlock
}+

For the first, it allows sequential use of 'case else':

case else
StatementBlock
case else
StatementBlock
case else
StatementBlock


For the second, it leads to strange code, when 'case else' is the first and the only one branch. The 'case' statement look like non-functional codestuffing done by TS writer. It is also unclear for what values the 'else' branch is an option:

select (MyModulePar) // where tsp_MyModulePar is of charstring type
case else
{
log ("The value of the module parameter MyModulePar is incorrect");
setverdict (inconc); stop
}

For the third, it is not consistent with description: "The statement contains a header part and zero or more branches."
According BNF:
{abc}+ means "1 or more instances of abc" and each 'case' construct body part is defined as:
{ SelectCase }+
which means at least branch should exists.
I suppose the description should be changed to: "The statement contains a header part and one or more branches." instead of modifying BNF.
In case of zero branches allowed the code is ineffective, i.e. nothing is done:

select (MyModulePar) // where tsp_MyModulePar is of charstring type


More correct BNF is I hope:

SelectCaseConstruct ::= select "(" SingleExpression ")"
{
case "(" SingleExpression { ","SingleExpression} ")"
StatementBlock
}+
[
case ElseKeyword
StatementBlock
]


I would also introduce SelectorExpression and CaseExpression to differentiate the two expressions used:

SelectorExpression ::= SingleExpression
CaseExpression ::= SingleExpression

SelectCaseConstruct ::= select "(" SelectorExpression ")"
{
case "(" CaseExpression { "," CaseExpression } ")"
StatementBlock
}+
[
case ElseKeyword
StatementBlock
]


which leads to definitions:

542. BasicStatements ::= Assignment | LogStatement | LoopConstruct | ConditionalConstruct | SelectCaseConstruct
596. SelectCaseConstruct ::= SelectKeyword "(" SelectorExpression ")" SelectCaseBody SelectCaseElseBody
597. SelectKeyword ::= select
598. SelectCaseBody ::= { SelectCase }+
599. SelectCase ::= CaseKeyword "(" CaseExpression { "," CaseExpression } ")" StatementBlock
600. SelectCaseElseBody ::= [ SelectCaseElse ]
601. SelectCaseElse ::= CaseKeyword ElseKeyword StatementBlock
602. CaseKeyword ::= case
603. SelectorExpression ::= SingleExpression
604. CaseExpression ::= SingleExpression

3. What about uniqueness of branche expressions? May the values or lists of values (or even subranges if allowed someday) overlap as in the first example?
It is said that "Never more than one of the branches is executed." what suggest that although "Branches are evaluated in their textual order." but after execution of the first matching branch all other branches should be skipped. For that reason the sentence "The block of statements of an else branch is always executed." seems to be simply invalid.
It should be something like that: "The block of statements of an else branch is always executed if none of the expressions evaluates to the value of the expression in the header."

4. What about defining subranges in branches?
What about other 'case' version taken from Pascal and modified a little bit, also by extending SelectorExpression not only for ordinal types but for other types as e.g. charstring? Inclusion of ranges in CaseExpression not only in ordinal types as in Pascal may also be valid for current version of 'case' statement /TTCN-3 intact version/.

EXAMPLE of proposed 'case' statement:

CaseConstruct ::= case "(" SelectorExpression ")" of "{"
{
CaseExpression { "," CaseExpression} ":"
StatementBlock
}+
[
ElseKeyword
StatementBlock
]
"}"


CaseExpression ::= SingleExpression |
CaseExpressionRange

CaseExpressionRange ::= ... definition here for range of values

I have taken ordinal range from Pascal but TTCN-3 allows range of values of type integer, char, universal char and float (or derivations of these types).
Clause 6.2.2 Ranges should apply when using ranges in 'case' statement.

Instead of CaseExpressionRange we may use already defined RangeDef or even instead of CaseExpression use ValueOrRange. For the second there will be a problem because ValueOrRange uses only constant expressions:

46. ValueOrRange ::= RangeDef | SingleConstExpression

/* STATIC SEMANTICS - RangeDef production shall only be used with integer, char, universal char, charstring, universal charstring or float based types */

/* STATIC SEMANTICS - When subtyping charstring or universal charstring range and values shall not be mixed in the same SubTypeSpec */

47. RangeDef ::= LowerBound ".." UpperBound



In case of ranges the redefinition of equivalency to the if-else statement is needed.
Not only
SelectorExpression == CaseExpression
should be taken into account but also
if (SelectorExpression in CaseExpressionRange)
I have written it quickly using Pascal 'in' operator which does not exists in TTCN-3.


The above modifications of BNF result in examples for a SelectorExpression of charstring type:

case (MyModulePar) of // where tsp_MyModulePar is of charstring type
{
"firstValue": { log ("The first branch is chosen") }
"secondValue": { log ("The second branch is chosen") }
else {
log ("The value of the module parameter MyModulePar is incorrect");
setverdict (inconc); stop
}
}

and for SelectorExpression of integer type where CaseExpression uses ranges:
case (MyModulePar) of // where tsp_MyModulePar is of integer type
{
1: { log ("The first branch is chosen") }
2..5, 10..11, 15: { log ("The second branch is chosen") }
else {
log ("The value of the module parameter MyModulePar is incorrect");
setverdict (inconc); stop
}
}


I have proposed construct a little bit different than Pascal case statement. The advantage of grouping case branches into "{" "}" parenthesis allows also zero branches to be defined in BNF, which will look quite good, because branches are grouped in a body of statement, i.e.:

CaseConstruct ::= case "(" SelectorExpression ")" of "{"
[
{
CaseExpression { "," CaseExpression} ":"
StatementBlock
}+
[
ElseKeyword
StatementBlock
]
]
"}"


I do not see much sense in simplified construct described by BNF as:

CaseConstruct ::= case "(" SelectorExpression ")" of "{"
"}"


but if zero branches will be ever taken into account /for some unknown for me reasons/ then I hope it is nice and readable solution to group also case branches in "{" "}".

BR,
Mariusz Kupiec
The administrator has disabled public write access.
  • Page:
  • 1

FacebookTwitterGoogle BookmarksRedditNewsvineTechnoratiLinkedin