Skip to content

Commit

Permalink
Drop "else if" and "else" clauses from braced conditionals
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelhkay committed Jan 18, 2025
1 parent 972ce90 commit 46afc6d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 74 deletions.
14 changes: 7 additions & 7 deletions specifications/grammar-40/xpath-grammar.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,7 @@ VersionDecl ::= "xquery" (("encoding" StringLiteral) | ("version" StringLiteral
<g:string>)</g:string>
<g:choice>
<g:ref name="UnbracedActions"/>
<g:ref name="BracedActions"/>
<g:ref name="BracedAction"/>
</g:choice>
</g:production>

Expand All @@ -1344,21 +1344,21 @@ VersionDecl ::= "xquery" (("encoding" StringLiteral) | ("version" StringLiteral
<g:ref name="ExprSingle"/>
</g:production>

<g:production name="BracedActions">
<g:ref name="ThenAction"/>
<g:zeroOrMore>
<g:production name="BracedAction">
<g:ref name="EnclosedExpr"/>
<!--<g:zeroOrMore>
<g:ref name="ElseIfAction"/>
</g:zeroOrMore>
<g:optional>
<g:ref name="ElseAction"/>
</g:optional>
</g:optional>-->
</g:production>

<g:production name="ThenAction">
<g:ref name="EnclosedExpr"/>
</g:production>

<g:production name="ElseIfAction">
<!--<g:production name="ElseIfAction">
<g:string>else</g:string>
<g:string>if</g:string>
<g:string>(</g:string>
Expand All @@ -1370,7 +1370,7 @@ VersionDecl ::= "xquery" (("encoding" StringLiteral) | ("version" StringLiteral
<g:production name="ElseAction">
<g:string>else</g:string>
<g:ref name="EnclosedExpr"/>
</g:production>
</g:production>-->

<!-- [ start TryCatchExpr -->

Expand Down
97 changes: 30 additions & 67 deletions specifications/xquery-40/src/expressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20686,70 +20686,40 @@ return $map?[?key ge 2]</eg>
<head/>
<prodrecap id="IfExpr" ref="IfExpr"/>
<prodrecap id="UnbracedActions" ref="UnbracedActions"/>
<prodrecap id="BracedActions" ref="BracedActions"/>
<prodrecap id="ThenAction" ref="ThenAction"/>
<prodrecap id="BracedAction" ref="BracedAction"/>
<!--<prodrecap id="ThenAction" ref="ThenAction"/>
<prodrecap id="ElseIfAction" ref="ElseIfAction"/>
<prodrecap id="ElseAction" ref="ElseAction"/>
<prodrecap id="ElseAction" ref="ElseAction"/>-->
<prodrecap ref="EnclosedExpr"/>
</scrap>

<p diff="chg" at="2023-01-17">There are two formats with essentially the same semantics.</p>
<ulist diff="chg" at="2023-01-10">
<item><p>The unbraced expression <code>if (C) then T else E</code> is equivalent to
the braced expression <code>if (C) { T } else { E }</code>.</p></item>
<item diff="del" at="2023-01-17"><p>The ternary expression <code>C ?? T !! E</code> is equivalent to the
braced expression <code>if (C) { T } else { E }</code>.</p>
<note><p>The ternary operator syntax is borrowed from Perl6.</p></note>
</item>
<item><p>The value <var>V</var> of a conditional expression using the
braced format is obtained by applying the following rules in order, finishing
as soon as <var>V</var> has a value:</p>
<p>The braced expression <code>if (<var>C</var>) then {<var>T</var>}</code> is equivalent to the
unbraced expression <code>if (<var>C</var>) then <var>T</var> else ()</code>.</p>

<p>The value <var>V</var> of a conditional expression in the form <code>if (<var>C</var>) then <var>T</var>
else <var>E</var></code> is obtained as follows:</p>


<olist>
<item><p>Let <var>C</var> be the <termref
def="dt-ebv"
>effective boolean value</termref> of the test expression, as defined in <specref
<item><p>Let <var>B</var> be the <termref
def="dt-ebv">effective boolean value</termref> of the test expression
<var>C</var>, as defined in <specref
ref="id-ebv"/>.</p>
</item>
<item><p>If <var>C</var> is true, <var>V</var> is the
value of the <nt def="EnclosedExpr">EnclosedExpr</nt> in the <nt def="ThenAction">ThenAction</nt>.</p>
</item>
<item><p>The <nt def="ElseIfAction">ElseIfActions</nt> (if any) are processed in order as follows:</p>
<olist>
<item><p>Let <var>C'</var> be the <termref
def="dt-ebv"
>effective boolean value</termref> of the test expression, as defined in <specref
ref="id-ebv"/>.</p></item>
<item><p>If <var>C'</var> is true, <var>V</var> is the
value of the <nt def="EnclosedExpr">EnclosedExpr</nt> in the <nt def="ElseIfAction">ElseIfAction</nt>

</p>
</item>
</olist>
</item>
<item>
<p>If there is an <nt def="ElseAction">ElseAction</nt>, then <var>V</var>
is the value of its <nt def="EnclosedExpr">EnclosedExpr</nt>.</p>
<item><p>If <var>B</var> is true, <var>V</var> is the
result of evaluating <var>T</var>.</p>
</item>
<item>
<p><var>V</var> is the empty sequence.</p>
<item><p>Otherwise, <var>V</var> is the
result of evaluating <var>E</var>.</p>
</item>
</olist>

</item>
</olist>


</ulist>



<p diff="del" at="2023-01-10">Whichever format is used, the first step in processing a conditional expression is to find
the <termref
def="dt-ebv"
>effective boolean value</termref> of the test expression, as defined in <specref
ref="id-ebv"/>.</p>

<p diff="del" at="2023-01-10">The value of a conditional expression is defined as follows: If the
effective boolean value of the test expression is <code>true</code>, the value of the then-expression is returned. If the
effective boolean value of the test expression is <code>false</code>,
the value of the else-expression is returned.</p>
<p>Conditional expressions have a special rule for propagating <termref
def="dt-dynamic-error"
>dynamic errors</termref>: <phrase diff="chg" at="2023-01-10">expressions whose value is not needed for
Expand Down Expand Up @@ -20781,14 +20751,7 @@ then $part/wholesale
else $part/retail]]></eg>
</item>

<item diff="add" at="2023-01-10">
<p>The above expression can equivalently be written:</p>
<eg role="parse-test"><![CDATA[if ($part/@discounted) {
$part/wholesale
} else {
$part/retail
}]]></eg>
</item>


<item diff="add" at="2022-12-07">
<p>The following example returns the attribute node <code>@discount</code> provided the value of <code>@price</code>
Expand All @@ -20798,24 +20761,24 @@ else $part/retail]]></eg>
</item>
<item diff="add" at="2023-01-10">
<p>The following example tests a number of conditions:</p>
<eg role="parse-test"><![CDATA[if (@code = 1) {
<eg role="parse-test"><![CDATA[if (@code = 1) then
"food"
} else if (@code = 2) {
else if (@code = 2) then
"fashion"
} else if (@code = 3) {
else if (@code = 3) then
"household"
} else {
else
"general"
}]]></eg>
]]></eg>
</item>
</ulist>
<note diff="add" at="2023-01-10">
<p>The “dangling else ambiguity” found in many other languages cannot arise:</p>
<ulist>
<item><p>In the unbraced format, both the <code>then</code> and <code>else</code> clauses
are mandatory.</p></item>
<item><p>In the braced format, an <code>else</code> clause is always unambiguously
associated with the immediately containing <nt def="IfExpr">IfExpr</nt>.</p></item>
<item><p>In the braced format, the expression terminates unambiguously with the closing
brace.</p></item>
</ulist>
</note>
</div2>
Expand Down

0 comments on commit 46afc6d

Please sign in to comment.