1 # Exercising Bison Grammar Reduction. -*- Autotest -*-
2 # Copyright (C) 2001, 2002, 2007, 2008, 2009 Free Software Foundation,
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 AT_BANNER([[Grammar Reduction.]])
21 ## ------------------- ##
22 ## Useless Terminals. ##
23 ## ------------------- ##
25 AT_SETUP([Useless Terminals])
46 AT_BISON_CHECK([[input.y]])
48 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
49 [[Terminals unused in grammar
65 ## ---------------------- ##
66 ## Useless Nonterminals. ##
67 ## ---------------------- ##
69 AT_SETUP([Useless Nonterminals])
90 AT_BISON_CHECK([[input.y]], 0, [],
91 [[input.y: warning: 9 nonterminals useless in grammar
92 input.y:4.8-15: warning: nonterminal useless in grammar: useless1
93 input.y:5.8-15: warning: nonterminal useless in grammar: useless2
94 input.y:6.8-15: warning: nonterminal useless in grammar: useless3
95 input.y:7.8-15: warning: nonterminal useless in grammar: useless4
96 input.y:8.8-15: warning: nonterminal useless in grammar: useless5
97 input.y:9.8-15: warning: nonterminal useless in grammar: useless6
98 input.y:10.8-15: warning: nonterminal useless in grammar: useless7
99 input.y:11.8-15: warning: nonterminal useless in grammar: useless8
100 input.y:12.8-15: warning: nonterminal useless in grammar: useless9
103 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
104 [[Nonterminals useless in grammar
120 ## --------------- ##
122 ## --------------- ##
124 AT_SETUP([Useless Rules])
126 AT_KEYWORDS([report])
145 AT_BISON_CHECK([[input.y]], 0, [],
146 [[input.y: warning: 9 nonterminals useless in grammar
147 input.y: warning: 9 rules useless in grammar
148 input.y:6.1-8: warning: nonterminal useless in grammar: useless1
149 input.y:7.1-8: warning: nonterminal useless in grammar: useless2
150 input.y:8.1-8: warning: nonterminal useless in grammar: useless3
151 input.y:9.1-8: warning: nonterminal useless in grammar: useless4
152 input.y:10.1-8: warning: nonterminal useless in grammar: useless5
153 input.y:11.1-8: warning: nonterminal useless in grammar: useless6
154 input.y:12.1-8: warning: nonterminal useless in grammar: useless7
155 input.y:13.1-8: warning: nonterminal useless in grammar: useless8
156 input.y:14.1-8: warning: nonterminal useless in grammar: useless9
157 input.y:6.11-13: warning: rule useless in grammar: useless1: '1'
158 input.y:7.11-13: warning: rule useless in grammar: useless2: '2'
159 input.y:8.11-13: warning: rule useless in grammar: useless3: '3'
160 input.y:9.11-13: warning: rule useless in grammar: useless4: '4'
161 input.y:10.11-13: warning: rule useless in grammar: useless5: '5'
162 input.y:11.11-13: warning: rule useless in grammar: useless6: '6'
163 input.y:12.11-13: warning: rule useless in grammar: useless7: '7'
164 input.y:13.11-13: warning: rule useless in grammar: useless8: '8'
165 input.y:14.11-13: warning: rule useless in grammar: useless9: '9'
168 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
169 [[Nonterminals useless in grammar
179 Terminals unused in grammar
189 Rules useless in grammar
205 ## ------------------- ##
206 ## Reduced Automaton. ##
207 ## ------------------- ##
209 # Check that the automaton is that as the for the grammar reduced by
212 AT_SETUP([Reduced Automaton])
214 AT_KEYWORDS([report])
216 # The non reduced grammar.
217 # ------------------------
218 AT_DATA([[not-reduced.y]],
219 [[/* A useless token. */
224 %output "not-reduced.c"
228 exp: useful { /* A useful action. */ }
229 | non_productive { /* A non productive action. */ }
232 not_reachable: useful { /* A not reachable action. */ }
235 non_productive: non_productive useless_token
236 { /* Another non productive action. */ }
241 AT_BISON_CHECK([[not-reduced.y]], 0, [],
242 [[not-reduced.y: warning: 2 nonterminals useless in grammar
243 not-reduced.y: warning: 3 rules useless in grammar
244 not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable
245 not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive
246 not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive
247 not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful
248 not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token
251 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
252 [[Nonterminals useless in grammar
255 Terminals unused in grammar
257 Rules useless in grammar
258 2 exp: non_productive
259 3 not_reachable: useful
260 4 non_productive: non_productive useless_token
263 # The reduced grammar.
264 # --------------------
265 AT_DATA([[reduced.y]],
266 [[/* A useless token. */
275 exp: useful { /* A useful action. */ }
276 // | non_productive { /* A non productive action. */ } */
279 //not_reachable: useful { /* A not reachable action. */ }
282 //non_productive: non_productive useless_token
283 // { /* Another non productive action. */ }
288 AT_BISON_CHECK([[reduced.y]])
290 # Comparing the parsers.
292 AT_CHECK([sed 's/not-reduced/reduced/g' not-reduced.c], 0, [expout])
298 ## ------------------- ##
299 ## Underivable Rules. ##
300 ## ------------------- ##
302 AT_SETUP([Underivable Rules])
304 AT_KEYWORDS([report])
311 exp: useful | underivable;
312 underivable: indirection;
313 indirection: underivable;
316 AT_BISON_CHECK([[input.y]], 0, [],
317 [[input.y: warning: 2 nonterminals useless in grammar
318 input.y: warning: 3 rules useless in grammar
319 input.y:5.15-25: warning: nonterminal useless in grammar: underivable
320 input.y:6.14-24: warning: nonterminal useless in grammar: indirection
321 input.y:5.15-25: warning: rule useless in grammar: exp: underivable
322 input.y:6.14-24: warning: rule useless in grammar: underivable: indirection
323 input.y:7.14-24: warning: rule useless in grammar: indirection: underivable
326 AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
327 [[Nonterminals useless in grammar
330 Rules useless in grammar
332 3 underivable: indirection
333 4 indirection: underivable
340 ## ---------------- ##
341 ## Empty Language. ##
342 ## ---------------- ##
344 AT_SETUP([Empty Language])
352 AT_BISON_CHECK([[input.y]], 1, [],
353 [[input.y: warning: 2 nonterminals useless in grammar
354 input.y: warning: 2 rules useless in grammar
355 input.y:3.1-3: fatal error: start symbol exp does not derive any sentence
362 ## -------------------------- ##
363 ## %define lr.default_rules. ##
364 ## -------------------------- ##
366 # AT_TEST_LR_DEFAULT_RULES(GRAMMAR, INPUT, TABLES)
367 # ------------------------------------------------
368 m4_define([AT_TEST_LR_DEFAULT_RULES],
370 AT_TEST_TABLES_AND_PARSE([[no %define lr.default_rules]],
373 [$1], [$2], [[]], [$3])
374 AT_TEST_TABLES_AND_PARSE([[%define lr.default_rules "all"]],
376 [[%define lr.default_rules "all"]],
377 [$1], [$2], [[]], [$3])
378 AT_TEST_TABLES_AND_PARSE([[%define lr.default_rules "consistent"]],
379 [[consistent]], [[]],
380 [[%define lr.default_rules "consistent"]],
381 [$1], [$2], [[]], [$3])
382 AT_TEST_TABLES_AND_PARSE([[%define lr.default_rules "accepting"]],
384 [[%define lr.default_rules "accepting"]],
385 [$1], [$2], [[]], [$3])
388 AT_TEST_LR_DEFAULT_RULES([[
389 /* The start state is consistent and has a shift on 'a' and no reductions.
390 After pushing the b below, enter an inconsistent state that has a shift and
391 one reduction with one lookahead. */
398 /* After shifting this 'a', enter a consistent state that has no shift and 1
399 reduction with multiple lookaheads. */
402 /* After the previous reduction, enter an inconsistent state that has no shift
403 and multiple reductions. The first reduction has more lookaheads than the
404 second, so the first should always be preferred as the default rule if
405 enabled. The second reduction has one lookahead. */
409 dnl Visit each state mentioned above.
413 0 $accept: . start $end
419 'a' shift, and go to state 1
427 4 a: 'a' .]AT_COND_CASE([[accepting]], [[ [$end, 'a', 'b']
429 $end reduce using rule 4 (a)
430 'a' reduce using rule 4 (a)
431 'b' reduce using rule 4 (a)]], [[
433 $default reduce using rule 4 (a)]])[
438 0 $accept: start . $end
440 $end shift, and go to state 4
449 6 c: . ['b']]AT_COND_CASE([[all]], [[
451 'b' reduce using rule 6 (c)
452 $default reduce using rule 5 (b)]], [[
454 $end reduce using rule 5 (b)
455 'a' reduce using rule 5 (b)
456 'b' reduce using rule 6 (c)]])[
464 0 $accept: start $end .
471 1 start: a b . [$end]
474 'a' shift, and go to state 7
476 ]AT_COND_CASE([[all]], [[$default]], [[$end]])[ reduce using rule 1 (start)
483 'b' shift, and go to state 8
488 2 start: a b 'a' .]AT_COND_CASE([[accepting]], [[ [$end]
490 $end reduce using rule 2 (start)]], [[
492 $default reduce using rule 2 (start)]])[
497 3 start: a c 'b' .]AT_COND_CASE([[accepting]], [[ [$end]
499 $end reduce using rule 3 (start)]], [[
501 $default reduce using rule 3 (start)]])[