Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1706 Drop "else if" and "else" clauses from braced conditionals #1712

Merged
merged 1 commit into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading