1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%% Description  : Yecc spec for XPATH grammar
22%%    This version of the parser is based on the XPATH spec:
23%%    http://www.w3.org/TR/1999/REC-xpath-19991116 (XPATH version 1.0)
24
25
26Nonterminals
27	'LocationPath'
28	'AbsoluteLocationPath'
29	'RelativeLocationPath'
30	'Step'
31%%	'AxisSpecifier'
32	'NodeTest'
33	'Predicate'
34	'PredicateExpr'
35	'AbbreviatedAbsoluteLocationPath'
36	'AbbreviatedRelativeLocationPath'
37	'AbbreviatedStep'
38%%	'AbbreviatedAxisSpecifier'
39	'Expr'
40	'PrimaryExpr'
41	'FunctionCall'
42	'Argument'
43	'UnionExpr'
44	'PathExpr'
45	'FilterExpr'
46	'OrExpr'
47	'AndExpr'
48	'EqualityExpr'
49	'RelationalExpr'
50	'AdditiveExpr'
51	'MultiplicativeExpr'
52	'UnaryExpr'
53%%	'Operator'
54%%	'OperatorName'
55	'MultiplyOperator'
56	'NameTest'
57	'<PredicateList>'
58	'<PredicateMember>'
59	'<ArgumentList>'
60	'<ArgumentMember>'
61	.
62
63Terminals
64	'number'
65	'axis'
66	'node_type'
67	'literal'
68	'prefix_test'
69	'var_reference'
70	'function_name'
71	'name'
72	'processing-instruction'
73	'wildcard'
74	'(' ')' '[' ']' '.' '..' '@' ',' '::'
75	'and' 'or' 'mod' 'div'
76	'/' '//' '|' '+' '-' '=' '!=' '<' '<=' '>' '>='
77	'*'
78	.
79
80Rootsymbol 'Expr'.
81
82Endsymbol '$end' .
83
84Left 100 'or' .
85Left 200 'and' .
86Left 300 '=' .
87Left 300 '!=' .
88Left 400 '<' .
89Left 400 '>=' .
90Left 400 '>' .
91Left 400 '<=' .
92Unary 500 '-' .
93
94Expect 2.
95
96%%------------------------------------------------------------
97%% Clauses
98%%
99
100%% [1]
101'LocationPath' -> 'RelativeLocationPath' : {path, rel, '$1'} .
102'LocationPath' -> 'AbsoluteLocationPath' : {path, abs, '$1'}.
103
104%% [2]
105'AbsoluteLocationPath' -> '/' 'RelativeLocationPath' : '$2' .
106'AbsoluteLocationPath' -> '/' : '/' .
107
108%% [3]
109'RelativeLocationPath' -> 'AbbreviatedAbsoluteLocationPath' : '$1' .
110'RelativeLocationPath' -> 'Step' : '$1' .
111'RelativeLocationPath' -> 'RelativeLocationPath' '/' 'Step' :
112	{refine, '$1', '$3'} .
113'RelativeLocationPath' -> 'AbbreviatedRelativeLocationPath' : '$1' .
114
115%% [4]
116'Step' -> 'axis' '::' 'NodeTest' '<PredicateList>'
117	: {step, {value('$1'), '$3', '$4'}} .
118'Step' -> 'axis' '::' 'NodeTest'
119	: {step, {value('$1'), '$3', []}} .
120'Step' -> '@' 'name' '<PredicateList>'
121	: {step, {value('$1'), '$2', '$3'}} .
122'Step' -> '@' 'name'
123	: {step, {'attribute', '$2', []}} .
124'Step' -> 'NodeTest' '<PredicateList>'
125	: {step, {'child', '$1', '$2'}} .
126'Step' -> 'NodeTest'
127	: {step, {'child', '$1', []}} .
128'Step' -> 'AbbreviatedStep'
129	: {abbrev_step, '$1'} .
130
131
132'<PredicateList>' -> '<PredicateMember>' : lists:reverse('$1') .
133
134
135'<PredicateMember>' -> '<PredicateMember>' 'Predicate'
136	: ['$2'|'$1'] .
137'<PredicateMember>' -> 'Predicate' : ['$1'] .
138
139
140%% [5]
141%% 'AxisSpecifier' -> 'axis' '::' : '$1' .
142%% 'AxisSpecifier' -> 'AbbreviatedAxisSpecifier' : '$1' .
143
144
145%% [7]
146'NodeTest' -> 'NameTest' : '$1' .
147'NodeTest' -> 'node_type' '(' ')' : {node_type, value('$1')} .
148'NodeTest' -> 'processing-instruction' '(' ')' : {node_type, value('$1')} .
149'NodeTest' -> 'processing-instruction' '(' 'literal' ')'
150	: {processing_instruction, value('$3')} .
151
152
153%% [8]
154'Predicate' -> '[' 'PredicateExpr' ']' : {pred, '$2'} .
155
156%% [9]
157'PredicateExpr' -> 'Expr' : '$1' .
158
159%% [10]
160'AbbreviatedAbsoluteLocationPath'  -> '//' 'RelativeLocationPath'
161	: {'//', '$2'} .
162
163%% [11]
164'AbbreviatedRelativeLocationPath' -> 'RelativeLocationPath' '//' 'Step'
165	: {'$1', '//', '$3'} .
166
167%% [12]
168'AbbreviatedStep' -> '.' : '$1' .
169'AbbreviatedStep' -> '..' : '$1' .
170
171%% [13]
172%% 'AbbreviatedAxisSpecifier' ->  '$empty' : 'child' .
173%% 'AbbreviatedAxisSpecifier' ->  '@' : '$1' .
174
175%% [14]
176'Expr' -> 'OrExpr' : '$1' .
177
178%% [15]
179'PrimaryExpr' -> 'var_reference' : {variable_reference, value('$1')} .
180'PrimaryExpr' -> '(' Expr ')' : '$2' .
181'PrimaryExpr' -> 'literal' : {literal, value('$1')} .
182'PrimaryExpr' -> 'number' : {number, value('$1')} .
183'PrimaryExpr' -> 'FunctionCall' : '$1' .
184
185
186%% [16]
187'FunctionCall' -> 'function_name' '(' ')' : {function_call, value('$1'), []} .
188'FunctionCall' -> 'function_name' '(' '<ArgumentList>' ')'
189	: {function_call, value('$1'), '$3'} .
190
191'<ArgumentList>' -> '<ArgumentMember>' : lists:reverse('$1') .
192
193'<ArgumentMember>' -> '<ArgumentMember>' ',' 'Argument'
194	: ['$3'|'$1'] .
195'<ArgumentMember>' -> 'Argument' : ['$1'] .
196
197
198%% [17]
199'Argument' -> 'Expr' : '$1' .
200
201
202%% [18]
203'UnionExpr' -> 'PathExpr' : '$1' .
204'UnionExpr' -> 'UnionExpr' '|' 'PathExpr' : {path, union, {'$1', '$3'}} .
205
206
207%% [19]
208'PathExpr' -> 'LocationPath' : '$1' .
209'PathExpr' -> 'FilterExpr' : '$1' .
210'PathExpr' -> 'FilterExpr' '/' 'RelativeLocationPath' : {refine, '$1', '$3'} .
211'PathExpr' -> 'FilterExpr' '//' 'RelativeLocationPath' : {'$1', '//', '$3'} .
212
213%% [20]
214'FilterExpr' -> 'PrimaryExpr' : '$1' .
215'FilterExpr' -> 'FilterExpr' 'Predicate' : {path, filter, {'$1', '$2'}} .
216
217
218%% [21]
219'OrExpr' -> 'AndExpr' : '$1' .
220'OrExpr' -> 'OrExpr' 'or' 'AndExpr'
221	: {bool, 'or', '$1', '$3'} .
222
223
224%% [22]
225'AndExpr' -> 'EqualityExpr' : '$1' .
226'AndExpr' -> 'AndExpr' 'and' 'EqualityExpr'
227	: {bool, 'and', '$1', '$3'} .
228
229%% [23]
230'EqualityExpr' -> 'RelationalExpr' : '$1' .
231'EqualityExpr' -> 'EqualityExpr' '=' 'RelationalExpr'
232	: {comp, '=', '$1', '$3'} .
233'EqualityExpr' -> 'EqualityExpr' '!=' 'RelationalExpr'
234	: {comp, '!=', '$1', '$3'} .
235
236%%[24]
237'RelationalExpr' -> 'AdditiveExpr' : '$1' .
238'RelationalExpr' -> 'RelationalExpr' '<' 'AdditiveExpr'
239	: {comp, '<', '$1', '$3'} .
240'RelationalExpr' -> 'RelationalExpr' '>' 'AdditiveExpr'
241	: {comp, '>', '$1', '$3'} .
242'RelationalExpr' -> 'RelationalExpr' '<=' 'AdditiveExpr'
243	: {comp, '<=', '$1', '$3'} .
244'RelationalExpr' -> 'RelationalExpr' '>=' 'AdditiveExpr'
245	: {comp, '>=', '$1', '$3'} .
246
247
248%% [25]
249'AdditiveExpr' -> 'MultiplicativeExpr' : '$1' .
250'AdditiveExpr' -> 'AdditiveExpr' '+' 'MultiplicativeExpr'
251	: {arith, '+', '$1', '$3'} .
252'AdditiveExpr' -> 'AdditiveExpr' '-' 'MultiplicativeExpr'
253	: {arith, '-', '$1', '$3'} .
254
255
256%% [26]
257'MultiplicativeExpr' -> 'UnaryExpr' : '$1' .
258'MultiplicativeExpr' -> 'MultiplicativeExpr' 'MultiplyOperator' 'UnaryExpr'
259	: {arith, '$2', '$1', '$3'} .
260'MultiplicativeExpr' -> 'MultiplicativeExpr' 'div' 'UnaryExpr'
261	: {arith, 'div', '$1', '$3'} .
262'MultiplicativeExpr' -> 'MultiplicativeExpr' 'mod' 'UnaryExpr'
263	: {arith, 'mod', '$1', '$3'} .
264
265
266%% [27]
267'UnaryExpr' -> 'UnionExpr' : '$1' .
268'UnaryExpr' -> '-' UnaryExpr : {'negative', '$2'} .
269
270
271
272%% [32]
273%% 'Operator' -> 'OperatorName' : '$1' .
274%% 'Operator' -> 'MultiplyOperator' : '$1' .
275%% 'Operator' -> '/' : '$1' .
276%% 'Operator' -> '//' : '$1' .
277%% 'Operator' -> '|' : '$1' .
278%% 'Operator' -> '+' : '$1' .
279%% 'Operator' -> '-' : '$1' .
280%% 'Operator' -> '=' : '$1' .
281%% 'Operator' -> '!=' : '$1' .
282%% 'Operator' -> '<' : '$1' .
283%% 'Operator' -> '<=' : '$1' .
284%% 'Operator' -> '>' : '$1' .
285%% 'Operator' -> '>=' : '$1' .
286
287%% [33]
288%% 'OperatorName' -> 'and' : '$1' .
289%% 'OperatorName' -> 'mod' : '$1' .
290%% 'OperatorName' -> 'div' : '$1' .
291
292%% [34]
293'MultiplyOperator' -> '*' : '*' .
294
295
296%% [37]
297'NameTest' -> 'wildcard' : {wildcard, value('$1')} .
298'NameTest' -> 'prefix_test' : {prefix_test, value('$1')} .
299'NameTest' -> 'name' : {name, value('$1')} .
300
301
302
303Erlang code.
304
305% token({Token, _Line}) ->
306% 	Token;
307% token({Token, _Line, _Value}) ->
308% 	Token.
309
310value({Token, _Line}) ->
311	Token;
312value({_Token, _Line, Value}) ->
313	Value.
314