|
@@ -41,8 +41,8 @@ resourcestring
|
|
{ Parser errors }
|
|
{ Parser errors }
|
|
SParserExpectedLeftBracket = 'Expected "("';
|
|
SParserExpectedLeftBracket = 'Expected "("';
|
|
SParserExpectedRightBracket = 'Expected ")"';
|
|
SParserExpectedRightBracket = 'Expected ")"';
|
|
- SParserExpectedColonColon = 'Expected "::" after axis specifier';
|
|
|
|
- SParserExpectedBrackets = 'Expected "()" after NodeType test';
|
|
|
|
|
|
+ SParserBadAxisName = 'Invalid axis name';
|
|
|
|
+ SParserBadNodeType = 'Invalid node type';
|
|
SParserExpectedRightSquareBracket = 'Expected "]" after predicate';
|
|
SParserExpectedRightSquareBracket = 'Expected "]" after predicate';
|
|
SParserInvalidPrimExpr = 'Invalid primary expression';
|
|
SParserInvalidPrimExpr = 'Invalid primary expression';
|
|
SParserGarbageAfterExpression = 'Unrecognized input after expression';
|
|
SParserGarbageAfterExpression = 'Unrecognized input after expression';
|
|
@@ -351,7 +351,7 @@ type
|
|
FTokenStart: DOMPChar;
|
|
FTokenStart: DOMPChar;
|
|
FTokenLength: Integer;
|
|
FTokenLength: Integer;
|
|
procedure Error(const Msg: String);
|
|
procedure Error(const Msg: String);
|
|
- procedure ParseStep(var Dest: TStep); // [4]
|
|
|
|
|
|
+ procedure ParseStep(Dest: TStep); // [4]
|
|
function ParsePrimaryExpr: TXPathExprNode; // [15]
|
|
function ParsePrimaryExpr: TXPathExprNode; // [15]
|
|
function ParseUnionExpr: TXPathExprNode; // [18]
|
|
function ParseUnionExpr: TXPathExprNode; // [18]
|
|
function ParsePathExpr: TXPathExprNode; // [19]
|
|
function ParsePathExpr: TXPathExprNode; // [19]
|
|
@@ -1707,15 +1707,13 @@ begin
|
|
raise Exception.Create(Msg) at get_caller_addr(get_frame);
|
|
raise Exception.Create(Msg) at get_caller_addr(get_frame);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TXPathScanner.ParseStep(var Dest: TStep); // [4]
|
|
|
|
-var
|
|
|
|
- NeedColonColon: Boolean;
|
|
|
|
|
|
+procedure TXPathScanner.ParseStep(Dest: TStep); // [4]
|
|
|
|
|
|
procedure NeedBrackets;
|
|
procedure NeedBrackets;
|
|
begin
|
|
begin
|
|
- if (NextToken <> tkLeftBracket) or
|
|
|
|
- (NextToken <> tkRightBracket) then
|
|
|
|
- Error(SParserExpectedBrackets);
|
|
|
|
|
|
+ NextToken;
|
|
|
|
+ if NextToken <> tkRightBracket then
|
|
|
|
+ Error(SParserExpectedRightBracket);
|
|
NextToken;
|
|
NextToken;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1739,12 +1737,9 @@ begin
|
|
Dest.Axis := axisAttribute;
|
|
Dest.Axis := axisAttribute;
|
|
NextToken;
|
|
NextToken;
|
|
end
|
|
end
|
|
- else if CurToken = tkIdentifier then // [5] AxisName '::'
|
|
|
|
|
|
+ else if (CurToken = tkIdentifier) and (PeekToken = tkColonColon) then // [5] AxisName '::'
|
|
begin
|
|
begin
|
|
- { TODO: should first check whether identifier is followed by '::',
|
|
|
|
- if not, it should be treated as NodeTest, not AxisName }
|
|
|
|
// Check for [6] AxisName
|
|
// Check for [6] AxisName
|
|
- NeedColonColon := True;
|
|
|
|
if CurTokenString = 'ancestor' then
|
|
if CurTokenString = 'ancestor' then
|
|
Dest.Axis := axisAncestor
|
|
Dest.Axis := axisAncestor
|
|
else if CurTokenString = 'ancestor-or-self' then
|
|
else if CurTokenString = 'ancestor-or-self' then
|
|
@@ -1772,16 +1767,10 @@ begin
|
|
else if CurTokenString = 'self' then
|
|
else if CurTokenString = 'self' then
|
|
Dest.Axis := axisSelf
|
|
Dest.Axis := axisSelf
|
|
else
|
|
else
|
|
- begin
|
|
|
|
- NeedColonColon := False;
|
|
|
|
- Dest.Axis := axisChild;
|
|
|
|
- end;
|
|
|
|
- if NeedColonColon then
|
|
|
|
- begin
|
|
|
|
- if NextToken <> tkColonColon then
|
|
|
|
- Error(SParserExpectedColonColon);
|
|
|
|
- NextToken;
|
|
|
|
- end;
|
|
|
|
|
|
+ Error(SParserBadAxisName);
|
|
|
|
+
|
|
|
|
+ NextToken; // skip identifier and the '::'
|
|
|
|
+ NextToken;
|
|
end
|
|
end
|
|
else if CurToken <> tkEndOfStream then
|
|
else if CurToken <> tkEndOfStream then
|
|
Dest.Axis := axisChild;
|
|
Dest.Axis := axisChild;
|
|
@@ -1794,38 +1783,40 @@ begin
|
|
end
|
|
end
|
|
else if CurToken = tkIdentifier then
|
|
else if CurToken = tkIdentifier then
|
|
begin
|
|
begin
|
|
- { TODO: should first check whether identifier is followed by '(',
|
|
|
|
- if not, it is a NodeTest, not NodeType }
|
|
|
|
// Check for case [38] NodeType
|
|
// Check for case [38] NodeType
|
|
- if CurTokenString = 'comment' then
|
|
|
|
- begin
|
|
|
|
- NeedBrackets;
|
|
|
|
- Dest.NodeTestType := ntCommentNode;
|
|
|
|
- end
|
|
|
|
- else if CurTokenString = 'text' then
|
|
|
|
|
|
+ if PeekToken = tkLeftBracket then
|
|
begin
|
|
begin
|
|
- NeedBrackets;
|
|
|
|
- Dest.NodeTestType := ntTextNode;
|
|
|
|
- end
|
|
|
|
- else if CurTokenString = 'processing-instruction' then
|
|
|
|
- begin
|
|
|
|
- if NextToken <> tkLeftBracket then
|
|
|
|
- Error(SParserExpectedLeftBracket);
|
|
|
|
- if NextToken = tkString then
|
|
|
|
|
|
+ if CurTokenString = 'comment' then
|
|
|
|
+ begin
|
|
|
|
+ NeedBrackets;
|
|
|
|
+ Dest.NodeTestType := ntCommentNode;
|
|
|
|
+ end
|
|
|
|
+ else if CurTokenString = 'text' then
|
|
begin
|
|
begin
|
|
- // TODO: Handle processing-instruction('name') constructs
|
|
|
|
- Dest.NodeTestString := CurTokenString;
|
|
|
|
|
|
+ NeedBrackets;
|
|
|
|
+ Dest.NodeTestType := ntTextNode;
|
|
|
|
+ end
|
|
|
|
+ else if CurTokenString = 'processing-instruction' then
|
|
|
|
+ begin
|
|
|
|
+ NextToken; { skip '('; we know it's there }
|
|
|
|
+ if NextToken = tkString then
|
|
|
|
+ begin
|
|
|
|
+ // TODO: Handle processing-instruction('name') constructs
|
|
|
|
+ Dest.NodeTestString := CurTokenString;
|
|
|
|
+ NextToken;
|
|
|
|
+ end;
|
|
|
|
+ if CurToken <> tkRightBracket then
|
|
|
|
+ Error(SParserExpectedRightBracket);
|
|
NextToken;
|
|
NextToken;
|
|
- end;
|
|
|
|
- if CurToken <> tkRightBracket then
|
|
|
|
- Error(SParserExpectedRightBracket);
|
|
|
|
- NextToken;
|
|
|
|
- Dest.NodeTestType := ntPINode;
|
|
|
|
- end
|
|
|
|
- else if CurTokenString = 'node' then
|
|
|
|
- begin
|
|
|
|
- NeedBrackets;
|
|
|
|
- Dest.NodeTestType := ntAnyNode;
|
|
|
|
|
|
+ Dest.NodeTestType := ntPINode;
|
|
|
|
+ end
|
|
|
|
+ else if CurTokenString = 'node' then
|
|
|
|
+ begin
|
|
|
|
+ NeedBrackets;
|
|
|
|
+ Dest.NodeTestType := ntAnyNode;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ Error(SParserBadNodeType);
|
|
end
|
|
end
|
|
else // [37] NameTest, second or third case
|
|
else // [37] NameTest, second or third case
|
|
begin
|
|
begin
|