Open johnlumley opened 1 week ago
As noted in the meeting, the type
and record
keywords should be added to the reserved function name list.
I don't think it's quite as simple as that. Taking the simple example:
$tree ??type(foo)
and a reduced-tree grammar, we get two parses:
<XPath xmlns:ixml="http://invisiblexml.org/NS" ixml:state="ambiguous">
<ValueExpr>
<LookupExpr>
<VarRef>
<QName local="tree"/>
</VarRef>
<Lookup>??<TypeQualifier>
<SequenceType>
<QName local="foo"/>
</SequenceType>
</TypeQualifier>
</Lookup>
</LookupExpr>
</ValueExpr>
</XPath>
which is probably the intended meaning, and
<XPath xmlns:ixml="http://invisiblexml.org/NS" ixml:state="ambiguous">
<ValueExpr>
<DynamicFunctionCall>
<LookupExpr>
<VarRef>
<QName local="tree"/>
</VarRef>
<Lookup>??<QName local="type"/>
</Lookup>
</LookupExpr>
<PositionalArgumentList>
<ValueExpr>
<AxisStep>
<QName local="foo"/>
<PredicateList/>
</AxisStep>
</ValueExpr>
</PositionalArgumentList>
</DynamicFunctionCall>
</ValueExpr>
</XPath>
where the bracketed section is taken as arguments to a dynamic function call via a LookupExpr
, the lookup key of which happened to be type
, and similarly for record
. (If we change the expression to $tree ??Type(foo)
, the ambiguity disappears of course and it parses as a DynamicFunctionCall
.)
In this case it isn't a function call that would have to disallow type
, but the conjunction of a Lookup
with key type
within a DynamicFunctionCall
. The alternative would be to forbid type
or record
being used as lookup keys, which I don't think would go down very well.
Right, so the actual ambiguity is in LookupExpr parsing a TypeQualifier or NCName:
$tree??type(foo)
^^^^^^^^^ -- KeySpecifier / TypeQualifier
^^^^^^^^^^^ -- Lookup
^^^^^^^^^^^^^^^^ -- LookupExpr
$tree??type(foo)
^^^^ -- KeySpecifier / NCName
^^^^^^ -- Lookup
^^^^^^^^^^^ -- PostfixExpr / LookupExpr
^^^^^^^^^^^^^^^^ -- DynamicFunctionCall
Does moving TypeQualifier
to the start of the KeySpecifier
list resolve this? I.e.
[88] KeySpecifier ::= TypeQualifier | NCName | IntegerLiteral | StringLiteral | VarRef | ParenthesizedExpr | LookupWildcard
And do we need to do the same with PostfixExpr for DynamicFunctionCall (moving it to the end):
[75] PostfixExpr ::= PrimaryExpr | FilterExpr | LookupExpr | FilterExprAM | DynamicFunctionCall
Does moving TypeQualifier to the start of the KeySpecifier list resolve this?
I don't think so, as the order of alternatives in EBNF doesn't, I think, constitute a priority order. (Please correct me if I'm wrong, but I can't see anything that suggests that)
I'm not sure as I've only hand-written the XPath/XQuery parser, so would handle this case by maximally matching the TypeQualifier i.e. by placing it before testing for an NCName.
If maximal matching on TypeQualifier
is required, it needs to be stated in the extra-grammatical notes of the spec. (Such is already done for occurrence indicators on function types.) If this is the case then I assume:
($tree??type)(foo)
would be required and allow dynamic lookup and evaluation of a function via a type
keyspecifier.
I would have expected the rule "Postfix expressions are evaluated from left-to-right." (in 4.3) to cover this. But actually, that would encourage the ($tree??type)(foo)
interpretation. And I agree, while we can make type
a reserved function name easily enough, we can't make it a reserved key in a map. So perhaps we do need to find a different syntax.
Additional to https://github.com/qt4cg/qtspecs/issues/1050 An additional ambiguity occurs in one of the deep lookup examples:
which can be simplified to
where there is ambiguity between a
LookupExpr
withTypeQualifier
and aDynamicFunctionCall
on a function namedtype
. That is,type
should perhaps be one of the restrictions on function name to avoid this ambiguity.Whether something more fundamental is needed on the productions around [74],[75] and [84]-[88] I'm not sure, but certainly
type
can appear either as a keyword forTypeQualifier
(consuming the bracketed type) or a value of anNCName
(with the bracketed section being a higher-levelPositionalArgumentList
), both being part of aKeySpecifier
.