# Exercising Bison Grammar Reduction. -*- Autotest -*- # Copyright 2001 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. AT_BANNER([[Grammar Reduction.]]) ## ------------------- ## ## Useless Terminals. ## ## ------------------- ## AT_SETUP([Useless Terminals]) AT_DATA([[input.y]], [[%verbose %output="input.c" %token useless1 %token useless2 %token useless3 %token useless4 %token useless5 %token useless6 %token useless7 %token useless8 %token useless9 %token useful %% exp: useful; ]]) AT_CHECK([[bison input.y]]) AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0, [[Terminals which are not used: useless1 useless2 useless3 useless4 useless5 useless6 useless7 useless8 useless9 ]]) AT_CLEANUP ## ---------------------- ## ## Useless Nonterminals. ## ## ---------------------- ## AT_SETUP([Useless Nonterminals]) AT_DATA([[input.y]], [[%verbose %output="input.c" %nterm useless1 %nterm useless2 %nterm useless3 %nterm useless4 %nterm useless5 %nterm useless6 %nterm useless7 %nterm useless8 %nterm useless9 %token useful %% exp: useful; ]]) AT_CHECK([[bison input.y]], 0, [], [[input.y contains 9 useless nonterminals ]]) AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0, [[Useless nonterminals: useless1 useless2 useless3 useless4 useless5 useless6 useless7 useless8 useless9 ]]) AT_CLEANUP ## --------------- ## ## Useless Rules. ## ## --------------- ## AT_SETUP([Useless Rules]) AT_DATA([[input.y]], [[%verbose %output="input.c" %token useful %% exp: useful; useless1: '1'; useless2: '2'; useless3: '3'; useless4: '4'; useless5: '5'; useless6: '6'; useless7: '7'; useless8: '8'; useless9: '9'; ]]) AT_CHECK([[bison input.y]], 0, [], [[input.y contains 9 useless nonterminals and 9 useless rules ]]) AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0, [[Useless nonterminals: useless1 useless2 useless3 useless4 useless5 useless6 useless7 useless8 useless9 Terminals which are not used: '1' '2' '3' '4' '5' '6' '7' '8' '9' Useless rules: #2 useless1: '1'; #3 useless2: '2'; #4 useless3: '3'; #5 useless4: '4'; #6 useless5: '5'; #7 useless6: '6'; #8 useless7: '7'; #9 useless8: '8'; #10 useless9: '9'; ]]) AT_CLEANUP ## ------------------- ## ## Reduced Automaton. ## ## ------------------- ## # Check that the automaton is that as the for the grammar reduced by # hand. AT_SETUP([Reduced Automaton]) # The non reduced grammar. # ------------------------ AT_DATA([[not-reduced.y]], [[/* A useless token. */ %token useless_token /* A useful one. */ %token useful %verbose %output="not-reduced.c" %% exp: useful { /* A useful action. */ } | non_productive { /* A non productive action. */ } ; not_reachable: useful { /* A not reachable action. */ } ; non_productive: non_productive useless_token { /* Another non productive action. */ } ; ]]) AT_CHECK([[bison not-reduced.y]], 0, [], [[not-reduced.y contains 2 useless nonterminals and 3 useless rules ]]) AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0, [[Useless nonterminals: not_reachable non_productive Terminals which are not used: useless_token Useless rules: #2 exp: non_productive; #3 not_reachable: useful; #4 non_productive: non_productive useless_token; ]]) # The reduced grammar. # -------------------- AT_DATA([[reduced.y]], [[/* A useless token. */ %token useless_token /* A useful one. */ %token useful %verbose %output="reduced.c" %% exp: useful { /* A useful action. */ } // | non_productive { /* A non productive action. */ } */ ; //not_reachable: useful { /* A not reachable action. */ } // ; //non_productive: non_productive useless_token // { /* Another non productive action. */ } // ; ]]) AT_CHECK([[bison reduced.y]]) # Comparing the parsers. cp reduced.c expout AT_CHECK([sed 's/not-reduced/reduced/g' not-reduced.c], 0, [expout]) AT_CLEANUP ## ------------------- ## ## Underivable Rules. ## ## ------------------- ## AT_SETUP([Underivable Rules]) AT_DATA([[input.y]], [[%verbose %output="input.c" %token useful %% exp: useful | underivable; underivable: indirection; indirection: underivable; ]]) AT_CHECK([[bison input.y]], 0, [], [[input.y contains 2 useless nonterminals and 3 useless rules ]]) AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0, [[Useless nonterminals: underivable indirection Useless rules: #2 exp: underivable; #3 underivable: indirection; #4 indirection: underivable; ]]) AT_CLEANUP