#! /bin/sh ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH SHELL=${CONFIG_SHELL-/bin/sh} # How were we run? at_cli_args="$@" # Load the config file. for at_file in atconfig atlocal do test -r $at_file || continue . ./$at_file || { echo "$as_me: error: invalid content: $at_file" >&2 { (exit 1); exit 1; }; } done # atconfig delivers paths relative to the directory the test suite is # in, but the groups themselves are run in testsuite-dir/group-dir. if test -n "$at_top_srcdir"; then builddir=../.. for at_dir in srcdir top_srcdir top_builddir do at_val=`eval echo '${'at_$at_dir'}'` eval "$at_dir=\$at_val/../.." done fi # Not all shells have the 'times' builtin; the subshell is needed to make # sure we discard the 'times: not found' message from the shell. at_times_p=false (times) >/dev/null 2>&1 && at_times_p=: # CLI Arguments to pass to the debugging scripts. at_debug_args= # -e sets to true at_errexit_p=false # Shall we be verbose? at_verbose=: at_quiet=echo # Shall we keep the debug scripts? Must be `:' when the suite is # run by a debug script, so that the script doesn't remove itself. at_debug_p=false # Display help message? at_help_p=false # List test groups? at_list_p=false # Test groups to run at_groups= # The directory we are in. at_dir=`pwd` # The directory the whole suite works in. # Should be absolutely to let the user `cd' at will. at_suite_dir=$at_dir/$as_me.dir # The file containing the suite. at_suite_log=$at_dir/$as_me.log # The file containing the location of the last AT_CHECK. at_check_line_file=$at_suite_dir/at-check-line # The file containing the exit status of the last command. at_status_file=$at_suite_dir/at-status # The files containing the output of the tested commands. at_stdout=$at_suite_dir/at-stdout at_stder1=$at_suite_dir/at-stder1 at_stderr=$at_suite_dir/at-stderr # The file containing dates. at_times_file=$at_suite_dir/at-times # List of the tested programs. at_tested='bison' # List of the all the test groups. at_groups_all=' banner-1 1 2 3 4 5 6 7 8 9 10 banner-2 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 banner-3 31 32 33 34 banner-4 35 36 37 38 39 40 banner-5 41 42 43 44 45 banner-6 46 47 48 49 banner-7 50 51 52 53 54 55 56 57 banner-8 58 59 60 61 62 63 64 65 66 67 68 69 banner-9 70 71 72 73 74 75 76 77 78 79 80 81 82 83 banner-10 84 85 86 87 88 89 90 91 92 93 94 95 96 97 banner-11 98 99 100 101 102 banner-12 103 104 banner-13 105 106 107 108 109 banner-14 110 111 112 banner-15 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 banner-16 131 132 banner-17 133 134 135 136 137 138 139 140 141 banner-18 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158' # As many dots as there are digits in the last test group number. # Used to normalize the test group numbers so that `ls' lists them in # numerical order. at_format='...' # Description of all the test groups. at_help_all='1;input.at:28;Invalid dollar-n;; 2;input.at:46;Invalid @n;; 3;input.at:64;Type Clashes;; 4;input.at:89;Unused values;; 5;input.at:157;Incompatible Aliases;; 6;input.at:198;Torturing the Scanner;; 7;input.at:357;Typed symbol aliases;; 8;input.at:393;Require 1.0;; 9;input.at:394;Require 2.3;; 10;input.at:396;Require 100.0;; 11;output.at:43;Output files: -dv ;; 12;output.at:46;Output files: -dv >&-;; 13;output.at:48;Output files: -dv -o foo.c ;; 14;output.at:50;Output files: -dv -o foo.tab.c ;; 15;output.at:52;Output files: -dv -y ;; 16;output.at:54;Output files: -dv -b bar ;; 17;output.at:56;Output files: -dv -g -o foo.c ;; 18;output.at:60;Output files: %defines %verbose ;; 19;output.at:62;Output files: %defines %verbose %yacc ;; 20;output.at:65;Output files: %defines %verbose %yacc ;; 21;output.at:69;Output files: %file-prefix="bar" %defines %verbose ;; 22;output.at:71;Output files: %output="bar.c" %defines %verbose %yacc ;; 23;output.at:75;Output files: %file-prefix="baz" %output="bar.c" %defines %verbose %yacc ;; 24;output.at:80;Output files: %defines %verbose ;; 25;output.at:83;Output files: %defines %verbose -o foo.c ;; 26;output.at:87;Output files: --defines=foo.hpp -o foo.c++ ;; 27;output.at:91;Output files: -o foo.c++ --graph=foo.gph ;; 28;output.at:105;Output files: %skeleton "lalr1.cc" %defines %verbose ;; 29;output.at:109;Output files: %skeleton "lalr1.cc" %defines %verbose ;; 30;output.at:114;Output files: %skeleton "lalr1.cc" %defines %verbose -o subdir/foo.cc ;; 31;sets.at:66;Nullable;; 32;sets.at:151;Broken Closure;; 33;sets.at:193;Firsts;; 34;sets.at:269;Accept;; 35;reduce.at:26;Useless Terminals;; 36;reduce.at:70;Useless Nonterminals;; 37;reduce.at:125;Useless Rules;report; 38;reduce.at:212;Reduced Automaton;report; 39;reduce.at:301;Underivable Rules;report; 40;reduce.at:342;Empty Language;; 41;synclines.at:95;Prologue synch line;; 42;synclines.at:115;%union synch line;; 43;synclines.at:138;Postprologue synch line;; 44;synclines.at:157;Action synch line;; 45;synclines.at:175;Epilogue synch line;; 46;headers.at:27;%union and --defines;; 47;headers.at:77;Invalid CPP guards: input/input;; 48;headers.at:78;Invalid CPP guards: 9foo;; 49;headers.at:87;export YYLTYPE;; 50;actions.at:25;Mid-rule actions;; 51;actions.at:91;Exotic Dollars;; 52;actions.at:527;Printers and Destructors : ;; 53;actions.at:528;Printers and Destructors with union: ;; 54;actions.at:533;Printers and Destructors : %defines %skeleton "lalr1.cc";c++; 55;actions.at:534;Printers and Destructors with union: %defines %skeleton "lalr1.cc";c++; 56;actions.at:536;Printers and Destructors : %glr-parser;; 57;actions.at:537;Printers and Destructors with union: %glr-parser;; 58;conflicts.at:32;S/R in initial;; 59;conflicts.at:52;%nonassoc and eof;; 60;conflicts.at:128;Unresolved SR Conflicts;report; 61;conflicts.at:235;Resolved SR Conflicts;report; 62;conflicts.at:357;Defaulted Conflicted Reduction;report; 63;conflicts.at:476;%expect not enough;; 64;conflicts.at:496;%expect right;; 65;conflicts.at:513;%expect too much;; 66;conflicts.at:533;%expect with reduce conflicts;; 67;conflicts.at:553;%no-default-prec without %prec;; 68;conflicts.at:579;%no-default-prec with %prec;; 69;conflicts.at:603;%default-prec;; 70;calc.at:550;Calculator ;; 71;calc.at:552;Calculator %defines;; 72;calc.at:553;Calculator %locations;; 73;calc.at:554;Calculator %name-prefix="calc";; 74;calc.at:555;Calculator %verbose;; 75;calc.at:556;Calculator %yacc;; 76;calc.at:557;Calculator %error-verbose;; 77;calc.at:559;Calculator %pure-parser %locations;; 78;calc.at:560;Calculator %error-verbose %locations;; 79;calc.at:562;Calculator %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc;; 80;calc.at:564;Calculator %debug;; 81;calc.at:565;Calculator %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc;; 82;calc.at:567;Calculator %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc;; 83;calc.at:569;Calculator %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count};; 84;calc.at:586;Calculator %glr-parser ;; 85;calc.at:588;Calculator %glr-parser %defines;; 86;calc.at:589;Calculator %glr-parser %locations;; 87;calc.at:590;Calculator %glr-parser %name-prefix="calc";; 88;calc.at:591;Calculator %glr-parser %verbose;; 89;calc.at:592;Calculator %glr-parser %yacc;; 90;calc.at:593;Calculator %glr-parser %error-verbose;; 91;calc.at:595;Calculator %glr-parser %pure-parser %locations;; 92;calc.at:596;Calculator %glr-parser %error-verbose %locations;; 93;calc.at:598;Calculator %glr-parser %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc;; 94;calc.at:600;Calculator %glr-parser %debug;; 95;calc.at:601;Calculator %glr-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc;; 96;calc.at:603;Calculator %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc;; 97;calc.at:605;Calculator %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count};; 98;calc.at:621;Calculator %skeleton "lalr1.cc" %defines %locations ;c++; 99;calc.at:622;Calculator %skeleton "lalr1.cc" %defines %locations %error-verbose %name-prefix="calc" %verbose %yacc;c++; 100;calc.at:624;Calculator %skeleton "lalr1.cc" %defines %locations %error-verbose %debug %name-prefix="calc" %verbose %yacc;c++; 101;calc.at:626;Calculator %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc;c++; 102;calc.at:628;Calculator %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count};c++; 103;calc.at:651;Calculator %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc;c++; 104;calc.at:653;Calculator %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count};c++; 105;torture.at:140;Big triangle;; 106;torture.at:232;Big horizontal;; 107;torture.at:368;Many look-ahead tokens;; 108;torture.at:445;Exploding the Stack Size with Alloca;; 109;torture.at:471;Exploding the Stack Size with Malloc;; 110;existing.at:26;GNU AWK Grammar;; 111;existing.at:364;GNU Cim Grammar;; 112;existing.at:980;GNU pic Grammar;; 113;regression.at:28;Trivial grammars;; 114;regression.at:57;Early token definitions;; 115;regression.at:95;Braces parsing;; 116;regression.at:117;Duplicate string;; 117;regression.at:143;Rule Line Numbers;report; 118;regression.at:287;Mixing %token styles;; 119;regression.at:310;Invalid inputs;; 120;regression.at:336;Invalid inputs with {};; 121;regression.at:363;Token definitions;; 122;regression.at:416;Characters Escapes;; 123;regression.at:447;Web2c Report;report; 124;regression.at:624;Web2c Actions;report; 125;regression.at:866;Dancer ;; 126;regression.at:867;Dancer %glr-parser;; 127;regression.at:868;Dancer %skeleton "lalr1.cc";c++; 128;regression.at:963;Expecting two tokens ;; 129;regression.at:964;Expecting two tokens %glr-parser;; 130;regression.at:965;Expecting two tokens %skeleton "lalr1.cc";c++; 131;c++.at:102;Doxygen Public Documentation;; 132;c++.at:103;Doxygen Private Documentation;; 133;cxx-type.at:412;GLR: Resolve ambiguity, impure, no locations;; 134;cxx-type.at:419;GLR: Resolve ambiguity, impure, locations;; 135;cxx-type.at:425;GLR: Resolve ambiguity, pure, no locations;; 136;cxx-type.at:432;GLR: Resolve ambiguity, pure, locations;; 137;cxx-type.at:439;GLR: Merge conflicting parses, impure, no locations;; 138;cxx-type.at:446;GLR: Merge conflicting parses, impure, locations;; 139;cxx-type.at:453;GLR: Merge conflicting parses, pure, no locations;; 140;cxx-type.at:459;GLR: Merge conflicting parses, pure, locations;; 141;cxx-type.at:466;GLR: Verbose messages, resolve ambiguity, impure, no locations;; 142;glr-regression.at:25;Badly Collapsed GLR States;; 143;glr-regression.at:116;Improper handling of embedded actions and dollar(-N) in GLR parsers;; 144;glr-regression.at:232;Improper merging of GLR delayed action sets;; 145;glr-regression.at:337;Duplicate representation of merged trees;; 146;glr-regression.at:432;User destructor for unresolved GLR semantic value;; 147;glr-regression.at:502;User destructor after an error during a split parse;; 148;glr-regression.at:566;Duplicated user destructor for lookahead;; 149;glr-regression.at:644;Incorrectly initialized location for empty right-hand side in GLR;; 150;glr-regression.at:740;No users destructors if stack 0 deleted;; 151;glr-regression.at:820;Corrupted semantic options if user action cuts parse;; 152;glr-regression.at:881;Undesirable destructors if user action cuts parse;; 153;glr-regression.at:947;Leaked semantic values if user action cuts parse;; 154;glr-regression.at:1078;Incorrect lookahead during deterministic GLR;; 155;glr-regression.at:1212;Incorrect lookahead during nondeterministic GLR;; 156;glr-regression.at:1429;Leaked semantic values when reporting ambiguity;; 157;glr-regression.at:1519;Leaked lookahead after nondeterministic parse syntax error;; 158;glr-regression.at:1585;Uninitialized location when reporting ambiguity;; ' at_keywords= at_prev= for at_option do # If the previous option needs an argument, assign it. if test -n "$at_prev"; then at_option=$at_prev=$at_option at_prev= fi at_optarg=`expr "x$at_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $at_option in --help | -h ) at_help_p=: ;; --list | -l ) at_list_p=: ;; --version | -V ) echo "$as_me (GNU Bison 2.3)" exit 0 ;; --clean | -c ) rm -rf $at_suite_dir $at_suite_log exit 0 ;; --debug | -d ) at_debug_p=: ;; --errexit | -e ) at_debug_p=: at_errexit_p=: ;; --verbose | -v ) at_verbose=echo; at_quiet=: ;; --trace | -x ) at_traceon='set -vx'; at_traceoff='set +vx' ;; [0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9]) at_groups="$at_groups$at_option " ;; # Ranges [0-9]- | [0-9][0-9]- | [0-9][0-9][0-9]- | [0-9][0-9][0-9][0-9]-) at_range_start=`echo $at_option |tr -d '-'` at_range=`echo " $at_groups_all " | \ sed -e 's,^.* '$at_range_start' ,'$at_range_start' ,'` at_groups="$at_groups$at_range " ;; -[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | -[0-9][0-9][0-9][0-9]) at_range_end=`echo $at_option |tr -d '-'` at_range=`echo " $at_groups_all " | \ sed -e 's, '$at_range_end' .*$, '$at_range_end','` at_groups="$at_groups$at_range " ;; [0-9]-[0-9] | [0-9]-[0-9][0-9] | [0-9]-[0-9][0-9][0-9] | \ [0-9]-[0-9][0-9][0-9][0-9] | [0-9][0-9]-[0-9][0-9] | \ [0-9][0-9]-[0-9][0-9][0-9] | [0-9][0-9]-[0-9][0-9][0-9][0-9] | \ [0-9][0-9][0-9]-[0-9][0-9][0-9] | \ [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9] | \ [0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9] ) at_range_start=`echo $at_option |sed 's,-.*,,'` at_range_end=`echo $at_option |sed 's,.*-,,'` # FIXME: Maybe test to make sure start <= end? at_range=`echo " $at_groups_all " | \ sed -e 's,^.* '$at_range_start' ,'$at_range_start' ,' \ -e 's, '$at_range_end' .*$, '$at_range_end','` at_groups="$at_groups$at_range " ;; # Keywords. --keywords | -k ) at_prev=--keywords ;; --keywords=* ) at_keywords="$at_keywords,$at_optarg" ;; *=*) at_envvar=`expr "x$at_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$at_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $at_envvar" >&2 { (exit 1); exit 1; }; } at_value=`echo "$at_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$at_envvar='$at_value'" export $at_envvar # Propagate to debug scripts. at_debug_args="$at_debug_args $at_option" ;; *) echo "$as_me: invalid option: $at_option" >&2 echo "Try \`$0 --help' for more information." >&2 exit 1 ;; esac done # Process the --keywords if test -n "$at_keywords"; then at_groups_selected=$at_help_all for at_keyword in `IFS=,; set X $at_keywords; shift; echo ${1+$@}` do # It is on purpose that we match the test group titles too. at_groups_selected=`echo "$at_groups_selected" | grep -i "^[^;]*;[^;]*.*[; ]$at_keyword[ ;]"` done at_groups_selected=`echo "$at_groups_selected" | sed 's/;.*//'` # Smash the end of lines. at_groups_selected=`echo $at_groups_selected` at_groups="$at_groups$at_groups_selected " fi # Selected test groups. test -z "$at_groups" && at_groups=$at_groups_all # Help message. if $at_help_p; then cat <<_ATEOF Usage: $0 [OPTION]... [VARIABLE=VALUE]... [TESTS] Run all the tests, or the selected TESTS, and save a detailed log file. Upon failure, create debugging scripts. You should not change environment variables unless explicitly passed as command line arguments. Set \`AUTOTEST_PATH' to select the executables to exercise. Each relative directory is expanded as build and source directories relatively to the top level of this distribution. E.g., $ $0 AUTOTEST_PATH=bin possibly amounts into PATH=/tmp/foo-1.0/bin:/src/foo-1.0/bin:\$PATH _ATEOF cat <<_ATEOF Operation modes: -h, --help print the help message, then exit -V, --version print version number, then exit -c, --clean remove all the files this test suite might create and exit -l, --list describes all the tests, or the selected TESTS _ATEOF cat <<_ATEOF Execution tuning: -k, --keywords=KEYWORDS select the tests matching all the comma separated KEYWORDS accumulates -e, --errexit abort as soon as a test fails; implies --debug -v, --verbose force more detailed output default for debugging scripts -d, --debug inhibit clean up and debug script creation default for debugging scripts -x, --trace enable tests shell tracing _ATEOF cat <<_ATEOF Report bugs to . _ATEOF exit 0 fi # List of tests. if $at_list_p; then cat <<_ATEOF GNU Bison 2.3 test suite test groups: NUM: FILENAME:LINE TEST-GROUP-NAME KEYWORDS _ATEOF # " 1 42 45 " => "^(1|42|45);". at_groups_pattern=`echo "$at_groups" | sed 's/^ *//;s/ *$//;s/ */|/g'` echo "$at_help_all" | awk 'BEGIN { FS = ";" } { if ($1 !~ /^('"$at_groups_pattern"')$/) next } { if ($1) printf " %3d: %-18s %s\n", $1, $2, $3 if ($4) printf " %s\n", $4 } ' exit 0 fi # Don't take risks: use only absolute directories in PATH. # # For stand-alone test suites, AUTOTEST_PATH is relative to `.'. # # For embedded test suites, AUTOTEST_PATH is relative to the top level # of the package. Then expand it into build/src parts, since users # may create executables in both places. # # There might be directories that don't exist, but don't redirect # builtins' (eg., cd) stderr directly: Ultrix's sh hates that. AUTOTEST_PATH=`echo $AUTOTEST_PATH | tr ':' $PATH_SEPARATOR` at_path= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $AUTOTEST_PATH $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in [\\/]* | ?:[\\/]* ) at_path=$at_path$PATH_SEPARATOR$as_dir ;; * ) if test -z "$at_top_builddir"; then # Stand-alone test suite. at_path=$at_path$PATH_SEPARATOR$as_dir else # Embedded test suite. at_path=$at_path$PATH_SEPARATOR$at_top_builddir/$as_dir at_path=$at_path$PATH_SEPARATOR$at_top_srcdir/$as_dir fi ;; esac done # Now build and simplify PATH. PATH= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $at_path do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_dir=`(cd "$as_dir" && pwd) 2>/dev/null` test -d "$as_dir" || continue case $PATH in $as_dir | \ $as_dir$PATH_SEPARATOR* | \ *$PATH_SEPARATOR$as_dir | \ *$PATH_SEPARATOR$as_dir$PATH_SEPARATOR* ) ;; '') PATH=$as_dir ;; *) PATH=$PATH$PATH_SEPARATOR$as_dir ;; esac done export PATH # Setting up the FDs. # 5 is the log file. Not to be overwritten if `-d'. $at_debug_p && at_suite_log=/dev/null exec 5>$at_suite_log # Banners and logs. cat <<\_ASBOX ## ------------------------- ## ## GNU Bison 2.3 test suite. ## ## ------------------------- ## _ASBOX { cat <<\_ASBOX ## ------------------------- ## ## GNU Bison 2.3 test suite. ## ## ------------------------- ## _ASBOX echo echo "$as_me: command line was:" echo " $ $0 $at_cli_args" echo # Try to find a few ChangeLogs in case it might help determining the # exact version. Use the relative dir: if the top dir is a symlink, # find will not follow it (and options to follow the links are not # portable), which would result in no output here. if test -n "$at_top_srcdir"; then cat <<\_ASBOX ## ----------- ## ## ChangeLogs. ## ## ----------- ## _ASBOX echo for at_file in `find "$at_top_srcdir" -name ChangeLog -print` do echo "$as_me: $at_file:" sed 's/^/| /;10q' $at_file echo done { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } echo fi # Contents of the config files. for at_file in atconfig atlocal do test -r $at_file || continue echo "$as_me: $at_file:" sed 's/^/| /' $at_file echo done cat <<\_ASBOX ## ---------------- ## ## Tested programs. ## ## ---------------- ## _ASBOX echo } >&5 # Report what programs are being tested. for at_program in : $at_tested do test "$at_program" = : && continue as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -f $as_dir/$at_program && break done if test -f $as_dir/$at_program; then { echo "local.at:216: $as_dir/$at_program --version" $as_dir/$at_program --version echo } >&5 2>&1 else { { echo "$as_me:$LINENO: error: cannot find $at_program" >&5 echo "$as_me: error: cannot find $at_program" >&2;} { (exit 1); exit 1; }; } fi done { cat <<\_ASBOX ## ------------------ ## ## Running the tests. ## ## ------------------ ## _ASBOX } >&5 at_start_date=`date` at_start_time=`(date +%s) 2>/dev/null` echo "$as_me: starting at: $at_start_date" >&5 at_xpass_list= at_xfail_list= at_pass_list= at_fail_list= at_skip_list= at_group_count=0 # Create the master directory if it doesn't already exist. test -d $at_suite_dir || mkdir $at_suite_dir || { { echo "$as_me:$LINENO: error: cannot create $at_suite_dir" >&5 echo "$as_me: error: cannot create $at_suite_dir" >&2;} { (exit 1); exit 1; }; } # Can we diff with `/dev/null'? DU 5.0 refuses. if diff /dev/null /dev/null >/dev/null 2>&1; then at_devnull=/dev/null else at_devnull=$at_suite_dir/devnull cp /dev/null $at_devnull fi # Use `diff -u' when possible. if diff -u $at_devnull $at_devnull >/dev/null 2>&1; then at_diff='diff -u' else at_diff=diff fi for at_group in $at_groups do # Be sure to come back to the top test directory. cd $at_suite_dir case $at_group in banner-*) at_group_log=$at_suite_log ;; *) # Skip tests we already run (using --keywords makes it easy to get # duplication). case " $at_pass_test $at_skip_test $at_fail_test " in *" $at_group "* ) continue;; esac # Normalize the test group number. at_group_normalized=`expr "00000$at_group" : ".*\($at_format\)"` # Create a fresh directory for the next test group, and enter. at_group_dir=$at_suite_dir/$at_group_normalized at_group_log=$at_group_dir/$as_me.log rm -rf $at_group_dir mkdir $at_group_dir || { { echo "$as_me:$LINENO: error: cannot create $at_group_dir" >&5 echo "$as_me: error: cannot create $at_group_dir" >&2;} { (exit 1); exit 1; }; } cd $at_group_dir ;; esac echo 0 > $at_status_file # Clearly separate the test groups when verbose. test $at_group_count != 0 && $at_verbose # In verbose mode, append to the log file *and* show on # the standard output; in quiet mode only write to the log if test $at_verbose = echo; then at_tee_pipe="tee -a $at_group_log" else at_tee_pipe="cat >> $at_group_log" fi case $at_group in banner-1 ) # Banner 1. input.at:19 cat <<\_ATEOF Input Processing. _ATEOF ;; 1 ) # 1. input.at:28: Invalid dollar-n at_setup_line='input.at:28' at_desc='Invalid dollar-n' $at_quiet $ECHO_N " 1: Invalid dollar-n $ECHO_C" at_xfail=no ( echo "1. input.at:28: testing ..." $at_traceon cat >input.y <<'_ATEOF' %% exp: { $$ = $1 ; }; _ATEOF $at_traceoff echo "input.at:37: bison input.y" echo input.at:37 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:2.13-14: integer out of range: \`\$1' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "input.at:37: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 2 ) # 2. input.at:46: Invalid @n at_setup_line='input.at:46' at_desc='Invalid @n' $at_quiet $ECHO_N " 2: Invalid @n $ECHO_C" at_xfail=no ( echo "2. input.at:46: testing ..." $at_traceon cat >input.y <<'_ATEOF' %% exp: { @$ = @1 ; }; _ATEOF $at_traceoff echo "input.at:55: bison input.y" echo input.at:55 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:2.13-14: integer out of range: \`@1' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "input.at:55: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 3 ) # 3. input.at:64: Type Clashes at_setup_line='input.at:64' at_desc='Type Clashes' $at_quiet $ECHO_N " 3: Type Clashes $ECHO_C" at_xfail=no ( echo "3. input.at:64: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token foo %type exp %% exp: foo {} foo | foo | /* Empty. */ ; _ATEOF $at_traceoff echo "input.at:80: bison input.y" echo input.at:80 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:4.6-15: warning: type clash on default action: != <> input.y:5.6-8: warning: type clash on default action: != <> input.y:6.5: warning: empty rule for typed nonterminal, and no action " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:80: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 4 ) # 4. input.at:89: Unused values at_setup_line='input.at:89' at_desc='Unused values' $at_quiet $ECHO_N " 4: Unused values $ECHO_C" at_xfail=no ( echo "4. input.at:89: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token INT %type a b c d e f g h i j k l %destructor { destroy ($$); } INT a b c d e f g h i j k l %% start: 'a' a { $2 } | 'b' b { $2 } | 'c' c { $2 } | 'd' d { $2 } | 'e' e { $2 } | 'f' f { $2 } | 'g' g { $2 } | 'h' h { $2 } | 'i' i { $2 } | 'j' j { $2 } | 'k' k { $2 } | 'l' l { $2 } ; a: INT | INT { } INT { } INT { }; b: INT | /* empty */; c: INT | INT { $1 } INT { } INT { }; d: INT | INT { } INT { $1 } INT { }; e: INT | INT { } INT { } INT { $1 }; f: INT | INT { } INT { } INT { $$ = $1 + $3 + $5; }; g: INT | INT { $$ } INT { $$ } INT { }; h: INT | INT { $$ } INT { $$ = $2 } INT { }; i: INT | INT INT { } { $$ = $1 + $2; }; j: INT | INT INT { $$ = 1; } { $$ = $1 + $2; }; k: INT | INT INT { $$; } { $$ = $3; } { }; l: INT | INT { $$ = $1; } INT { $$ = $2 + $3; } INT { $$ = $4 + $5; }; _ATEOF $at_traceoff echo "input.at:148: bison input.y" echo input.at:148 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:11.10-32: warning: unset value: \$\$ input.y:11.10-32: warning: unused value: \$1 input.y:11.10-32: warning: unused value: \$3 input.y:11.10-32: warning: unused value: \$5 input.y:12.9: warning: empty rule for typed nonterminal, and no action input.y:13.10-35: warning: unset value: \$\$ input.y:13.10-35: warning: unused value: \$3 input.y:13.10-35: warning: unused value: \$5 input.y:14.10-35: warning: unset value: \$\$ input.y:14.10-35: warning: unused value: \$3 input.y:14.10-35: warning: unused value: \$5 input.y:15.10-36: warning: unset value: \$\$ input.y:15.10-36: warning: unused value: \$3 input.y:15.10-36: warning: unused value: \$5 input.y:17.10-38: warning: unset value: \$\$ input.y:17.10-38: warning: unused value: \$1 input.y:17.10-38: warning: unused value: \$2 input.y:17.10-38: warning: unused value: \$3 input.y:17.10-38: warning: unused value: \$4 input.y:17.10-38: warning: unused value: \$5 input.y:18.10-43: warning: unset value: \$\$ input.y:18.10-43: warning: unused value: \$1 input.y:18.10-43: warning: unused value: \$3 input.y:18.10-43: warning: unused value: \$4 input.y:18.10-43: warning: unused value: \$5 input.y:20.10-55: warning: unused value: \$3 input.y:21.10-41: warning: unset value: \$\$ input.y:21.10-41: warning: unused value: \$1 input.y:21.10-41: warning: unused value: \$2 input.y:21.10-41: warning: unused value: \$4 " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:148: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 5 ) # 5. input.at:157: Incompatible Aliases at_setup_line='input.at:157' at_desc='Incompatible Aliases' $at_quiet $ECHO_N " 5: Incompatible Aliases $ECHO_C" at_xfail=no ( echo "5. input.at:157: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token foo "foo" %type foo %printer {bar} foo %destructor {bar} foo %left foo %type "foo" %printer {baz} "foo" %destructor {baz} "foo" %left "foo" %% exp: foo; _ATEOF $at_traceoff echo "input.at:185: bison input.y" echo input.at:185 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:8.7-11: %type redeclaration for foo input.y:3.7-11: first declaration input.y:10.13-17: %destructor redeclaration for foo input.y:5.13-17: first declaration input.y:9.10-14: %printer redeclaration for foo input.y:10.13-17: first declaration input.y:11.1-5: %left redeclaration for foo input.y:6.1-5: first declaration " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "input.at:185: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 6 ) # 6. input.at:198: Torturing the Scanner at_setup_line='input.at:198' at_desc='Torturing the Scanner' $at_quiet $ECHO_N " 6: Torturing the Scanner $ECHO_C" at_xfail=no ( echo "6. input.at:198: testing ..." $at_traceon cat >input.y <<'_ATEOF' _ATEOF $at_traceoff echo "input.at:204: bison input.y" echo input.at:204 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:1.1: syntax error, unexpected end of file " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "input.at:204: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input.y <<'_ATEOF' {} _ATEOF $at_traceoff echo "input.at:212: bison input.y" echo input.at:212 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:1.1-2: syntax error, unexpected {...} " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "input.at:212: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ /* This is seen in GCC: a %{ and %} in middle of a comment. */ const char *foo = "So %{ and %} can be here too."; #if 0 /* These examples test Bison while not stressing C compilers too much. Many C compilers mishandle backslash-newlines, so this part of the test is inside "#if 0". The comment and string are written so that the "#endif" will be seen regardless of the C compiler bugs that we know about, namely: HP C (as of late 2002) mishandles *\[newline]\[newline]/ within a comment. The Apple Darwin compiler (as of late 2002) mishandles \\[newline]' within a character constant. */ /\ * A comment with backslash-newlines in it. %} *\ \ / /* { Close the above comment, if the C compiler mishandled it. */ char str[] = "\\ " A string with backslash-newlines in it %{ %} \\ \ ""; char apostrophe = '\''; #endif #include %} /* %{ and %} can be here too. */ %{ /* Exercise pre-prologue dependency to %union. */ typedef int value; %} /* Exercise M4 quoting: ']]', 0. */ /* Also exercise %union. */ %union { value ival; /* A comment to exercise an old bug. */ }; /* Exercise post-prologue dependency to %union. */ %{ static YYSTYPE value_as_yystype (value val); /* Exercise quotes in declarations. */ char quote[] = "]],"; %} %{ static void yyerror (const char *s); static int yylex (void); %} %type '[' /* Exercise quotes in strings. */ %token FAKE "fake [] \a\b\f\n\r\t\v\"\'\?\\\u005B\U0000005c ??!??'??(??)??-??/?? \x1\1" %% /* Exercise M4 quoting: ']]', [, 1. */ exp: '[' '\1' two '$' '@' '{' oline output.or.oline.opt { /* Exercise quotes in braces. */ char tmp[] = "[%c],\n"; printf (tmp, $1); } ; two: '\x000000000000000000000000000000000000000000000000000000000000000000002'; oline: '@' 'o' 'l' 'i' 'n' 'e' '@' '_' '_' 'o' 'l' 'i' 'n' 'e' '_' '_'; output.or.oline.opt: ;|oline;;|output;;; output: '#' 'o' 'u' 't' 'p' 'u' 't' ' '; %% /* Exercise M4 quoting: ']]', [, 2. */ static YYSTYPE value_as_yystype (value val) { YYSTYPE res; res.ival = val; return res; } static int yylex (void) { static const char *input = "[\1\2$@{@oline@__oline__\ #output "; /* " */ yylval = value_as_yystype (*input); return *input++; } static void yyerror (const char *msg) { fprintf (stderr, "%s\n", msg); } _ATEOF # Pacify Emacs'font-lock-mode: " cat >main.c <<'_ATEOF' typedef int value; #include "input.h" int yyparse (void); int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "input.at:342: bison -d -v -o input.c input.y" echo input.at:342 >$at_check_line_file ( $at_traceon; bison -d -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:342: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "input.at:343: \$CC \$CFLAGS \$CPPFLAGS -o input.o -c input.c" echo input.at:343 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o input.o -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:343: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "input.at:344: \$CC \$CFLAGS \$CPPFLAGS -o main.o -c main.c" echo input.at:344 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o main.o -c main.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:344: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "input.at:345: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.o main.o \$LIBS" echo input.at:345 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.o main.o $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:345: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "input.at:348: \$PREPARSER ./input" echo input.at:348 >$at_check_line_file ( $at_traceon; $PREPARSER ./input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "[[], " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:348: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 7 ) # 7. input.at:357: Typed symbol aliases at_setup_line='input.at:357' at_desc='Typed symbol aliases' $at_quiet $ECHO_N " 7: Typed symbol aliases $ECHO_C" at_xfail=no ( echo "7. input.at:357: testing ..." $at_traceon # Bison 2.0 broke typed symbol aliases - ensure they work. cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %union { int val; }; %token MY_TOKEN "MY TOKEN" %type exp %% exp: "MY TOKEN"; %% _ATEOF $at_traceoff echo "input.at:373: bison -o input.c input.y" echo input.at:373 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:373: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 8 ) # 8. input.at:393: Require 1.0 at_setup_line='input.at:393' at_desc='Require 1.0' $at_quiet $ECHO_N " 8: Require 1.0 $ECHO_C" at_xfail=no ( echo "8. input.at:393: testing ..." $at_traceon cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %require "1.0"; %% empty_file:; _ATEOF $at_traceoff echo "input.at:393: bison -o input.c input.y" echo input.at:393 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:393: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 9 ) # 9. input.at:394: Require 2.3 at_setup_line='input.at:394' at_desc='Require 2.3' $at_quiet $ECHO_N " 9: Require 2.3 $ECHO_C" at_xfail=no ( echo "9. input.at:394: testing ..." $at_traceon cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %require "2.3"; %% empty_file:; _ATEOF $at_traceoff echo "input.at:394: bison -o input.c input.y" echo input.at:394 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "input.at:394: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 10 ) # 10. input.at:396: Require 100.0 at_setup_line='input.at:396' at_desc='Require 100.0' $at_quiet $ECHO_N " 10: Require 100.0 $ECHO_C" at_xfail=no ( echo "10. input.at:396: testing ..." $at_traceon cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %require "100.0"; %% empty_file:; _ATEOF $at_traceoff echo "input.at:396: bison -o input.c input.y" echo input.at:396 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 63) ;; *) echo "input.at:396: exit code was $at_status, expected 63" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-2 ) # Banner 2. output.at:19 cat <<\_ATEOF Output file names. _ATEOF ;; 11 ) # 11. output.at:43: Output files: -dv at_setup_line='output.at:43' at_desc='Output files: -dv ' $at_quiet $ECHO_N " 11: Output files: -dv $ECHO_C" at_xfail=no ( echo "11. output.at:43: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %% foo: {}; _ATEOF $at_traceoff echo "output.at:43: bison -dv foo.y " echo output.at:43 >$at_check_line_file ( $at_traceon; bison -dv foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:43: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:43: ls foo.output foo.tab.c foo.tab.h" echo output.at:43 >$at_check_line_file ( $at_traceon; ls foo.output foo.tab.c foo.tab.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:43: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 12 ) # 12. output.at:46: Output files: -dv >&- at_setup_line='output.at:46' at_desc='Output files: -dv >&-' $at_quiet $ECHO_N " 12: Output files: -dv >&- $ECHO_C" at_xfail=no ( echo "12. output.at:46: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %% foo: {}; _ATEOF $at_traceoff echo "output.at:46: bison -dv foo.y >&-" echo output.at:46 >$at_check_line_file ( $at_traceon; bison -dv foo.y >&- ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:46: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:46: ls foo.output foo.tab.c foo.tab.h" echo output.at:46 >$at_check_line_file ( $at_traceon; ls foo.output foo.tab.c foo.tab.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:46: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 13 ) # 13. output.at:48: Output files: -dv -o foo.c at_setup_line='output.at:48' at_desc='Output files: -dv -o foo.c ' $at_quiet $ECHO_N " 13: Output files: -dv -o foo.c $ECHO_C" at_xfail=no ( echo "13. output.at:48: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %% foo: {}; _ATEOF $at_traceoff echo "output.at:48: bison -dv -o foo.c foo.y " echo output.at:48 >$at_check_line_file ( $at_traceon; bison -dv -o foo.c foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:48: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:48: ls foo.c foo.h foo.output" echo output.at:48 >$at_check_line_file ( $at_traceon; ls foo.c foo.h foo.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:48: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 14 ) # 14. output.at:50: Output files: -dv -o foo.tab.c at_setup_line='output.at:50' at_desc='Output files: -dv -o foo.tab.c ' $at_quiet $ECHO_N " 14: Output files: -dv -o foo.tab.c $ECHO_C" at_xfail=no ( echo "14. output.at:50: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %% foo: {}; _ATEOF $at_traceoff echo "output.at:50: bison -dv -o foo.tab.c foo.y " echo output.at:50 >$at_check_line_file ( $at_traceon; bison -dv -o foo.tab.c foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:50: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:50: ls foo.output foo.tab.c foo.tab.h" echo output.at:50 >$at_check_line_file ( $at_traceon; ls foo.output foo.tab.c foo.tab.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:50: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 15 ) # 15. output.at:52: Output files: -dv -y at_setup_line='output.at:52' at_desc='Output files: -dv -y ' $at_quiet $ECHO_N " 15: Output files: -dv -y $ECHO_C" at_xfail=no ( echo "15. output.at:52: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %% foo: {}; _ATEOF $at_traceoff echo "output.at:52: bison -dv -y foo.y " echo output.at:52 >$at_check_line_file ( $at_traceon; bison -dv -y foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:52: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:52: ls y.output y.tab.c y.tab.h" echo output.at:52 >$at_check_line_file ( $at_traceon; ls y.output y.tab.c y.tab.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:52: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 16 ) # 16. output.at:54: Output files: -dv -b bar at_setup_line='output.at:54' at_desc='Output files: -dv -b bar ' $at_quiet $ECHO_N " 16: Output files: -dv -b bar $ECHO_C" at_xfail=no ( echo "16. output.at:54: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %% foo: {}; _ATEOF $at_traceoff echo "output.at:54: bison -dv -b bar foo.y " echo output.at:54 >$at_check_line_file ( $at_traceon; bison -dv -b bar foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:54: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:54: ls bar.output bar.tab.c bar.tab.h" echo output.at:54 >$at_check_line_file ( $at_traceon; ls bar.output bar.tab.c bar.tab.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:54: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 17 ) # 17. output.at:56: Output files: -dv -g -o foo.c at_setup_line='output.at:56' at_desc='Output files: -dv -g -o foo.c ' $at_quiet $ECHO_N " 17: Output files: -dv -g -o foo.c $ECHO_C" at_xfail=no ( echo "17. output.at:56: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %% foo: {}; _ATEOF $at_traceoff echo "output.at:56: bison -dv -g -o foo.c foo.y " echo output.at:56 >$at_check_line_file ( $at_traceon; bison -dv -g -o foo.c foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:56: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:56: ls foo.c foo.h foo.output foo.vcg" echo output.at:56 >$at_check_line_file ( $at_traceon; ls foo.c foo.h foo.output foo.vcg ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:56: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 18 ) # 18. output.at:60: Output files: %defines %verbose at_setup_line='output.at:60' at_desc='Output files: %defines %verbose ' $at_quiet $ECHO_N " 18: Output files: %defines %verbose $ECHO_C" at_xfail=no ( echo "18. output.at:60: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %defines %verbose %% foo: {}; _ATEOF $at_traceoff echo "output.at:60: bison foo.y " echo output.at:60 >$at_check_line_file ( $at_traceon; bison foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:60: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:60: ls foo.output foo.tab.c foo.tab.h" echo output.at:60 >$at_check_line_file ( $at_traceon; ls foo.output foo.tab.c foo.tab.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:60: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 19 ) # 19. output.at:62: Output files: %defines %verbose %yacc at_setup_line='output.at:62' at_desc='Output files: %defines %verbose %yacc ' $at_quiet $ECHO_N " 19: Output files: %defines %verbose %yacc $ECHO_C" at_xfail=no ( echo "19. output.at:62: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %defines %verbose %yacc %% foo: {}; _ATEOF $at_traceoff echo "output.at:62: bison foo.y " echo output.at:62 >$at_check_line_file ( $at_traceon; bison foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:62: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:62: ls y.output y.tab.c y.tab.h" echo output.at:62 >$at_check_line_file ( $at_traceon; ls y.output y.tab.c y.tab.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:62: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 20 ) # 20. output.at:65: Output files: %defines %verbose %yacc at_setup_line='output.at:65' at_desc='Output files: %defines %verbose %yacc ' $at_quiet $ECHO_N " 20: Output files: %defines %verbose %yacc $ECHO_C" at_xfail=no ( echo "20. output.at:65: testing ..." $at_traceon case "foo.yy" in */*) mkdir `echo "foo.yy" | sed 's,/.*,,'`;; esac cat >foo.yy <<'_ATEOF' %defines %verbose %yacc %% foo: {}; _ATEOF $at_traceoff echo "output.at:65: bison foo.yy " echo output.at:65 >$at_check_line_file ( $at_traceon; bison foo.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:65: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:65: ls y.output y.tab.c y.tab.h" echo output.at:65 >$at_check_line_file ( $at_traceon; ls y.output y.tab.c y.tab.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:65: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 21 ) # 21. output.at:69: Output files: %file-prefix="bar" %defines %verbose at_setup_line='output.at:69' at_desc='Output files: %file-prefix="bar" %defines %verbose ' $at_quiet $ECHO_N " 21: Output files: %file-prefix="bar" %defines %verbose $ECHO_C" at_xfail=no ( echo "21. output.at:69: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %file-prefix="bar" %defines %verbose %% foo: {}; _ATEOF $at_traceoff echo "output.at:69: bison foo.y " echo output.at:69 >$at_check_line_file ( $at_traceon; bison foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:69: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:69: ls bar.output bar.tab.c bar.tab.h" echo output.at:69 >$at_check_line_file ( $at_traceon; ls bar.output bar.tab.c bar.tab.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:69: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 22 ) # 22. output.at:71: Output files: %output="bar.c" %defines %verbose %yacc at_setup_line='output.at:71' at_desc='Output files: %output="bar.c" %defines %verbose %yacc ' $at_quiet $ECHO_N " 22: Output files: %output="bar.c" %defines %verbose %yacc $ECHO_C" at_xfail=no ( echo "22. output.at:71: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %output="bar.c" %defines %verbose %yacc %% foo: {}; _ATEOF $at_traceoff echo "output.at:71: bison foo.y " echo output.at:71 >$at_check_line_file ( $at_traceon; bison foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:71: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:71: ls bar.output bar.c bar.h" echo output.at:71 >$at_check_line_file ( $at_traceon; ls bar.output bar.c bar.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:71: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 23 ) # 23. output.at:75: Output files: %file-prefix="baz" %output="bar.c" %defines %verbose %yacc at_setup_line='output.at:75' at_desc='Output files: %file-prefix="baz" %output="bar.c" %defines %verbose %yacc ' $at_quiet $ECHO_N " 23: Output files: %file-prefix="baz" %output="bar.c" %defines %verbose %yacc $ECHO_C" at_xfail=no ( echo "23. output.at:75: testing ..." $at_traceon case "foo.y" in */*) mkdir `echo "foo.y" | sed 's,/.*,,'`;; esac cat >foo.y <<'_ATEOF' %file-prefix="baz" %output="bar.c" %defines %verbose %yacc %% foo: {}; _ATEOF $at_traceoff echo "output.at:75: bison foo.y " echo output.at:75 >$at_check_line_file ( $at_traceon; bison foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:75: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:75: ls bar.output bar.c bar.h" echo output.at:75 >$at_check_line_file ( $at_traceon; ls bar.output bar.c bar.h ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:75: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 24 ) # 24. output.at:80: Output files: %defines %verbose at_setup_line='output.at:80' at_desc='Output files: %defines %verbose ' $at_quiet $ECHO_N " 24: Output files: %defines %verbose $ECHO_C" at_xfail=no ( echo "24. output.at:80: testing ..." $at_traceon case "foo.yy" in */*) mkdir `echo "foo.yy" | sed 's,/.*,,'`;; esac cat >foo.yy <<'_ATEOF' %defines %verbose %% foo: {}; _ATEOF $at_traceoff echo "output.at:80: bison foo.yy " echo output.at:80 >$at_check_line_file ( $at_traceon; bison foo.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:80: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:80: ls foo.output foo.tab.cc foo.tab.hh" echo output.at:80 >$at_check_line_file ( $at_traceon; ls foo.output foo.tab.cc foo.tab.hh ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:80: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 25 ) # 25. output.at:83: Output files: %defines %verbose -o foo.c at_setup_line='output.at:83' at_desc='Output files: %defines %verbose -o foo.c ' $at_quiet $ECHO_N " 25: Output files: %defines %verbose -o foo.c $ECHO_C" at_xfail=no ( echo "25. output.at:83: testing ..." $at_traceon case "foo.yy" in */*) mkdir `echo "foo.yy" | sed 's,/.*,,'`;; esac cat >foo.yy <<'_ATEOF' %defines %verbose %% foo: {}; _ATEOF $at_traceoff echo "output.at:83: bison -o foo.c foo.yy " echo output.at:83 >$at_check_line_file ( $at_traceon; bison -o foo.c foo.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:83: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:83: ls foo.c foo.h foo.output" echo output.at:83 >$at_check_line_file ( $at_traceon; ls foo.c foo.h foo.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:83: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 26 ) # 26. output.at:87: Output files: --defines=foo.hpp -o foo.c++ at_setup_line='output.at:87' at_desc='Output files: --defines=foo.hpp -o foo.c++ ' $at_quiet $ECHO_N " 26: Output files: --defines=foo.hpp -o foo.c++ $ECHO_C" at_xfail=no ( echo "26. output.at:87: testing ..." $at_traceon case "foo.yy" in */*) mkdir `echo "foo.yy" | sed 's,/.*,,'`;; esac cat >foo.yy <<'_ATEOF' %% foo: {}; _ATEOF $at_traceoff echo "output.at:87: bison --defines=foo.hpp -o foo.c++ foo.yy " echo output.at:87 >$at_check_line_file ( $at_traceon; bison --defines=foo.hpp -o foo.c++ foo.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:87: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:87: ls foo.c++ foo.hpp" echo output.at:87 >$at_check_line_file ( $at_traceon; ls foo.c++ foo.hpp ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:87: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 27 ) # 27. output.at:91: Output files: -o foo.c++ --graph=foo.gph at_setup_line='output.at:91' at_desc='Output files: -o foo.c++ --graph=foo.gph ' $at_quiet $ECHO_N " 27: Output files: -o foo.c++ --graph=foo.gph $ECHO_C" at_xfail=no ( echo "27. output.at:91: testing ..." $at_traceon case "foo.yy" in */*) mkdir `echo "foo.yy" | sed 's,/.*,,'`;; esac cat >foo.yy <<'_ATEOF' %% foo: {}; _ATEOF $at_traceoff echo "output.at:91: bison -o foo.c++ --graph=foo.gph foo.yy " echo output.at:91 >$at_check_line_file ( $at_traceon; bison -o foo.c++ --graph=foo.gph foo.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:91: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:91: ls foo.c++ foo.gph" echo output.at:91 >$at_check_line_file ( $at_traceon; ls foo.c++ foo.gph ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:91: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 28 ) # 28. output.at:105: Output files: %skeleton "lalr1.cc" %defines %verbose at_setup_line='output.at:105' at_desc='Output files: %skeleton "lalr1.cc" %defines %verbose ' $at_quiet $ECHO_N " 28: Output files: %skeleton "lalr1.cc" %defines %verbose $ECHO_C" at_xfail=no ( echo "28. output.at:105: testing ..." $at_traceon case "foo.yy" in */*) mkdir `echo "foo.yy" | sed 's,/.*,,'`;; esac cat >foo.yy <<'_ATEOF' %skeleton "lalr1.cc" %defines %verbose %% foo: {}; _ATEOF $at_traceoff echo "output.at:105: bison foo.yy " echo output.at:105 >$at_check_line_file ( $at_traceon; bison foo.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:105: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:105: ls foo.tab.cc foo.tab.hh foo.output location.hh stack.hh position.hh" echo output.at:105 >$at_check_line_file ( $at_traceon; ls foo.tab.cc foo.tab.hh foo.output location.hh stack.hh position.hh ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:105: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 29 ) # 29. output.at:109: Output files: %skeleton "lalr1.cc" %defines %verbose at_setup_line='output.at:109' at_desc='Output files: %skeleton "lalr1.cc" %defines %verbose ' $at_quiet $ECHO_N " 29: Output files: %skeleton "lalr1.cc" %defines %verbose $ECHO_C" at_xfail=no ( echo "29. output.at:109: testing ..." $at_traceon case "subdir/foo.yy" in */*) mkdir `echo "subdir/foo.yy" | sed 's,/.*,,'`;; esac cat >subdir/foo.yy <<'_ATEOF' %skeleton "lalr1.cc" %defines %verbose %% foo: {}; _ATEOF $at_traceoff echo "output.at:109: bison subdir/foo.yy " echo output.at:109 >$at_check_line_file ( $at_traceon; bison subdir/foo.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:109: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:109: ls foo.tab.cc foo.tab.hh foo.output location.hh stack.hh position.hh" echo output.at:109 >$at_check_line_file ( $at_traceon; ls foo.tab.cc foo.tab.hh foo.output location.hh stack.hh position.hh ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:109: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Also make sure that the includes do not refer to the subdirectory. $at_traceoff echo "output.at:109: grep 'include .subdir/' foo.tab.cc" echo output.at:109 >$at_check_line_file ( $at_traceon; grep 'include .subdir/' foo.tab.cc ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "output.at:109: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:109: grep 'include .subdir/' foo.tab.hh" echo output.at:109 >$at_check_line_file ( $at_traceon; grep 'include .subdir/' foo.tab.hh ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "output.at:109: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 30 ) # 30. output.at:114: Output files: %skeleton "lalr1.cc" %defines %verbose -o subdir/foo.cc at_setup_line='output.at:114' at_desc='Output files: %skeleton "lalr1.cc" %defines %verbose -o subdir/foo.cc ' $at_quiet $ECHO_N " 30: Output files: %skeleton "lalr1.cc" %defines %verbose -o subdir/foo.cc $ECHO_C" at_xfail=no ( echo "30. output.at:114: testing ..." $at_traceon case "subdir/foo.yy" in */*) mkdir `echo "subdir/foo.yy" | sed 's,/.*,,'`;; esac cat >subdir/foo.yy <<'_ATEOF' %skeleton "lalr1.cc" %defines %verbose %% foo: {}; _ATEOF $at_traceoff echo "output.at:114: bison -o subdir/foo.cc subdir/foo.yy " echo output.at:114 >$at_check_line_file ( $at_traceon; bison -o subdir/foo.cc subdir/foo.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:114: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:114: ls subdir/foo.cc subdir/foo.hh subdir/foo.output subdir/location.hh subdir/stack.hh subdir/position.hh" echo output.at:114 >$at_check_line_file ( $at_traceon; ls subdir/foo.cc subdir/foo.hh subdir/foo.output subdir/location.hh subdir/stack.hh subdir/position.hh ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "output.at:114: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Also make sure that the includes do not refer to the subdirectory. $at_traceoff echo "output.at:114: grep 'include .subdir/' subdir/foo.cc" echo output.at:114 >$at_check_line_file ( $at_traceon; grep 'include .subdir/' subdir/foo.cc ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "output.at:114: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "output.at:114: grep 'include .subdir/' subdir/foo.hh" echo output.at:114 >$at_check_line_file ( $at_traceon; grep 'include .subdir/' subdir/foo.hh ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "output.at:114: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-3 ) # Banner 3. sets.at:59 cat <<\_ATEOF Grammar Sets (Firsts etc.). _ATEOF ;; 31 ) # 31. sets.at:66: Nullable at_setup_line='sets.at:66' at_desc='Nullable' $at_quiet $ECHO_N " 31: Nullable $ECHO_C" at_xfail=no ( echo "31. sets.at:66: testing ..." $at_traceon # At some point, nullable had been smoking grass, and managed to say: # # Entering set_nullable # NULLABLE # 'e': yes # (null): no # ... cat >input.y <<'_ATEOF' %% e: 'e' | /* Nothing */; _ATEOF $at_traceoff echo "sets.at:81: bison --trace=sets input.y" echo sets.at:81 >$at_check_line_file ( $at_traceon; bison --trace=sets input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:81: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >extract.sed <<'_ATEOF' #n /^NULLABLE$/ { :null p n /^[ ]*$/ !b null } /^FIRSTS$/ { :firsts p n /^[ ]*$/ !b firsts } /^FDERIVES$/ { :fderiv p n /^[ ]*$/ !b fderiv } /^DERIVES$/ { :deriv p n /^[ ]*$/ !b deriv } _ATEOF $at_traceoff echo "sets.at:82: sed -f extract.sed stderr" echo sets.at:82 >$at_check_line_file ( $at_traceon; sed -f extract.sed stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:82: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "sets.at:82: mv stdout sets" echo sets.at:82 >$at_check_line_file ( $at_traceon; mv stdout sets ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:82: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "sets.at:107: cat sets" echo sets.at:107 >$at_check_line_file ( $at_traceon; cat sets ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "DERIVES \$accept derives 0 e \$end e derives 1 'e' 2 /* empty */ NULLABLE \$accept: no e: yes FIRSTS \$accept firsts \$accept e e firsts e FDERIVES \$accept derives 0 e \$end 1 'e' 2 /* empty */ e derives 1 'e' 2 /* empty */ " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:107: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 32 ) # 32. sets.at:151: Broken Closure at_setup_line='sets.at:151' at_desc='Broken Closure' $at_quiet $ECHO_N " 32: Broken Closure $ECHO_C" at_xfail=no ( echo "32. sets.at:151: testing ..." $at_traceon cat >input.y <<'_ATEOF' %% a: b; b: c; c: d; d: e; e: f; f: g; g: h; h: 'h'; _ATEOF $at_traceoff echo "sets.at:165: bison --trace=sets input.y" echo sets.at:165 >$at_check_line_file ( $at_traceon; bison --trace=sets input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:165: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "sets.at:183: sed -n 's/[ ]*\$//;/^RTC: Firsts Output BEGIN/,/^RTC: Firsts Output END/p' stderr" echo sets.at:183 >$at_check_line_file ( $at_traceon; sed -n 's/[ ]*$//;/^RTC: Firsts Output BEGIN/,/^RTC: Firsts Output END/p' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "RTC: Firsts Output BEGIN 012345678 .---------. 0|111111111| 1| 11111111| 2| 1111111| 3| 111111| 4| 11111| 5| 1111| 6| 111| 7| 11| 8| 1| \`---------' RTC: Firsts Output END " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:183: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 33 ) # 33. sets.at:193: Firsts at_setup_line='sets.at:193' at_desc='Firsts' $at_quiet $ECHO_N " 33: Firsts $ECHO_C" at_xfail=no ( echo "33. sets.at:193: testing ..." $at_traceon cat >input.y <<'_ATEOF' %nonassoc '<' '>' %left '+' '-' %right '^' '=' %% exp: exp '<' exp | exp '>' exp | exp '+' exp | exp '-' exp | exp '^' exp | exp '=' exp | "exp" ; _ATEOF $at_traceoff echo "sets.at:211: bison --trace=sets input.y" echo sets.at:211 >$at_check_line_file ( $at_traceon; bison --trace=sets input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:211: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >extract.sed <<'_ATEOF' #n /^NULLABLE$/ { :null p n /^[ ]*$/ !b null } /^FIRSTS$/ { :firsts p n /^[ ]*$/ !b firsts } /^FDERIVES$/ { :fderiv p n /^[ ]*$/ !b fderiv } /^DERIVES$/ { :deriv p n /^[ ]*$/ !b deriv } _ATEOF $at_traceoff echo "sets.at:212: sed -f extract.sed stderr" echo sets.at:212 >$at_check_line_file ( $at_traceon; sed -f extract.sed stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:212: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "sets.at:212: mv stdout sets" echo sets.at:212 >$at_check_line_file ( $at_traceon; mv stdout sets ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:212: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "sets.at:252: cat sets" echo sets.at:252 >$at_check_line_file ( $at_traceon; cat sets ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "DERIVES \$accept derives 0 exp \$end exp derives 1 exp '<' exp 2 exp '>' exp 3 exp '+' exp 4 exp '-' exp 5 exp '^' exp 6 exp '=' exp 7 \"exp\" NULLABLE \$accept: no exp: no FIRSTS \$accept firsts \$accept exp exp firsts exp FDERIVES \$accept derives 0 exp \$end 1 exp '<' exp 2 exp '>' exp 3 exp '+' exp 4 exp '-' exp 5 exp '^' exp 6 exp '=' exp 7 \"exp\" exp derives 1 exp '<' exp 2 exp '>' exp 3 exp '+' exp 4 exp '-' exp 5 exp '^' exp 6 exp '=' exp 7 \"exp\" " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:252: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 34 ) # 34. sets.at:269: Accept at_setup_line='sets.at:269' at_desc='Accept' $at_quiet $ECHO_N " 34: Accept $ECHO_C" at_xfail=no ( echo "34. sets.at:269: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token END 0 %% input: 'a' | '(' input ')' | '(' error END ; _ATEOF $at_traceoff echo "sets.at:281: bison -v -o input.c input.y" echo sets.at:281 >$at_check_line_file ( $at_traceon; bison -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:281: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Get the final state in the parser. $at_traceoff echo "sets.at:285: sed -n 's/.*define YYFINAL *\\([0-9][0-9]*\\)/final state \\1/p' input.c" echo sets.at:285 >$at_check_line_file ( $at_traceon; sed -n 's/.*define YYFINAL *\([0-9][0-9]*\)/final state \1/p' input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:285: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon mv stdout expout # Get the final state in the report, from the "accept" action.. $at_traceoff echo "sets.at:300: sed -n ' /^state \\(.*\\)/{ s//final state \\1/ x } / accept/{ x p q } ' input.output" echo sets.at:300 >$at_check_line_file ( $at_traceon; sed -n ' /^state \(.*\)/{ s//final state \1/ x } / accept/{ x p q } ' input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "sets.at:300: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-4 ) # Banner 4. reduce.at:19 cat <<\_ATEOF Grammar Reduction. _ATEOF ;; 35 ) # 35. reduce.at:26: Useless Terminals at_setup_line='reduce.at:26' at_desc='Useless Terminals' $at_quiet $ECHO_N " 35: Useless Terminals $ECHO_C" at_xfail=no ( echo "35. reduce.at:26: testing ..." $at_traceon cat >input.y <<'_ATEOF' %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; _ATEOF $at_traceoff echo "reduce.at:47: bison input.y" echo reduce.at:47 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:47: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "reduce.at:60: sed -n '/^Grammar/q;/^\$/!p' input.output" echo reduce.at:60 >$at_check_line_file ( $at_traceon; sed -n '/^Grammar/q;/^$/!p' input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Terminals which are not used useless1 useless2 useless3 useless4 useless5 useless6 useless7 useless8 useless9 " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:60: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 36 ) # 36. reduce.at:70: Useless Nonterminals at_setup_line='reduce.at:70' at_desc='Useless Nonterminals' $at_quiet $ECHO_N " 36: Useless Nonterminals $ECHO_C" at_xfail=no ( echo "36. reduce.at:70: testing ..." $at_traceon cat >input.y <<'_ATEOF' %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; _ATEOF $at_traceoff echo "reduce.at:102: bison input.y" echo reduce.at:102 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: warning: 9 useless nonterminals input.y:4.8-15: warning: useless nonterminal: useless1 input.y:5.8-15: warning: useless nonterminal: useless2 input.y:6.8-15: warning: useless nonterminal: useless3 input.y:7.8-15: warning: useless nonterminal: useless4 input.y:8.8-15: warning: useless nonterminal: useless5 input.y:9.8-15: warning: useless nonterminal: useless6 input.y:10.8-15: warning: useless nonterminal: useless7 input.y:11.8-15: warning: useless nonterminal: useless8 input.y:12.8-15: warning: useless nonterminal: useless9 " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:102: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "reduce.at:115: sed -n '/^Grammar/q;/^\$/!p' input.output" echo reduce.at:115 >$at_check_line_file ( $at_traceon; sed -n '/^Grammar/q;/^$/!p' input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Useless nonterminals useless1 useless2 useless3 useless4 useless5 useless6 useless7 useless8 useless9 " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:115: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 37 ) # 37. reduce.at:125: Useless Rules at_setup_line='reduce.at:125' at_desc='Useless Rules' $at_quiet $ECHO_N " 37: Useless Rules $ECHO_C" at_xfail=no ( echo "37. reduce.at:125: testing ..." $at_traceon cat >input.y <<'_ATEOF' %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'; _ATEOF $at_traceoff echo "reduce.at:166: bison input.y" echo reduce.at:166 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: warning: 9 useless nonterminals and 9 useless rules input.y:6.1-8: warning: useless nonterminal: useless1 input.y:7.1-8: warning: useless nonterminal: useless2 input.y:8.1-8: warning: useless nonterminal: useless3 input.y:9.1-8: warning: useless nonterminal: useless4 input.y:10.1-8: warning: useless nonterminal: useless5 input.y:11.1-8: warning: useless nonterminal: useless6 input.y:12.1-8: warning: useless nonterminal: useless7 input.y:13.1-8: warning: useless nonterminal: useless8 input.y:14.1-8: warning: useless nonterminal: useless9 input.y:6.11-13: warning: useless rule: useless1: '1' input.y:7.11-13: warning: useless rule: useless2: '2' input.y:8.11-13: warning: useless rule: useless3: '3' input.y:9.11-13: warning: useless rule: useless4: '4' input.y:10.11-13: warning: useless rule: useless5: '5' input.y:11.11-13: warning: useless rule: useless6: '6' input.y:12.11-13: warning: useless rule: useless7: '7' input.y:13.11-13: warning: useless rule: useless8: '8' input.y:14.11-13: warning: useless rule: useless9: '9' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:166: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "reduce.at:199: sed -n '/^Grammar/q;/^\$/!p' input.output" echo reduce.at:199 >$at_check_line_file ( $at_traceon; sed -n '/^Grammar/q;/^$/!p' input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "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_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:199: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 38 ) # 38. reduce.at:212: Reduced Automaton at_setup_line='reduce.at:212' at_desc='Reduced Automaton' $at_quiet $ECHO_N " 38: Reduced Automaton $ECHO_C" at_xfail=no ( echo "38. reduce.at:212: testing ..." $at_traceon # The non reduced grammar. # ------------------------ cat >not-reduced.y <<'_ATEOF' /* 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. */ } ; %% _ATEOF $at_traceoff echo "reduce.at:248: bison not-reduced.y" echo reduce.at:248 >$at_check_line_file ( $at_traceon; bison not-reduced.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "not-reduced.y: warning: 2 useless nonterminals and 3 useless rules not-reduced.y:14.1-13: warning: useless nonterminal: not_reachable not-reduced.y:11.6-19: warning: useless nonterminal: non_productive not-reduced.y:11.6-57: warning: useless rule: exp: non_productive not-reduced.y:14.16-56: warning: useless rule: not_reachable: useful not-reduced.y:17.17-18.63: warning: useless rule: non_productive: non_productive useless_token " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:248: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "reduce.at:260: sed -n '/^Grammar/q;/^\$/!p' not-reduced.output" echo reduce.at:260 >$at_check_line_file ( $at_traceon; sed -n '/^Grammar/q;/^$/!p' not-reduced.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "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 " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:260: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The reduced grammar. # -------------------- cat >reduced.y <<'_ATEOF' /* 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. */ } // ; %% _ATEOF $at_traceoff echo "reduce.at:287: bison reduced.y" echo reduce.at:287 >$at_check_line_file ( $at_traceon; bison reduced.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:287: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Comparing the parsers. cp reduced.c expout $at_traceoff echo "reduce.at:291: sed 's/not-reduced/reduced/g' not-reduced.c" echo reduce.at:291 >$at_check_line_file ( $at_traceon; sed 's/not-reduced/reduced/g' not-reduced.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:291: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 39 ) # 39. reduce.at:301: Underivable Rules at_setup_line='reduce.at:301' at_desc='Underivable Rules' $at_quiet $ECHO_N " 39: Underivable Rules $ECHO_C" at_xfail=no ( echo "39. reduce.at:301: testing ..." $at_traceon cat >input.y <<'_ATEOF' %verbose %output="input.c" %token useful %% exp: useful | underivable; underivable: indirection; indirection: underivable; _ATEOF $at_traceoff echo "reduce.at:322: bison input.y" echo reduce.at:322 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: warning: 2 useless nonterminals and 3 useless rules input.y:5.15-25: warning: useless nonterminal: underivable input.y:6.14-24: warning: useless nonterminal: indirection input.y:5.15-25: warning: useless rule: exp: underivable input.y:6.14-24: warning: useless rule: underivable: indirection input.y:7.14-24: warning: useless rule: indirection: underivable " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:322: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "reduce.at:332: sed -n '/^Grammar/q;/^\$/!p' input.output" echo reduce.at:332 >$at_check_line_file ( $at_traceon; sed -n '/^Grammar/q;/^$/!p' input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Useless nonterminals underivable indirection Useless rules 2 exp: underivable 3 underivable: indirection 4 indirection: underivable " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "reduce.at:332: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 40 ) # 40. reduce.at:342: Empty Language at_setup_line='reduce.at:342' at_desc='Empty Language' $at_quiet $ECHO_N " 40: Empty Language $ECHO_C" at_xfail=no ( echo "40. reduce.at:342: testing ..." $at_traceon cat >input.y <<'_ATEOF' %output="input.c" %% exp: exp; _ATEOF $at_traceoff echo "reduce.at:353: bison input.y" echo reduce.at:353 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: warning: 2 useless nonterminals and 2 useless rules input.y:3.1-3: fatal error: start symbol exp does not derive any sentence " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "reduce.at:353: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-5 ) # Banner 5. synclines.at:19 cat <<\_ATEOF User Actions. _ATEOF ;; 41 ) # 41. synclines.at:95: Prologue synch line at_setup_line='synclines.at:95' at_desc='Prologue synch line' $at_quiet $ECHO_N " 41: Prologue synch line $ECHO_C" at_xfail=no ( echo "41. synclines.at:95: testing ..." $at_traceon # It seems impossible to find a generic scheme to check the location # of an error. Even requiring GCC is not sufficient, since for instance # the version modified by Apple: # # | Reading specs from /usr/libexec/gcc/darwin/ppc/2.95.2/specs # | Apple Computer, Inc. version gcc-934.3, based on gcc version 2.95.2 # | 19991024 (release) configure:2124: $? = 0 # # instead of: # # | input.y:2: #error "2" # # it reports: # # | input.y:2: "2" # | cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode cat >syncline.c <<'_ATEOF' #error "1" _ATEOF $at_traceoff echo "synclines.at:95: \$CC \$CFLAGS \$CPPFLAGS -c syncline.c" echo synclines.at:95 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c syncline.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:95: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:95 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:95: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:95: test \"\`cat stdout\`\" = 'syncline.c:1: #error \"1\"' || exit 77" echo synclines.at:95 >$at_check_line_file ( $at_traceon; test "`cat stdout`" = 'syncline.c:1: #error "1"' || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:95: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input.y <<'_ATEOF' %{ #error "2" void yyerror (const char *s); int yylex (void); %} %% exp: '0'; _ATEOF $at_traceoff echo "synclines.at:95: bison -o input.c input.y" echo synclines.at:95 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:95: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:95: \$CC \$CFLAGS \$CPPFLAGS -c input.c" echo synclines.at:95 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:95: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:95 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:95: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:95: cat stdout" echo synclines.at:95 >$at_check_line_file ( $at_traceon; cat stdout ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "input.y:2: #error \"2\" " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:95: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 42 ) # 42. synclines.at:115: %union synch line at_setup_line='synclines.at:115' at_desc='%union synch line' $at_quiet $ECHO_N " 42: %union synch line $ECHO_C" at_xfail=no ( echo "42. synclines.at:115: testing ..." $at_traceon # It seems impossible to find a generic scheme to check the location # of an error. Even requiring GCC is not sufficient, since for instance # the version modified by Apple: # # | Reading specs from /usr/libexec/gcc/darwin/ppc/2.95.2/specs # | Apple Computer, Inc. version gcc-934.3, based on gcc version 2.95.2 # | 19991024 (release) configure:2124: $? = 0 # # instead of: # # | input.y:2: #error "2" # # it reports: # # | input.y:2: "2" # | cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode cat >syncline.c <<'_ATEOF' #error "1" _ATEOF $at_traceoff echo "synclines.at:115: \$CC \$CFLAGS \$CPPFLAGS -c syncline.c" echo synclines.at:115 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c syncline.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:115: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:115 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:115: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:115: test \"\`cat stdout\`\" = 'syncline.c:1: #error \"1\"' || exit 77" echo synclines.at:115 >$at_check_line_file ( $at_traceon; test "`cat stdout`" = 'syncline.c:1: #error "1"' || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:115: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input.y <<'_ATEOF' %union { #error "2" char dummy; } %{ void yyerror (const char *s); int yylex (void); %} %% exp: '0'; _ATEOF $at_traceoff echo "synclines.at:115: bison -o input.c input.y" echo synclines.at:115 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:115: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:115: \$CC \$CFLAGS \$CPPFLAGS -c input.c" echo synclines.at:115 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:115: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:115 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:115: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:115: cat stdout" echo synclines.at:115 >$at_check_line_file ( $at_traceon; cat stdout ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "input.y:2: #error \"2\" " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:115: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 43 ) # 43. synclines.at:138: Postprologue synch line at_setup_line='synclines.at:138' at_desc='Postprologue synch line' $at_quiet $ECHO_N " 43: Postprologue synch line $ECHO_C" at_xfail=no ( echo "43. synclines.at:138: testing ..." $at_traceon # It seems impossible to find a generic scheme to check the location # of an error. Even requiring GCC is not sufficient, since for instance # the version modified by Apple: # # | Reading specs from /usr/libexec/gcc/darwin/ppc/2.95.2/specs # | Apple Computer, Inc. version gcc-934.3, based on gcc version 2.95.2 # | 19991024 (release) configure:2124: $? = 0 # # instead of: # # | input.y:2: #error "2" # # it reports: # # | input.y:2: "2" # | cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode cat >syncline.c <<'_ATEOF' #error "1" _ATEOF $at_traceoff echo "synclines.at:138: \$CC \$CFLAGS \$CPPFLAGS -c syncline.c" echo synclines.at:138 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c syncline.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:138: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:138 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:138: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:138: test \"\`cat stdout\`\" = 'syncline.c:1: #error \"1\"' || exit 77" echo synclines.at:138 >$at_check_line_file ( $at_traceon; test "`cat stdout`" = 'syncline.c:1: #error "1"' || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:138: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input.y <<'_ATEOF' %{ void yyerror (const char *s); int yylex (void); %} %union { int ival; } %{ #error "10" %} %% exp: '0'; _ATEOF $at_traceoff echo "synclines.at:138: bison -o input.c input.y" echo synclines.at:138 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:138: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:138: \$CC \$CFLAGS \$CPPFLAGS -c input.c" echo synclines.at:138 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:138: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:138 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:138: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:138: cat stdout" echo synclines.at:138 >$at_check_line_file ( $at_traceon; cat stdout ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "input.y:10: #error \"10\" " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:138: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 44 ) # 44. synclines.at:157: Action synch line at_setup_line='synclines.at:157' at_desc='Action synch line' $at_quiet $ECHO_N " 44: Action synch line $ECHO_C" at_xfail=no ( echo "44. synclines.at:157: testing ..." $at_traceon # It seems impossible to find a generic scheme to check the location # of an error. Even requiring GCC is not sufficient, since for instance # the version modified by Apple: # # | Reading specs from /usr/libexec/gcc/darwin/ppc/2.95.2/specs # | Apple Computer, Inc. version gcc-934.3, based on gcc version 2.95.2 # | 19991024 (release) configure:2124: $? = 0 # # instead of: # # | input.y:2: #error "2" # # it reports: # # | input.y:2: "2" # | cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode cat >syncline.c <<'_ATEOF' #error "1" _ATEOF $at_traceoff echo "synclines.at:157: \$CC \$CFLAGS \$CPPFLAGS -c syncline.c" echo synclines.at:157 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c syncline.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:157: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:157 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:157: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:157: test \"\`cat stdout\`\" = 'syncline.c:1: #error \"1\"' || exit 77" echo synclines.at:157 >$at_check_line_file ( $at_traceon; test "`cat stdout`" = 'syncline.c:1: #error "1"' || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:157: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input.y <<'_ATEOF' %{ void yyerror (const char *s); int yylex (void); %} %% exp: { #error "8" }; _ATEOF $at_traceoff echo "synclines.at:157: bison -o input.c input.y" echo synclines.at:157 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:157: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:157: \$CC \$CFLAGS \$CPPFLAGS -c input.c" echo synclines.at:157 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:157: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:157 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:157: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:157: cat stdout" echo synclines.at:157 >$at_check_line_file ( $at_traceon; cat stdout ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "input.y:8: #error \"8\" " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:157: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 45 ) # 45. synclines.at:175: Epilogue synch line at_setup_line='synclines.at:175' at_desc='Epilogue synch line' $at_quiet $ECHO_N " 45: Epilogue synch line $ECHO_C" at_xfail=no ( echo "45. synclines.at:175: testing ..." $at_traceon # It seems impossible to find a generic scheme to check the location # of an error. Even requiring GCC is not sufficient, since for instance # the version modified by Apple: # # | Reading specs from /usr/libexec/gcc/darwin/ppc/2.95.2/specs # | Apple Computer, Inc. version gcc-934.3, based on gcc version 2.95.2 # | 19991024 (release) configure:2124: $? = 0 # # instead of: # # | input.y:2: #error "2" # # it reports: # # | input.y:2: "2" # | cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode cat >syncline.c <<'_ATEOF' #error "1" _ATEOF $at_traceoff echo "synclines.at:175: \$CC \$CFLAGS \$CPPFLAGS -c syncline.c" echo synclines.at:175 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c syncline.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:175: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:175 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:175: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:175: test \"\`cat stdout\`\" = 'syncline.c:1: #error \"1\"' || exit 77" echo synclines.at:175 >$at_check_line_file ( $at_traceon; test "`cat stdout`" = 'syncline.c:1: #error "1"' || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:175: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input.y <<'_ATEOF' %{ void yyerror (const char *s); int yylex (void); %} %% exp: '0'; %% #error "8" _ATEOF $at_traceoff echo "synclines.at:175: bison -o input.c input.y" echo synclines.at:175 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:175: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:175: \$CC \$CFLAGS \$CPPFLAGS -c input.c" echo synclines.at:175 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; *);; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # In case GCC displays column information, strip it down. # # input.y:4:2: #error "4" or # input.y:4.2: #error "4" or # input.y:4:2: error: #error "4" # => # input.y:4: #error "4" # $at_traceoff echo "synclines.at:175: sed -e 's/^\\([^:]*:[^:.]*\\)[.:][^:]*:\\(.*\\)\$/\\1:\\2/' -e 's/^\\([^:]*:[^:]*:\\)[^#]*\\( #error\\)/\\1\\2/' stderr" echo synclines.at:175 >$at_check_line_file ( $at_traceon; sed -e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' -e 's/^\([^:]*:[^:]*:\)[^#]*\( #error\)/\1\2/' stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:175: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "synclines.at:175: cat stdout" echo synclines.at:175 >$at_check_line_file ( $at_traceon; cat stdout ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "input.y:8: #error \"8\" " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "synclines.at:175: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-6 ) # Banner 6. headers.at:19 cat <<\_ATEOF Parser Headers. _ATEOF ;; 46 ) # 46. headers.at:27: %union and --defines at_setup_line='headers.at:27' at_desc='%union and --defines' $at_quiet $ECHO_N " 46: %union and --defines $ECHO_C" at_xfail=no ( echo "46. headers.at:27: testing ..." $at_traceon cat >input.y <<'_ATEOF' %union { int integer; char *string ; } %% exp: {}; _ATEOF $at_traceoff echo "headers.at:39: bison --defines input.y" echo headers.at:39 >$at_check_line_file ( $at_traceon; bison --defines input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:39: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 47 ) # 47. headers.at:77: Invalid CPP guards: input/input at_setup_line='headers.at:77' at_desc='Invalid CPP guards: input/input' $at_quiet $ECHO_N " 47: Invalid CPP guards: input/input $ECHO_C" at_xfail=no ( echo "47. headers.at:77: testing ..." $at_traceon # Possibly create inner directories. dirname=`(dirname input/input) 2>/dev/null || $as_expr Xinput/input : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ Xinput/input : 'X\(//\)[^/]' \| \ Xinput/input : 'X\(//\)$' \| \ Xinput/input : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo Xinput/input | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p $dirname else as_dir=$dirname as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirname" >&5 echo "$as_me: error: cannot create directory $dirname" >&2;} { (exit 1); exit 1; }; }; } cat >input/input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include void yyerror (const char *); int yylex (void); %} %% dummy:; %% #include _ATEOF $at_traceoff echo "headers.at:77: bison --defines=input/input.h --output=y.tab.c input/input.y" echo headers.at:77 >$at_check_line_file ( $at_traceon; bison --defines=input/input.h --output=y.tab.c input/input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:77: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "headers.at:77: \$CC \$CFLAGS \$CPPFLAGS -o y.tab.o -I. -c y.tab.c" echo headers.at:77 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o y.tab.o -I. -c y.tab.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:77: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 48 ) # 48. headers.at:78: Invalid CPP guards: 9foo at_setup_line='headers.at:78' at_desc='Invalid CPP guards: 9foo' $at_quiet $ECHO_N " 48: Invalid CPP guards: 9foo $ECHO_C" at_xfail=no ( echo "48. headers.at:78: testing ..." $at_traceon # Possibly create inner directories. dirname=`(dirname 9foo) 2>/dev/null || $as_expr X9foo : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X9foo : 'X\(//\)[^/]' \| \ X9foo : 'X\(//\)$' \| \ X9foo : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X9foo | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p $dirname else as_dir=$dirname as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirname" >&5 echo "$as_me: error: cannot create directory $dirname" >&2;} { (exit 1); exit 1; }; }; } cat >9foo.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include <9foo.h> void yyerror (const char *); int yylex (void); %} %% dummy:; %% #include <9foo.h> _ATEOF $at_traceoff echo "headers.at:78: bison --defines=9foo.h --output=y.tab.c 9foo.y" echo headers.at:78 >$at_check_line_file ( $at_traceon; bison --defines=9foo.h --output=y.tab.c 9foo.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:78: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "headers.at:78: \$CC \$CFLAGS \$CPPFLAGS -o y.tab.o -I. -c y.tab.c" echo headers.at:78 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o y.tab.o -I. -c y.tab.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:78: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 49 ) # 49. headers.at:87: export YYLTYPE at_setup_line='headers.at:87' at_desc='export YYLTYPE' $at_quiet $ECHO_N " 49: export YYLTYPE $ECHO_C" at_xfail=no ( echo "49. headers.at:87: testing ..." $at_traceon cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %locations %name-prefix="my_" %{ #include #include static int my_lex (void) { return EOF; } static void my_error (const char *msg) { fprintf (stderr, "%s\n", msg); } %} %% exp:; _ATEOF $at_traceoff echo "headers.at:114: bison --defines -o input.c input.y" echo headers.at:114 >$at_check_line_file ( $at_traceon; bison --defines -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:114: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # YYLTYPE should be defined, and MY_LLOC declared. cat >caller.c <<'_ATEOF' #include "input.h" YYLTYPE *my_llocp = &my_lloc; int my_parse (void); int main (void) { return my_parse (); } _ATEOF # Link and execute, just to make sure everything is fine (and in # particular, that MY_LLOC is indeed defined somewhere). $at_traceoff echo "headers.at:132: \$CC \$CFLAGS \$CPPFLAGS -o caller.o -c caller.c" echo headers.at:132 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o caller.o -c caller.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:132: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "headers.at:133: \$CC \$CFLAGS \$CPPFLAGS -o input.o -c input.c" echo headers.at:133 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o input.o -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:133: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "headers.at:134: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o caller caller.o input.o \$LIBS" echo headers.at:134 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o caller caller.o input.o $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:134: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "headers.at:135: \$PREPARSER ./caller" echo headers.at:135 >$at_check_line_file ( $at_traceon; $PREPARSER ./caller ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "headers.at:135: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-7 ) # Banner 7. actions.at:19 cat <<\_ATEOF User Actions. _ATEOF ;; 50 ) # 50. actions.at:25: Mid-rule actions at_setup_line='actions.at:25' at_desc='Mid-rule actions' $at_quiet $ECHO_N " 50: Mid-rule actions $ECHO_C" at_xfail=no ( echo "50. actions.at:25: testing ..." $at_traceon # Bison once forgot the mid-rule actions. It was because the action # was attached to the host rule (the one with the mid-rule action), # instead of being attached to the empty rule dedicated to this # action. cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %error-verbose %debug %{ # include # include static void yyerror (const char *msg); static int yylex (void); %} %% exp: { putchar ('0'); } '1' { putchar ('1'); } '2' { putchar ('2'); } '3' { putchar ('3'); } '4' { putchar ('4'); } '5' { putchar ('5'); } '6' { putchar ('6'); } '7' { putchar ('7'); } '8' { putchar ('8'); } '9' { putchar ('9'); } { putchar ('\n'); } ; %% static int yylex (void) { static const char *input = "123456789"; return *input++; } static void yyerror (const char *msg) { fprintf (stderr, "%s\n", msg); } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "actions.at:75: bison -d -v -o input.c input.y" echo actions.at:75 >$at_check_line_file ( $at_traceon; bison -d -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:75: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:76: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo actions.at:76 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:76: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:79: \$PREPARSER ./input" echo actions.at:79 >$at_check_line_file ( $at_traceon; $PREPARSER ./input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "0123456789 " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:79: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 51 ) # 51. actions.at:91: Exotic Dollars at_setup_line='actions.at:91' at_desc='Exotic Dollars' $at_quiet $ECHO_N " 51: Exotic Dollars $ECHO_C" at_xfail=no ( echo "51. actions.at:91: testing ..." $at_traceon cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %error-verbose %debug %{ # include # include static void yyerror (const char *msg); static int yylex (void); # define USE(Var) %} %union { int val; }; %type a_1 a_2 a_5 sum_of_the_five_previous_values %% exp: a_1 a_2 { $$ = 3; } { $$ = $3 + 1; } a_5 sum_of_the_five_previous_values { USE (($1, $2, $3, $4, $5)); printf ("%d\n", $6); } ; a_1: { $$ = 1; }; a_2: { $$ = 2; }; a_5: { $$ = 5; }; sum_of_the_five_previous_values: { $$ = $0 + $-1 + $-2 + $-3 + $-4; } ; %% static int yylex (void) { return EOF; } static void yyerror (const char *msg) { fprintf (stderr, "%s\n", msg); } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "actions.at:150: bison -d -v -o input.c input.y" echo actions.at:150 >$at_check_line_file ( $at_traceon; bison -d -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:150: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:151: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo actions.at:151 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:151: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:154: \$PREPARSER ./input" echo actions.at:154 >$at_check_line_file ( $at_traceon; $PREPARSER ./input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "15 " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:154: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 52 ) # 52. actions.at:527: Printers and Destructors : at_setup_line='actions.at:527' at_desc='Printers and Destructors : ' $at_quiet $ECHO_N " 52: Printers and Destructors : $ECHO_C" at_xfail=no ( echo "52. actions.at:527: testing ..." $at_traceon # Make sure complex $n work. # Be sure to pass all the %directives to this macro to have correct # helping macros. So don't put any directly in the Bison file. # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include #include #define YYINITDEPTH 10 #define YYMAXDEPTH 10 #define RANGE(Location) (Location).first_line, (Location).last_line %} %error-verbose %debug %verbose %locations %{ static int yylex (void); static void yyerror (const char *msg); %} %printer { fprintf (yyoutput, "%d", $$); } input line thing 'x' 'y' %destructor { printf ("Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); } input %destructor { printf ("Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); } line %destructor { printf ("Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); } thing %destructor { printf ("Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); } 'x' %destructor { printf ("Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); } 'y' %% /* This grammar is made to exercise error recovery. "Lines" starting with `(' support error recovery, with ')' as synchronizing token. Lines starting with 'x' can never be recovered from if in error. */ input: /* Nothing. */ { $$ = 0; printf ("input (%d@%d-%d): /* Nothing */\n", $$, RANGE (@$)); } | line input /* Right recursive to load the stack so that popping at EOF can be exercised. */ { $$ = 2; printf ("input (%d@%d-%d): line (%d@%d-%d) input (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2)); } ; line: thing thing thing ';' { $$ = $1; printf ("line (%d@%d-%d): thing (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ';' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3)); } | '(' error ')' { $$ = -1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) error (@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), RANGE (@2), $3, RANGE (@3)); } ; thing: 'x' { $$ = $1; printf ("thing (%d@%d-%d): 'x' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1)); } ; %% /* Alias to ARGV[1]. */ const char *source = 0; static int yylex (void) { static unsigned int counter = 0; int c = (yylval) = counter++; /* As in BASIC, line numbers go from 10 to 10. */ (yylloc).first_line = (yylloc).first_column = 10 * c; (yylloc).last_line = (yylloc).last_column = (yylloc).first_line + 9; if (source[c]) printf ("sending: '%c'", source[c]); else printf ("sending: EOF"); printf (" (%d@%d-%d)\n", c, RANGE ((yylloc))); return source[c]; } static void yyerror (const char *msg) { printf ("%d-%d: %s\n", RANGE (yylloc), msg); } int main (int argc, const char *argv[]) { int status; yydebug = !!getenv ("YYDEBUG"); assert (argc == 2); source = argv[1]; status = yyparse (); switch (status) { case 0: printf ("Successful parse.\n"); break; case 1: printf ("Parsing FAILED.\n"); break; default: printf ("Parsing FAILED (status %d).\n", status); break; } return status; } _ATEOF $at_traceoff echo "actions.at:527: bison -o input.c input.y" echo actions.at:527 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:527: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:527: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo actions.at:527 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:527: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the location of "empty" # ----------------------------- # I.e., epsilon-reductions, as in "(x)" which ends by reducing # an empty "line" nterm. # FIXME: This location is not satisfying. Depend on the lookahead? $at_traceoff echo "actions.at:527: \$PREPARSER ./input '(x)'" echo actions.at:527 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(x)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: ')' (2@20-29) line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (0@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:527: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check locations in error recovery # --------------------------------- # '(y)' is an error, but can be recovered from. But what's the location # of the error itself ('y'), and of the resulting reduction ('(error)'). $at_traceoff echo "actions.at:527: \$PREPARSER ./input '(y)'" echo actions.at:527 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(y)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'y' (1@10-19) 10-19: syntax error, unexpected 'y', expecting 'x' Freeing token 'y' (1@10-19) sending: ')' (2@20-29) line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (-1@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:527: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Syntax errors caught by the parser # ---------------------------------- # Exercise the discarding of stack top and input until `error' # can be reduced. # # '(', 'x', 'x', 'x', 'x', 'x', ')', # # Load the stack and provoke an error that cannot be caught by the # grammar, to check that the stack is cleared. And make sure the # lookahead is freed. # # '(', 'x', ')', # '(', 'x', ')', # 'y' $at_traceoff echo "actions.at:527: \$PREPARSER ./input '(xxxxx)(x)(x)y'" echo actions.at:527 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(xxxxx)(x)(x)y' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: 'x' (2@20-29) thing (2@20-29): 'x' (2@20-29) sending: 'x' (3@30-39) 30-39: syntax error, unexpected 'x', expecting ')' Freeing nterm thing (2@20-29) Freeing nterm thing (1@10-19) Freeing token 'x' (3@30-39) sending: 'x' (4@40-49) Freeing token 'x' (4@40-49) sending: 'x' (5@50-59) Freeing token 'x' (5@50-59) sending: ')' (6@60-69) line (-1@0-69): '(' (0@0-9) error (@10-59) ')' (6@60-69) sending: '(' (7@70-79) sending: 'x' (8@80-89) thing (8@80-89): 'x' (8@80-89) sending: ')' (9@90-99) line (7@70-99): '(' (7@70-79) thing (8@80-89) ')' (9@90-99) sending: '(' (10@100-109) sending: 'x' (11@110-119) thing (11@110-119): 'x' (11@110-119) sending: ')' (12@120-129) line (10@100-129): '(' (10@100-109) thing (11@110-119) ')' (12@120-129) sending: 'y' (13@130-139) input (0@129-129): /* Nothing */ input (2@100-129): line (10@100-129) input (0@129-129) input (2@70-129): line (7@70-99) input (2@100-129) input (2@0-129): line (-1@0-69) input (2@70-129) 130-139: syntax error, unexpected 'y', expecting \$end Freeing nterm input (2@0-129) Freeing token 'y' (13@130-139) Parsing FAILED. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "actions.at:527: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check destruction upon stack overflow # ------------------------------------- # Upon stack overflow, all symbols on the stack should be destroyed. # Only check for yacc.c. $at_traceoff echo "actions.at:527: \$PREPARSER ./input '(x)(x)(x)(x)(x)(x)(x)'" echo actions.at:527 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(x)(x)(x)(x)(x)(x)(x)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: ')' (2@20-29) line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29) sending: '(' (3@30-39) sending: 'x' (4@40-49) thing (4@40-49): 'x' (4@40-49) sending: ')' (5@50-59) line (3@30-59): '(' (3@30-39) thing (4@40-49) ')' (5@50-59) sending: '(' (6@60-69) sending: 'x' (7@70-79) thing (7@70-79): 'x' (7@70-79) sending: ')' (8@80-89) line (6@60-89): '(' (6@60-69) thing (7@70-79) ')' (8@80-89) sending: '(' (9@90-99) sending: 'x' (10@100-109) thing (10@100-109): 'x' (10@100-109) sending: ')' (11@110-119) line (9@90-119): '(' (9@90-99) thing (10@100-109) ')' (11@110-119) sending: '(' (12@120-129) sending: 'x' (13@130-139) thing (13@130-139): 'x' (13@130-139) sending: ')' (14@140-149) line (12@120-149): '(' (12@120-129) thing (13@130-139) ')' (14@140-149) sending: '(' (15@150-159) sending: 'x' (16@160-169) thing (16@160-169): 'x' (16@160-169) sending: ')' (17@170-179) line (15@150-179): '(' (15@150-159) thing (16@160-169) ')' (17@170-179) sending: '(' (18@180-189) sending: 'x' (19@190-199) thing (19@190-199): 'x' (19@190-199) sending: ')' (20@200-209) 200-209: memory exhausted Freeing nterm thing (19@190-199) Freeing nterm line (15@150-179) Freeing nterm line (12@120-149) Freeing nterm line (9@90-119) Freeing nterm line (6@60-89) Freeing nterm line (3@30-59) Freeing nterm line (0@0-29) Parsing FAILED (status 2). " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 2) ;; *) echo "actions.at:527: exit code was $at_status, expected 2" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 53 ) # 53. actions.at:528: Printers and Destructors with union: at_setup_line='actions.at:528' at_desc='Printers and Destructors with union: ' $at_quiet $ECHO_N " 53: Printers and Destructors with union: $ECHO_C" at_xfail=no ( echo "53. actions.at:528: testing ..." $at_traceon # Make sure complex $n work. # Be sure to pass all the %directives to this macro to have correct # helping macros. So don't put any directly in the Bison file. # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include #include #define YYINITDEPTH 10 #define YYMAXDEPTH 10 #define RANGE(Location) (Location).first_line, (Location).last_line %} %error-verbose %debug %verbose %locations %union { int ival; } %{ static int yylex (void); static void yyerror (const char *msg); %} %type '(' 'x' 'y' ')' ';' thing line input %printer { fprintf (yyoutput, "%d", $$); } input line thing 'x' 'y' %destructor { printf ("Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); } input %destructor { printf ("Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); } line %destructor { printf ("Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); } thing %destructor { printf ("Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); } 'x' %destructor { printf ("Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); } 'y' %% /* This grammar is made to exercise error recovery. "Lines" starting with `(' support error recovery, with ')' as synchronizing token. Lines starting with 'x' can never be recovered from if in error. */ input: /* Nothing. */ { $$ = 0; printf ("input (%d@%d-%d): /* Nothing */\n", $$, RANGE (@$)); } | line input /* Right recursive to load the stack so that popping at EOF can be exercised. */ { $$ = 2; printf ("input (%d@%d-%d): line (%d@%d-%d) input (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2)); } ; line: thing thing thing ';' { $$ = $1; printf ("line (%d@%d-%d): thing (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ';' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3)); } | '(' error ')' { $$ = -1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) error (@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), RANGE (@2), $3, RANGE (@3)); } ; thing: 'x' { $$ = $1; printf ("thing (%d@%d-%d): 'x' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1)); } ; %% /* Alias to ARGV[1]. */ const char *source = 0; static int yylex (void) { static unsigned int counter = 0; int c = (yylval).ival = counter++; /* As in BASIC, line numbers go from 10 to 10. */ (yylloc).first_line = (yylloc).first_column = 10 * c; (yylloc).last_line = (yylloc).last_column = (yylloc).first_line + 9; if (source[c]) printf ("sending: '%c'", source[c]); else printf ("sending: EOF"); printf (" (%d@%d-%d)\n", c, RANGE ((yylloc))); return source[c]; } static void yyerror (const char *msg) { printf ("%d-%d: %s\n", RANGE (yylloc), msg); } int main (int argc, const char *argv[]) { int status; yydebug = !!getenv ("YYDEBUG"); assert (argc == 2); source = argv[1]; status = yyparse (); switch (status) { case 0: printf ("Successful parse.\n"); break; case 1: printf ("Parsing FAILED.\n"); break; default: printf ("Parsing FAILED (status %d).\n", status); break; } return status; } _ATEOF $at_traceoff echo "actions.at:528: bison -o input.c input.y" echo actions.at:528 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:528: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:528: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo actions.at:528 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:528: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the location of "empty" # ----------------------------- # I.e., epsilon-reductions, as in "(x)" which ends by reducing # an empty "line" nterm. # FIXME: This location is not satisfying. Depend on the lookahead? $at_traceoff echo "actions.at:528: \$PREPARSER ./input '(x)'" echo actions.at:528 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(x)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: ')' (2@20-29) line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (0@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:528: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check locations in error recovery # --------------------------------- # '(y)' is an error, but can be recovered from. But what's the location # of the error itself ('y'), and of the resulting reduction ('(error)'). $at_traceoff echo "actions.at:528: \$PREPARSER ./input '(y)'" echo actions.at:528 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(y)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'y' (1@10-19) 10-19: syntax error, unexpected 'y', expecting 'x' Freeing token 'y' (1@10-19) sending: ')' (2@20-29) line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (-1@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:528: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Syntax errors caught by the parser # ---------------------------------- # Exercise the discarding of stack top and input until `error' # can be reduced. # # '(', 'x', 'x', 'x', 'x', 'x', ')', # # Load the stack and provoke an error that cannot be caught by the # grammar, to check that the stack is cleared. And make sure the # lookahead is freed. # # '(', 'x', ')', # '(', 'x', ')', # 'y' $at_traceoff echo "actions.at:528: \$PREPARSER ./input '(xxxxx)(x)(x)y'" echo actions.at:528 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(xxxxx)(x)(x)y' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: 'x' (2@20-29) thing (2@20-29): 'x' (2@20-29) sending: 'x' (3@30-39) 30-39: syntax error, unexpected 'x', expecting ')' Freeing nterm thing (2@20-29) Freeing nterm thing (1@10-19) Freeing token 'x' (3@30-39) sending: 'x' (4@40-49) Freeing token 'x' (4@40-49) sending: 'x' (5@50-59) Freeing token 'x' (5@50-59) sending: ')' (6@60-69) line (-1@0-69): '(' (0@0-9) error (@10-59) ')' (6@60-69) sending: '(' (7@70-79) sending: 'x' (8@80-89) thing (8@80-89): 'x' (8@80-89) sending: ')' (9@90-99) line (7@70-99): '(' (7@70-79) thing (8@80-89) ')' (9@90-99) sending: '(' (10@100-109) sending: 'x' (11@110-119) thing (11@110-119): 'x' (11@110-119) sending: ')' (12@120-129) line (10@100-129): '(' (10@100-109) thing (11@110-119) ')' (12@120-129) sending: 'y' (13@130-139) input (0@129-129): /* Nothing */ input (2@100-129): line (10@100-129) input (0@129-129) input (2@70-129): line (7@70-99) input (2@100-129) input (2@0-129): line (-1@0-69) input (2@70-129) 130-139: syntax error, unexpected 'y', expecting \$end Freeing nterm input (2@0-129) Freeing token 'y' (13@130-139) Parsing FAILED. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "actions.at:528: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check destruction upon stack overflow # ------------------------------------- # Upon stack overflow, all symbols on the stack should be destroyed. # Only check for yacc.c. $at_traceoff echo "actions.at:528: \$PREPARSER ./input '(x)(x)(x)(x)(x)(x)(x)'" echo actions.at:528 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(x)(x)(x)(x)(x)(x)(x)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: ')' (2@20-29) line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29) sending: '(' (3@30-39) sending: 'x' (4@40-49) thing (4@40-49): 'x' (4@40-49) sending: ')' (5@50-59) line (3@30-59): '(' (3@30-39) thing (4@40-49) ')' (5@50-59) sending: '(' (6@60-69) sending: 'x' (7@70-79) thing (7@70-79): 'x' (7@70-79) sending: ')' (8@80-89) line (6@60-89): '(' (6@60-69) thing (7@70-79) ')' (8@80-89) sending: '(' (9@90-99) sending: 'x' (10@100-109) thing (10@100-109): 'x' (10@100-109) sending: ')' (11@110-119) line (9@90-119): '(' (9@90-99) thing (10@100-109) ')' (11@110-119) sending: '(' (12@120-129) sending: 'x' (13@130-139) thing (13@130-139): 'x' (13@130-139) sending: ')' (14@140-149) line (12@120-149): '(' (12@120-129) thing (13@130-139) ')' (14@140-149) sending: '(' (15@150-159) sending: 'x' (16@160-169) thing (16@160-169): 'x' (16@160-169) sending: ')' (17@170-179) line (15@150-179): '(' (15@150-159) thing (16@160-169) ')' (17@170-179) sending: '(' (18@180-189) sending: 'x' (19@190-199) thing (19@190-199): 'x' (19@190-199) sending: ')' (20@200-209) 200-209: memory exhausted Freeing nterm thing (19@190-199) Freeing nterm line (15@150-179) Freeing nterm line (12@120-149) Freeing nterm line (9@90-119) Freeing nterm line (6@60-89) Freeing nterm line (3@30-59) Freeing nterm line (0@0-29) Parsing FAILED (status 2). " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 2) ;; *) echo "actions.at:528: exit code was $at_status, expected 2" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 54 ) # 54. actions.at:533: Printers and Destructors : %defines %skeleton "lalr1.cc" at_setup_line='actions.at:533' at_desc='Printers and Destructors : %defines %skeleton "lalr1.cc"' $at_quiet $ECHO_N " 54: Printers and Destructors : %defines %skeleton "lalr1.cc"$ECHO_C" at_xfail=no ( echo "54. actions.at:533: testing ..." $at_traceon # Make sure complex $n work. # Be sure to pass all the %directives to this macro to have correct # helping macros. So don't put any directly in the Bison file. # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include #include #define YYINITDEPTH 10 #define YYMAXDEPTH 10 #define RANGE(Location) (Location).begin.line, (Location).end.line %} %error-verbose %debug %verbose %locations %defines %skeleton "lalr1.cc" %define "global_tokens_and_yystype" %{ typedef yy::location YYLTYPE; #define YYSTYPE int static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); %} %printer { debug_stream () << $$;; } input line thing 'x' 'y' %destructor { printf ("Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); } input %destructor { printf ("Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); } line %destructor { printf ("Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); } thing %destructor { printf ("Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); } 'x' %destructor { printf ("Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); } 'y' %% /* This grammar is made to exercise error recovery. "Lines" starting with `(' support error recovery, with ')' as synchronizing token. Lines starting with 'x' can never be recovered from if in error. */ input: /* Nothing. */ { $$ = 0; printf ("input (%d@%d-%d): /* Nothing */\n", $$, RANGE (@$)); } | line input /* Right recursive to load the stack so that popping at EOF can be exercised. */ { $$ = 2; printf ("input (%d@%d-%d): line (%d@%d-%d) input (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2)); } ; line: thing thing thing ';' { $$ = $1; printf ("line (%d@%d-%d): thing (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ';' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3)); } | '(' error ')' { $$ = -1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) error (@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), RANGE (@2), $3, RANGE (@3)); } ; thing: 'x' { $$ = $1; printf ("thing (%d@%d-%d): 'x' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1)); } ; %% /* Alias to ARGV[1]. */ const char *source = 0; static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static unsigned int counter = 0; int c = (*lvalp) = counter++; /* As in BASIC, line numbers go from 10 to 10. */ (*llocp).begin.line = (*llocp).begin.column = 10 * c; (*llocp).end.line = (*llocp).end.column = (*llocp).begin.line + 9; if (source[c]) printf ("sending: '%c'", source[c]); else printf ("sending: EOF"); printf (" (%d@%d-%d)\n", c, RANGE ((*llocp))); return source[c]; } /* A C++ error reporting function. */ void yy::parser::error (const location& l, const std::string& m) { printf ("%d-%d: %s\n", RANGE (l), m.c_str()); } static bool yydebug; int yyparse () { yy::parser parser; parser.set_debug_level (yydebug); return parser.parse (); } int main (int argc, const char *argv[]) { int status; yydebug = !!getenv ("YYDEBUG"); assert (argc == 2); source = argv[1]; status = yyparse (); switch (status) { case 0: printf ("Successful parse.\n"); break; case 1: printf ("Parsing FAILED.\n"); break; default: printf ("Parsing FAILED (status %d).\n", status); break; } return status; } _ATEOF $at_traceoff echo "actions.at:533: bison -o input.cc input.y" echo actions.at:533 >$at_check_line_file ( $at_traceon; bison -o input.cc input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:533: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:533: \$BISON_CXX_WORKS" echo actions.at:533 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:533: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:533: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o input input.cc \$LIBS" echo actions.at:533 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o input input.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:533: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the location of "empty" # ----------------------------- # I.e., epsilon-reductions, as in "(x)" which ends by reducing # an empty "line" nterm. # FIXME: This location is not satisfying. Depend on the lookahead? $at_traceoff echo "actions.at:533: \$PREPARSER ./input '(x)'" echo actions.at:533 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(x)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: ')' (2@20-29) line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (0@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:533: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check locations in error recovery # --------------------------------- # '(y)' is an error, but can be recovered from. But what's the location # of the error itself ('y'), and of the resulting reduction ('(error)'). $at_traceoff echo "actions.at:533: \$PREPARSER ./input '(y)'" echo actions.at:533 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(y)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'y' (1@10-19) 10-19: syntax error, unexpected 'y', expecting 'x' Freeing token 'y' (1@10-19) sending: ')' (2@20-29) line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (-1@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:533: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Syntax errors caught by the parser # ---------------------------------- # Exercise the discarding of stack top and input until `error' # can be reduced. # # '(', 'x', 'x', 'x', 'x', 'x', ')', # # Load the stack and provoke an error that cannot be caught by the # grammar, to check that the stack is cleared. And make sure the # lookahead is freed. # # '(', 'x', ')', # '(', 'x', ')', # 'y' $at_traceoff echo "actions.at:533: \$PREPARSER ./input '(xxxxx)(x)(x)y'" echo actions.at:533 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(xxxxx)(x)(x)y' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: 'x' (2@20-29) thing (2@20-29): 'x' (2@20-29) sending: 'x' (3@30-39) 30-39: syntax error, unexpected 'x', expecting ')' Freeing nterm thing (2@20-29) Freeing nterm thing (1@10-19) Freeing token 'x' (3@30-39) sending: 'x' (4@40-49) Freeing token 'x' (4@40-49) sending: 'x' (5@50-59) Freeing token 'x' (5@50-59) sending: ')' (6@60-69) line (-1@0-69): '(' (0@0-9) error (@10-59) ')' (6@60-69) sending: '(' (7@70-79) sending: 'x' (8@80-89) thing (8@80-89): 'x' (8@80-89) sending: ')' (9@90-99) line (7@70-99): '(' (7@70-79) thing (8@80-89) ')' (9@90-99) sending: '(' (10@100-109) sending: 'x' (11@110-119) thing (11@110-119): 'x' (11@110-119) sending: ')' (12@120-129) line (10@100-129): '(' (10@100-109) thing (11@110-119) ')' (12@120-129) sending: 'y' (13@130-139) input (0@129-129): /* Nothing */ input (2@100-129): line (10@100-129) input (0@129-129) input (2@70-129): line (7@70-99) input (2@100-129) input (2@0-129): line (-1@0-69) input (2@70-129) 130-139: syntax error, unexpected 'y', expecting \$end Freeing nterm input (2@0-129) Freeing token 'y' (13@130-139) Parsing FAILED. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "actions.at:533: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check destruction upon stack overflow # ------------------------------------- # Upon stack overflow, all symbols on the stack should be destroyed. # Only check for yacc.c. $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 55 ) # 55. actions.at:534: Printers and Destructors with union: %defines %skeleton "lalr1.cc" at_setup_line='actions.at:534' at_desc='Printers and Destructors with union: %defines %skeleton "lalr1.cc"' $at_quiet $ECHO_N " 55: Printers and Destructors with union: %defines %skeleton "lalr1.cc"$ECHO_C" at_xfail=no ( echo "55. actions.at:534: testing ..." $at_traceon # Make sure complex $n work. # Be sure to pass all the %directives to this macro to have correct # helping macros. So don't put any directly in the Bison file. # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include #include #define YYINITDEPTH 10 #define YYMAXDEPTH 10 #define RANGE(Location) (Location).begin.line, (Location).end.line %} %error-verbose %debug %verbose %locations %defines %skeleton "lalr1.cc" %union { int ival; } %define "global_tokens_and_yystype" %{ typedef yy::location YYLTYPE; static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); %} %type '(' 'x' 'y' ')' ';' thing line input %printer { debug_stream () << $$;; } input line thing 'x' 'y' %destructor { printf ("Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); } input %destructor { printf ("Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); } line %destructor { printf ("Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); } thing %destructor { printf ("Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); } 'x' %destructor { printf ("Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); } 'y' %% /* This grammar is made to exercise error recovery. "Lines" starting with `(' support error recovery, with ')' as synchronizing token. Lines starting with 'x' can never be recovered from if in error. */ input: /* Nothing. */ { $$ = 0; printf ("input (%d@%d-%d): /* Nothing */\n", $$, RANGE (@$)); } | line input /* Right recursive to load the stack so that popping at EOF can be exercised. */ { $$ = 2; printf ("input (%d@%d-%d): line (%d@%d-%d) input (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2)); } ; line: thing thing thing ';' { $$ = $1; printf ("line (%d@%d-%d): thing (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ';' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3)); } | '(' error ')' { $$ = -1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) error (@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), RANGE (@2), $3, RANGE (@3)); } ; thing: 'x' { $$ = $1; printf ("thing (%d@%d-%d): 'x' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1)); } ; %% /* Alias to ARGV[1]. */ const char *source = 0; static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static unsigned int counter = 0; int c = (*lvalp).ival = counter++; /* As in BASIC, line numbers go from 10 to 10. */ (*llocp).begin.line = (*llocp).begin.column = 10 * c; (*llocp).end.line = (*llocp).end.column = (*llocp).begin.line + 9; if (source[c]) printf ("sending: '%c'", source[c]); else printf ("sending: EOF"); printf (" (%d@%d-%d)\n", c, RANGE ((*llocp))); return source[c]; } /* A C++ error reporting function. */ void yy::parser::error (const location& l, const std::string& m) { printf ("%d-%d: %s\n", RANGE (l), m.c_str()); } static bool yydebug; int yyparse () { yy::parser parser; parser.set_debug_level (yydebug); return parser.parse (); } int main (int argc, const char *argv[]) { int status; yydebug = !!getenv ("YYDEBUG"); assert (argc == 2); source = argv[1]; status = yyparse (); switch (status) { case 0: printf ("Successful parse.\n"); break; case 1: printf ("Parsing FAILED.\n"); break; default: printf ("Parsing FAILED (status %d).\n", status); break; } return status; } _ATEOF $at_traceoff echo "actions.at:534: bison -o input.cc input.y" echo actions.at:534 >$at_check_line_file ( $at_traceon; bison -o input.cc input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:534: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:534: \$BISON_CXX_WORKS" echo actions.at:534 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:534: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:534: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o input input.cc \$LIBS" echo actions.at:534 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o input input.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:534: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the location of "empty" # ----------------------------- # I.e., epsilon-reductions, as in "(x)" which ends by reducing # an empty "line" nterm. # FIXME: This location is not satisfying. Depend on the lookahead? $at_traceoff echo "actions.at:534: \$PREPARSER ./input '(x)'" echo actions.at:534 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(x)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: ')' (2@20-29) line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (0@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:534: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check locations in error recovery # --------------------------------- # '(y)' is an error, but can be recovered from. But what's the location # of the error itself ('y'), and of the resulting reduction ('(error)'). $at_traceoff echo "actions.at:534: \$PREPARSER ./input '(y)'" echo actions.at:534 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(y)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'y' (1@10-19) 10-19: syntax error, unexpected 'y', expecting 'x' Freeing token 'y' (1@10-19) sending: ')' (2@20-29) line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (-1@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:534: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Syntax errors caught by the parser # ---------------------------------- # Exercise the discarding of stack top and input until `error' # can be reduced. # # '(', 'x', 'x', 'x', 'x', 'x', ')', # # Load the stack and provoke an error that cannot be caught by the # grammar, to check that the stack is cleared. And make sure the # lookahead is freed. # # '(', 'x', ')', # '(', 'x', ')', # 'y' $at_traceoff echo "actions.at:534: \$PREPARSER ./input '(xxxxx)(x)(x)y'" echo actions.at:534 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(xxxxx)(x)(x)y' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: 'x' (2@20-29) thing (2@20-29): 'x' (2@20-29) sending: 'x' (3@30-39) 30-39: syntax error, unexpected 'x', expecting ')' Freeing nterm thing (2@20-29) Freeing nterm thing (1@10-19) Freeing token 'x' (3@30-39) sending: 'x' (4@40-49) Freeing token 'x' (4@40-49) sending: 'x' (5@50-59) Freeing token 'x' (5@50-59) sending: ')' (6@60-69) line (-1@0-69): '(' (0@0-9) error (@10-59) ')' (6@60-69) sending: '(' (7@70-79) sending: 'x' (8@80-89) thing (8@80-89): 'x' (8@80-89) sending: ')' (9@90-99) line (7@70-99): '(' (7@70-79) thing (8@80-89) ')' (9@90-99) sending: '(' (10@100-109) sending: 'x' (11@110-119) thing (11@110-119): 'x' (11@110-119) sending: ')' (12@120-129) line (10@100-129): '(' (10@100-109) thing (11@110-119) ')' (12@120-129) sending: 'y' (13@130-139) input (0@129-129): /* Nothing */ input (2@100-129): line (10@100-129) input (0@129-129) input (2@70-129): line (7@70-99) input (2@100-129) input (2@0-129): line (-1@0-69) input (2@70-129) 130-139: syntax error, unexpected 'y', expecting \$end Freeing nterm input (2@0-129) Freeing token 'y' (13@130-139) Parsing FAILED. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "actions.at:534: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check destruction upon stack overflow # ------------------------------------- # Upon stack overflow, all symbols on the stack should be destroyed. # Only check for yacc.c. $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 56 ) # 56. actions.at:536: Printers and Destructors : %glr-parser at_setup_line='actions.at:536' at_desc='Printers and Destructors : %glr-parser' $at_quiet $ECHO_N " 56: Printers and Destructors : %glr-parser $ECHO_C" at_xfail=no ( echo "56. actions.at:536: testing ..." $at_traceon # Make sure complex $n work. # Be sure to pass all the %directives to this macro to have correct # helping macros. So don't put any directly in the Bison file. # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include #include #define YYINITDEPTH 10 #define YYMAXDEPTH 10 #define RANGE(Location) (Location).first_line, (Location).last_line %} %error-verbose %debug %verbose %locations %glr-parser %{ static int yylex (void); static void yyerror (const char *msg); %} %printer { fprintf (yyoutput, "%d", $$); } input line thing 'x' 'y' %destructor { printf ("Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); } input %destructor { printf ("Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); } line %destructor { printf ("Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); } thing %destructor { printf ("Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); } 'x' %destructor { printf ("Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); } 'y' %% /* This grammar is made to exercise error recovery. "Lines" starting with `(' support error recovery, with ')' as synchronizing token. Lines starting with 'x' can never be recovered from if in error. */ input: /* Nothing. */ { $$ = 0; printf ("input (%d@%d-%d): /* Nothing */\n", $$, RANGE (@$)); } | line input /* Right recursive to load the stack so that popping at EOF can be exercised. */ { $$ = 2; printf ("input (%d@%d-%d): line (%d@%d-%d) input (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2)); } ; line: thing thing thing ';' { $$ = $1; printf ("line (%d@%d-%d): thing (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ';' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3)); } | '(' error ')' { $$ = -1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) error (@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), RANGE (@2), $3, RANGE (@3)); } ; thing: 'x' { $$ = $1; printf ("thing (%d@%d-%d): 'x' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1)); } ; %% /* Alias to ARGV[1]. */ const char *source = 0; static int yylex (void) { static unsigned int counter = 0; int c = (yylval) = counter++; /* As in BASIC, line numbers go from 10 to 10. */ (yylloc).first_line = (yylloc).first_column = 10 * c; (yylloc).last_line = (yylloc).last_column = (yylloc).first_line + 9; if (source[c]) printf ("sending: '%c'", source[c]); else printf ("sending: EOF"); printf (" (%d@%d-%d)\n", c, RANGE ((yylloc))); return source[c]; } static void yyerror (const char *msg) { printf ("%d-%d: %s\n", RANGE (yylloc), msg); } int main (int argc, const char *argv[]) { int status; yydebug = !!getenv ("YYDEBUG"); assert (argc == 2); source = argv[1]; status = yyparse (); switch (status) { case 0: printf ("Successful parse.\n"); break; case 1: printf ("Parsing FAILED.\n"); break; default: printf ("Parsing FAILED (status %d).\n", status); break; } return status; } _ATEOF $at_traceoff echo "actions.at:536: bison -o input.c input.y" echo actions.at:536 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:536: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:536: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo actions.at:536 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:536: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the location of "empty" # ----------------------------- # I.e., epsilon-reductions, as in "(x)" which ends by reducing # an empty "line" nterm. # FIXME: This location is not satisfying. Depend on the lookahead? $at_traceoff echo "actions.at:536: \$PREPARSER ./input '(x)'" echo actions.at:536 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(x)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: ')' (2@20-29) line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (0@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:536: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check locations in error recovery # --------------------------------- # '(y)' is an error, but can be recovered from. But what's the location # of the error itself ('y'), and of the resulting reduction ('(error)'). $at_traceoff echo "actions.at:536: \$PREPARSER ./input '(y)'" echo actions.at:536 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(y)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'y' (1@10-19) 10-19: syntax error, unexpected 'y', expecting 'x' Freeing token 'y' (1@10-19) sending: ')' (2@20-29) line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (-1@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:536: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Syntax errors caught by the parser # ---------------------------------- # Exercise the discarding of stack top and input until `error' # can be reduced. # # '(', 'x', 'x', 'x', 'x', 'x', ')', # # Load the stack and provoke an error that cannot be caught by the # grammar, to check that the stack is cleared. And make sure the # lookahead is freed. # # '(', 'x', ')', # '(', 'x', ')', # 'y' $at_traceoff echo "actions.at:536: \$PREPARSER ./input '(xxxxx)(x)(x)y'" echo actions.at:536 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(xxxxx)(x)(x)y' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: 'x' (2@20-29) thing (2@20-29): 'x' (2@20-29) sending: 'x' (3@30-39) 30-39: syntax error, unexpected 'x', expecting ')' Freeing nterm thing (2@20-29) Freeing nterm thing (1@10-19) Freeing token 'x' (3@30-39) sending: 'x' (4@40-49) Freeing token 'x' (4@40-49) sending: 'x' (5@50-59) Freeing token 'x' (5@50-59) sending: ')' (6@60-69) line (-1@0-69): '(' (0@0-9) error (@10-59) ')' (6@60-69) sending: '(' (7@70-79) sending: 'x' (8@80-89) thing (8@80-89): 'x' (8@80-89) sending: ')' (9@90-99) line (7@70-99): '(' (7@70-79) thing (8@80-89) ')' (9@90-99) sending: '(' (10@100-109) sending: 'x' (11@110-119) thing (11@110-119): 'x' (11@110-119) sending: ')' (12@120-129) line (10@100-129): '(' (10@100-109) thing (11@110-119) ')' (12@120-129) sending: 'y' (13@130-139) input (0@129-129): /* Nothing */ input (2@100-129): line (10@100-129) input (0@129-129) input (2@70-129): line (7@70-99) input (2@100-129) input (2@0-129): line (-1@0-69) input (2@70-129) 130-139: syntax error, unexpected 'y', expecting \$end Freeing nterm input (2@0-129) Freeing token 'y' (13@130-139) Parsing FAILED. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "actions.at:536: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check destruction upon stack overflow # ------------------------------------- # Upon stack overflow, all symbols on the stack should be destroyed. # Only check for yacc.c. $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 57 ) # 57. actions.at:537: Printers and Destructors with union: %glr-parser at_setup_line='actions.at:537' at_desc='Printers and Destructors with union: %glr-parser' $at_quiet $ECHO_N " 57: Printers and Destructors with union: %glr-parser$ECHO_C" at_xfail=no ( echo "57. actions.at:537: testing ..." $at_traceon # Make sure complex $n work. # Be sure to pass all the %directives to this macro to have correct # helping macros. So don't put any directly in the Bison file. # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include #include #define YYINITDEPTH 10 #define YYMAXDEPTH 10 #define RANGE(Location) (Location).first_line, (Location).last_line %} %error-verbose %debug %verbose %locations %glr-parser %union { int ival; } %{ static int yylex (void); static void yyerror (const char *msg); %} %type '(' 'x' 'y' ')' ';' thing line input %printer { fprintf (yyoutput, "%d", $$); } input line thing 'x' 'y' %destructor { printf ("Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); } input %destructor { printf ("Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); } line %destructor { printf ("Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); } thing %destructor { printf ("Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); } 'x' %destructor { printf ("Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); } 'y' %% /* This grammar is made to exercise error recovery. "Lines" starting with `(' support error recovery, with ')' as synchronizing token. Lines starting with 'x' can never be recovered from if in error. */ input: /* Nothing. */ { $$ = 0; printf ("input (%d@%d-%d): /* Nothing */\n", $$, RANGE (@$)); } | line input /* Right recursive to load the stack so that popping at EOF can be exercised. */ { $$ = 2; printf ("input (%d@%d-%d): line (%d@%d-%d) input (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2)); } ; line: thing thing thing ';' { $$ = $1; printf ("line (%d@%d-%d): thing (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ';' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3), $4, RANGE (@4)); } | '(' thing ')' { $$ = $1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3)); } | '(' error ')' { $$ = -1; printf ("line (%d@%d-%d): '(' (%d@%d-%d) error (@%d-%d) ')' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1), RANGE (@2), $3, RANGE (@3)); } ; thing: 'x' { $$ = $1; printf ("thing (%d@%d-%d): 'x' (%d@%d-%d)\n", $$, RANGE (@$), $1, RANGE (@1)); } ; %% /* Alias to ARGV[1]. */ const char *source = 0; static int yylex (void) { static unsigned int counter = 0; int c = (yylval).ival = counter++; /* As in BASIC, line numbers go from 10 to 10. */ (yylloc).first_line = (yylloc).first_column = 10 * c; (yylloc).last_line = (yylloc).last_column = (yylloc).first_line + 9; if (source[c]) printf ("sending: '%c'", source[c]); else printf ("sending: EOF"); printf (" (%d@%d-%d)\n", c, RANGE ((yylloc))); return source[c]; } static void yyerror (const char *msg) { printf ("%d-%d: %s\n", RANGE (yylloc), msg); } int main (int argc, const char *argv[]) { int status; yydebug = !!getenv ("YYDEBUG"); assert (argc == 2); source = argv[1]; status = yyparse (); switch (status) { case 0: printf ("Successful parse.\n"); break; case 1: printf ("Parsing FAILED.\n"); break; default: printf ("Parsing FAILED (status %d).\n", status); break; } return status; } _ATEOF $at_traceoff echo "actions.at:537: bison -o input.c input.y" echo actions.at:537 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:537: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "actions.at:537: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo actions.at:537 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:537: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the location of "empty" # ----------------------------- # I.e., epsilon-reductions, as in "(x)" which ends by reducing # an empty "line" nterm. # FIXME: This location is not satisfying. Depend on the lookahead? $at_traceoff echo "actions.at:537: \$PREPARSER ./input '(x)'" echo actions.at:537 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(x)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: ')' (2@20-29) line (0@0-29): '(' (0@0-9) thing (1@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (0@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:537: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check locations in error recovery # --------------------------------- # '(y)' is an error, but can be recovered from. But what's the location # of the error itself ('y'), and of the resulting reduction ('(error)'). $at_traceoff echo "actions.at:537: \$PREPARSER ./input '(y)'" echo actions.at:537 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(y)' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'y' (1@10-19) 10-19: syntax error, unexpected 'y', expecting 'x' Freeing token 'y' (1@10-19) sending: ')' (2@20-29) line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29) sending: EOF (3@30-39) input (0@29-29): /* Nothing */ input (2@0-29): line (-1@0-29) input (0@29-29) Freeing nterm input (2@0-29) Successful parse. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "actions.at:537: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Syntax errors caught by the parser # ---------------------------------- # Exercise the discarding of stack top and input until `error' # can be reduced. # # '(', 'x', 'x', 'x', 'x', 'x', ')', # # Load the stack and provoke an error that cannot be caught by the # grammar, to check that the stack is cleared. And make sure the # lookahead is freed. # # '(', 'x', ')', # '(', 'x', ')', # 'y' $at_traceoff echo "actions.at:537: \$PREPARSER ./input '(xxxxx)(x)(x)y'" echo actions.at:537 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '(xxxxx)(x)(x)y' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: 'x' (2@20-29) thing (2@20-29): 'x' (2@20-29) sending: 'x' (3@30-39) 30-39: syntax error, unexpected 'x', expecting ')' Freeing nterm thing (2@20-29) Freeing nterm thing (1@10-19) Freeing token 'x' (3@30-39) sending: 'x' (4@40-49) Freeing token 'x' (4@40-49) sending: 'x' (5@50-59) Freeing token 'x' (5@50-59) sending: ')' (6@60-69) line (-1@0-69): '(' (0@0-9) error (@10-59) ')' (6@60-69) sending: '(' (7@70-79) sending: 'x' (8@80-89) thing (8@80-89): 'x' (8@80-89) sending: ')' (9@90-99) line (7@70-99): '(' (7@70-79) thing (8@80-89) ')' (9@90-99) sending: '(' (10@100-109) sending: 'x' (11@110-119) thing (11@110-119): 'x' (11@110-119) sending: ')' (12@120-129) line (10@100-129): '(' (10@100-109) thing (11@110-119) ')' (12@120-129) sending: 'y' (13@130-139) input (0@129-129): /* Nothing */ input (2@100-129): line (10@100-129) input (0@129-129) input (2@70-129): line (7@70-99) input (2@100-129) input (2@0-129): line (-1@0-69) input (2@70-129) 130-139: syntax error, unexpected 'y', expecting \$end Freeing nterm input (2@0-129) Freeing token 'y' (13@130-139) Parsing FAILED. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "actions.at:537: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check destruction upon stack overflow # ------------------------------------- # Upon stack overflow, all symbols on the stack should be destroyed. # Only check for yacc.c. $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-8 ) # Banner 8. conflicts.at:20 cat <<\_ATEOF Conflicts. _ATEOF ;; 58 ) # 58. conflicts.at:32: S/R in initial at_setup_line='conflicts.at:32' at_desc='S/R in initial' $at_quiet $ECHO_N " 58: S/R in initial $ECHO_C" at_xfail=no ( echo "58. conflicts.at:32: testing ..." $at_traceon cat >input.y <<'_ATEOF' %expect 1 %% exp: e 'e'; e: 'e' | /* Nothing. */; _ATEOF $at_traceoff echo "conflicts.at:43: bison -o input.c input.y" echo conflicts.at:43 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:4.9: warning: rule never reduced because of conflicts: e: /* empty */ " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:43: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 59 ) # 59. conflicts.at:52: %nonassoc and eof at_setup_line='conflicts.at:52' at_desc='%nonassoc and eof' $at_quiet $ECHO_N " 59: %nonassoc and eof $ECHO_C" at_xfail=no ( echo "59. conflicts.at:52: testing ..." $at_traceon cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include #define YYERROR_VERBOSE 1 static void yyerror (const char *msg) { fprintf (stderr, "%s\n", msg); } /* The current argument. */ static const char *input = NULL; static int yylex (void) { /* No token stands for end of file. */ if (input && *input) return *input++; else return 0; } %} %nonassoc '<' '>' %% expr: expr '<' expr | expr '>' expr | '0' ; %% int main (int argc, const char *argv[]) { if (argc > 1) input = argv[1]; return yyparse (); } _ATEOF # Specify the output files to avoid problems on different file systems. $at_traceoff echo "conflicts.at:100: bison -o input.c input.y" echo conflicts.at:100 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:100: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "conflicts.at:101: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo conflicts.at:101 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:101: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "conflicts.at:103: \$PREPARSER ./input '0<0'" echo conflicts.at:103 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '0<0' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:103: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # FIXME: This is an actual bug, but a new one, in the sense that # no one has ever spotted it! The messages are *wrong*: there should # be nothing there, it should be expected eof. $at_traceoff echo "conflicts.at:109: \$PREPARSER ./input '0<0<0'" echo conflicts.at:109 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '0<0<0' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected '<', expecting '<' or '>' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "conflicts.at:109: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "conflicts.at:111: \$PREPARSER ./input '0>0'" echo conflicts.at:111 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '0>0' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:111: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "conflicts.at:114: \$PREPARSER ./input '0>0>0'" echo conflicts.at:114 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '0>0>0' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected '>', expecting '<' or '>' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "conflicts.at:114: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "conflicts.at:118: \$PREPARSER ./input '0<0>0'" echo conflicts.at:118 >$at_check_line_file ( $at_traceon; $PREPARSER ./input '0<0>0' ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected '>', expecting '<' or '>' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "conflicts.at:118: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 60 ) # 60. conflicts.at:128: Unresolved SR Conflicts at_setup_line='conflicts.at:128' at_desc='Unresolved SR Conflicts' $at_quiet $ECHO_N " 60: Unresolved SR Conflicts $ECHO_C" at_xfail=no ( echo "60. conflicts.at:128: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token NUM OP %% exp: exp OP exp | NUM; _ATEOF $at_traceoff echo "conflicts.at:140: bison -o input.c --report=all input.y" echo conflicts.at:140 >$at_check_line_file ( $at_traceon; bison -o input.c --report=all input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: conflicts: 1 shift/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:140: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the contents of the report. $at_traceoff echo "conflicts.at:225: cat input.output" echo conflicts.at:225 >$at_check_line_file ( $at_traceon; cat input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "State 5 conflicts: 1 shift/reduce Grammar 0 \$accept: exp \$end 1 exp: exp OP exp 2 | NUM Terminals, with rules where they appear \$end (0) 0 error (256) NUM (258) 2 OP (259) 1 Nonterminals, with rules where they appear \$accept (5) on left: 0 exp (6) on left: 1 2, on right: 0 1 state 0 0 \$accept: . exp \$end 1 exp: . exp OP exp 2 | . NUM NUM shift, and go to state 1 exp go to state 2 state 1 2 exp: NUM . \$default reduce using rule 2 (exp) state 2 0 \$accept: exp . \$end 1 exp: exp . OP exp \$end shift, and go to state 3 OP shift, and go to state 4 state 3 0 \$accept: exp \$end . \$default accept state 4 1 exp: . exp OP exp 1 | exp OP . exp 2 | . NUM NUM shift, and go to state 1 exp go to state 5 state 5 1 exp: exp . OP exp [\$end, OP] 1 | exp OP exp . [\$end, OP] OP shift, and go to state 4 OP [reduce using rule 1 (exp)] \$default reduce using rule 1 (exp) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:225: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 61 ) # 61. conflicts.at:235: Resolved SR Conflicts at_setup_line='conflicts.at:235' at_desc='Resolved SR Conflicts' $at_quiet $ECHO_N " 61: Resolved SR Conflicts $ECHO_C" at_xfail=no ( echo "61. conflicts.at:235: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token NUM OP %left OP %% exp: exp OP exp | NUM; _ATEOF $at_traceoff echo "conflicts.at:246: bison -o input.c --report=all input.y" echo conflicts.at:246 >$at_check_line_file ( $at_traceon; bison -o input.c --report=all input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:246: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the contents of the report. $at_traceoff echo "conflicts.at:327: cat input.output" echo conflicts.at:327 >$at_check_line_file ( $at_traceon; cat input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Grammar 0 \$accept: exp \$end 1 exp: exp OP exp 2 | NUM Terminals, with rules where they appear \$end (0) 0 error (256) NUM (258) 2 OP (259) 1 Nonterminals, with rules where they appear \$accept (5) on left: 0 exp (6) on left: 1 2, on right: 0 1 state 0 0 \$accept: . exp \$end 1 exp: . exp OP exp 2 | . NUM NUM shift, and go to state 1 exp go to state 2 state 1 2 exp: NUM . \$default reduce using rule 2 (exp) state 2 0 \$accept: exp . \$end 1 exp: exp . OP exp \$end shift, and go to state 3 OP shift, and go to state 4 state 3 0 \$accept: exp \$end . \$default accept state 4 1 exp: . exp OP exp 1 | exp OP . exp 2 | . NUM NUM shift, and go to state 1 exp go to state 5 state 5 1 exp: exp . OP exp [\$end, OP] 1 | exp OP exp . [\$end, OP] \$default reduce using rule 1 (exp) Conflict between rule 1 and token OP resolved as reduce (%left OP). " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:327: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 62 ) # 62. conflicts.at:357: Defaulted Conflicted Reduction at_setup_line='conflicts.at:357' at_desc='Defaulted Conflicted Reduction' $at_quiet $ECHO_N " 62: Defaulted Conflicted Reduction $ECHO_C" at_xfail=no ( echo "62. conflicts.at:357: testing ..." $at_traceon cat >input.y <<'_ATEOF' %% exp: num | id; num: '0'; id : '0'; %% _ATEOF $at_traceoff echo "conflicts.at:371: bison -o input.c --report=all input.y" echo conflicts.at:371 >$at_check_line_file ( $at_traceon; bison -o input.c --report=all input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: conflicts: 1 reduce/reduce input.y:4.6-8: warning: rule never reduced because of conflicts: id: '0' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:371: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the contents of the report. $at_traceoff echo "conflicts.at:465: cat input.output" echo conflicts.at:465 >$at_check_line_file ( $at_traceon; cat input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Rules never reduced 4 id: '0' State 1 conflicts: 1 reduce/reduce Grammar 0 \$accept: exp \$end 1 exp: num 2 | id 3 num: '0' 4 id: '0' Terminals, with rules where they appear \$end (0) 0 '0' (48) 3 4 error (256) Nonterminals, with rules where they appear \$accept (4) on left: 0 exp (5) on left: 1 2, on right: 0 num (6) on left: 3, on right: 1 id (7) on left: 4, on right: 2 state 0 0 \$accept: . exp \$end 1 exp: . num 2 | . id 3 num: . '0' 4 id: . '0' '0' shift, and go to state 1 exp go to state 2 num go to state 3 id go to state 4 state 1 3 num: '0' . [\$end] 4 id: '0' . [\$end] \$end reduce using rule 3 (num) \$end [reduce using rule 4 (id)] \$default reduce using rule 3 (num) state 2 0 \$accept: exp . \$end \$end shift, and go to state 5 state 3 1 exp: num . \$default reduce using rule 1 (exp) state 4 2 exp: id . \$default reduce using rule 2 (exp) state 5 0 \$accept: exp \$end . \$default accept " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:465: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 63 ) # 63. conflicts.at:476: %expect not enough at_setup_line='conflicts.at:476' at_desc='%expect not enough' $at_quiet $ECHO_N " 63: %expect not enough $ECHO_C" at_xfail=no ( echo "63. conflicts.at:476: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token NUM OP %expect 0 %% exp: exp OP exp | NUM; _ATEOF $at_traceoff echo "conflicts.at:488: bison -o input.c input.y" echo conflicts.at:488 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: conflicts: 1 shift/reduce input.y: expected 0 shift/reduce conflicts " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "conflicts.at:488: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 64 ) # 64. conflicts.at:496: %expect right at_setup_line='conflicts.at:496' at_desc='%expect right' $at_quiet $ECHO_N " 64: %expect right $ECHO_C" at_xfail=no ( echo "64. conflicts.at:496: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token NUM OP %expect 1 %% exp: exp OP exp | NUM; _ATEOF $at_traceoff echo "conflicts.at:505: bison -o input.c input.y" echo conflicts.at:505 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:505: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 65 ) # 65. conflicts.at:513: %expect too much at_setup_line='conflicts.at:513' at_desc='%expect too much' $at_quiet $ECHO_N " 65: %expect too much $ECHO_C" at_xfail=no ( echo "65. conflicts.at:513: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token NUM OP %expect 2 %% exp: exp OP exp | NUM; _ATEOF $at_traceoff echo "conflicts.at:525: bison -o input.c input.y" echo conflicts.at:525 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: conflicts: 1 shift/reduce input.y: expected 2 shift/reduce conflicts " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "conflicts.at:525: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 66 ) # 66. conflicts.at:533: %expect with reduce conflicts at_setup_line='conflicts.at:533' at_desc='%expect with reduce conflicts' $at_quiet $ECHO_N " 66: %expect with reduce conflicts $ECHO_C" at_xfail=no ( echo "66. conflicts.at:533: testing ..." $at_traceon cat >input.y <<'_ATEOF' %expect 0 %% program: a 'a' | a a; a: 'a'; _ATEOF $at_traceoff echo "conflicts.at:545: bison -o input.c input.y" echo conflicts.at:545 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: conflicts: 1 reduce/reduce input.y: expected 0 reduce/reduce conflicts " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "conflicts.at:545: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 67 ) # 67. conflicts.at:553: %no-default-prec without %prec at_setup_line='conflicts.at:553' at_desc='%no-default-prec without %prec' $at_quiet $ECHO_N " 67: %no-default-prec without %prec $ECHO_C" at_xfail=no ( echo "67. conflicts.at:553: testing ..." $at_traceon cat >input.y <<'_ATEOF' %left '+' %left '*' %% %no-default-prec; e: e '+' e | e '*' e | '0' ; _ATEOF $at_traceoff echo "conflicts.at:571: bison -o input.c input.y" echo conflicts.at:571 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: conflicts: 4 shift/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:571: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 68 ) # 68. conflicts.at:579: %no-default-prec with %prec at_setup_line='conflicts.at:579' at_desc='%no-default-prec with %prec' $at_quiet $ECHO_N " 68: %no-default-prec with %prec $ECHO_C" at_xfail=no ( echo "68. conflicts.at:579: testing ..." $at_traceon cat >input.y <<'_ATEOF' %left '+' %left '*' %% %no-default-prec; e: e '+' e %prec '+' | e '*' e %prec '*' | '0' ; _ATEOF $at_traceoff echo "conflicts.at:595: bison -o input.c input.y" echo conflicts.at:595 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 69 ) # 69. conflicts.at:603: %default-prec at_setup_line='conflicts.at:603' at_desc='%default-prec' $at_quiet $ECHO_N " 69: %default-prec $ECHO_C" at_xfail=no ( echo "69. conflicts.at:603: testing ..." $at_traceon cat >input.y <<'_ATEOF' %left '+' %left '*' %% %default-prec; e: e '+' e | e '*' e | '0' ; _ATEOF $at_traceoff echo "conflicts.at:619: bison -o input.c input.y" echo conflicts.at:619 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "conflicts.at:619: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-9 ) # Banner 9. calc.at:541 cat <<\_ATEOF Simple LALR(1) Calculator. _ATEOF ;; 70 ) # 70. calc.at:550: Calculator at_setup_line='calc.at:550' at_desc='Calculator ' $at_quiet $ECHO_N " 70: Calculator $ECHO_C" at_xfail=no ( echo "70. calc.at:550: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:550: bison -o calc.c calc.y" echo calc.at:550 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:550: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:550 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:550: \$PREPARSER ./calc input" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:550: \$PREPARSER ./calc input" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:550: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:550: cat stderr" echo calc.at:550 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:550: \$PREPARSER ./calc input" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:550: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:550: cat stderr" echo calc.at:550 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:550: \$PREPARSER ./calc input" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:550: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:550: cat stderr" echo calc.at:550 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:550: \$PREPARSER ./calc input" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:550: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:550: cat stderr" echo calc.at:550 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:550: \$PREPARSER ./calc input" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:550: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:550: cat stderr" echo calc.at:550 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:550: \$PREPARSER ./calc /dev/null" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:550: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:550: cat stderr" echo calc.at:550 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:550: \$PREPARSER ./calc input" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:550: cat stderr" echo calc.at:550 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:550: \$PREPARSER ./calc input" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:550: cat stderr" echo calc.at:550 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:550: \$PREPARSER ./calc input" echo calc.at:550 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:550: cat stderr" echo calc.at:550 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 71 ) # 71. calc.at:552: Calculator %defines at_setup_line='calc.at:552' at_desc='Calculator %defines' $at_quiet $ECHO_N " 71: Calculator %defines $ECHO_C" at_xfail=no ( echo "71. calc.at:552: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %defines %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:552: bison -o calc.c calc.y" echo calc.at:552 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:552: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:552 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:552: \$PREPARSER ./calc input" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:552: \$PREPARSER ./calc input" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:552: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:552: cat stderr" echo calc.at:552 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:552: \$PREPARSER ./calc input" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:552: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:552: cat stderr" echo calc.at:552 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:552: \$PREPARSER ./calc input" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:552: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:552: cat stderr" echo calc.at:552 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:552: \$PREPARSER ./calc input" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:552: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:552: cat stderr" echo calc.at:552 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:552: \$PREPARSER ./calc input" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:552: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:552: cat stderr" echo calc.at:552 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:552: \$PREPARSER ./calc /dev/null" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:552: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:552: cat stderr" echo calc.at:552 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:552: \$PREPARSER ./calc input" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:552: cat stderr" echo calc.at:552 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:552: \$PREPARSER ./calc input" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:552: cat stderr" echo calc.at:552 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:552: \$PREPARSER ./calc input" echo calc.at:552 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:552: cat stderr" echo calc.at:552 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:552: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 72 ) # 72. calc.at:553: Calculator %locations at_setup_line='calc.at:553' at_desc='Calculator %locations' $at_quiet $ECHO_N " 72: Calculator %locations $ECHO_C" at_xfail=no ( echo "72. calc.at:553: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %locations %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%d.%d", (yylloc).first_line, (yylloc).first_column); if ((yylloc).first_line != (yylloc).last_line) fprintf (stderr, "-%d.%d", (yylloc).last_line, (yylloc).last_column - 1); else if ((yylloc).first_column != (yylloc).last_column - 1) fprintf (stderr, "-%d", (yylloc).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (void) { int res = getc (input); ; last_yylloc = (yylloc); if (res == '\n') { (yylloc).last_line++; (yylloc).last_column = 0; } else (yylloc).last_column++; return res; } static void unget_char ( int c) { ; /* Wrong when C == `\n'. */ (yylloc) = last_yylloc; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; (yylloc).last_column = 0; (yylloc).last_line = 1; } (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:553: bison -o calc.c calc.y" echo calc.at:553 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:553: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:553 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:553: \$PREPARSER ./calc input" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:553: \$PREPARSER ./calc input" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:553: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:553: cat stderr" echo calc.at:553 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:553: \$PREPARSER ./calc input" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:553: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:553: cat stderr" echo calc.at:553 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:553: \$PREPARSER ./calc input" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:553: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:553: cat stderr" echo calc.at:553 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:553: \$PREPARSER ./calc input" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:553: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:553: cat stderr" echo calc.at:553 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:553: \$PREPARSER ./calc input" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:553: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:553: cat stderr" echo calc.at:553 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:553: \$PREPARSER ./calc /dev/null" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:553: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:553: cat stderr" echo calc.at:553 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:553: \$PREPARSER ./calc input" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:553: cat stderr" echo calc.at:553 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:553: \$PREPARSER ./calc input" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:553: cat stderr" echo calc.at:553 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:553: \$PREPARSER ./calc input" echo calc.at:553 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:553: cat stderr" echo calc.at:553 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:553: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 73 ) # 73. calc.at:554: Calculator %name-prefix="calc" at_setup_line='calc.at:554' at_desc='Calculator %name-prefix="calc"' $at_quiet $ECHO_N " 73: Calculator %name-prefix="calc" $ECHO_C" at_xfail=no ( echo "73. calc.at:554: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %name-prefix="calc" %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:554: bison -o calc.c calc.y" echo calc.at:554 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:554: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:554 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:554: \$PREPARSER ./calc input" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:554: \$PREPARSER ./calc input" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:554: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:554: cat stderr" echo calc.at:554 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:554: \$PREPARSER ./calc input" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:554: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:554: cat stderr" echo calc.at:554 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:554: \$PREPARSER ./calc input" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:554: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:554: cat stderr" echo calc.at:554 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:554: \$PREPARSER ./calc input" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:554: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:554: cat stderr" echo calc.at:554 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:554: \$PREPARSER ./calc input" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:554: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:554: cat stderr" echo calc.at:554 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:554: \$PREPARSER ./calc /dev/null" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:554: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:554: cat stderr" echo calc.at:554 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:554: \$PREPARSER ./calc input" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:554: cat stderr" echo calc.at:554 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:554: \$PREPARSER ./calc input" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:554: cat stderr" echo calc.at:554 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:554: \$PREPARSER ./calc input" echo calc.at:554 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:554: cat stderr" echo calc.at:554 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:554: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 74 ) # 74. calc.at:555: Calculator %verbose at_setup_line='calc.at:555' at_desc='Calculator %verbose' $at_quiet $ECHO_N " 74: Calculator %verbose $ECHO_C" at_xfail=no ( echo "74. calc.at:555: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %verbose %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:555: bison -o calc.c calc.y" echo calc.at:555 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:555: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:555 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:555: \$PREPARSER ./calc input" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:555: \$PREPARSER ./calc input" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:555: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:555: cat stderr" echo calc.at:555 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:555: \$PREPARSER ./calc input" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:555: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:555: cat stderr" echo calc.at:555 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:555: \$PREPARSER ./calc input" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:555: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:555: cat stderr" echo calc.at:555 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:555: \$PREPARSER ./calc input" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:555: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:555: cat stderr" echo calc.at:555 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:555: \$PREPARSER ./calc input" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:555: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:555: cat stderr" echo calc.at:555 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:555: \$PREPARSER ./calc /dev/null" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:555: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:555: cat stderr" echo calc.at:555 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:555: \$PREPARSER ./calc input" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:555: cat stderr" echo calc.at:555 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:555: \$PREPARSER ./calc input" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:555: cat stderr" echo calc.at:555 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:555: \$PREPARSER ./calc input" echo calc.at:555 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:555: cat stderr" echo calc.at:555 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:555: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 75 ) # 75. calc.at:556: Calculator %yacc at_setup_line='calc.at:556' at_desc='Calculator %yacc' $at_quiet $ECHO_N " 75: Calculator %yacc $ECHO_C" at_xfail=no ( echo "75. calc.at:556: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %yacc %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:556: bison -o calc.c calc.y" echo calc.at:556 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:556: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:556 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:556: \$PREPARSER ./calc input" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:556: \$PREPARSER ./calc input" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:556: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:556: cat stderr" echo calc.at:556 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:556: \$PREPARSER ./calc input" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:556: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:556: cat stderr" echo calc.at:556 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:556: \$PREPARSER ./calc input" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:556: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:556: cat stderr" echo calc.at:556 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:556: \$PREPARSER ./calc input" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:556: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:556: cat stderr" echo calc.at:556 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:556: \$PREPARSER ./calc input" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:556: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:556: cat stderr" echo calc.at:556 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:556: \$PREPARSER ./calc /dev/null" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:556: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:556: cat stderr" echo calc.at:556 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:556: \$PREPARSER ./calc input" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:556: cat stderr" echo calc.at:556 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:556: \$PREPARSER ./calc input" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:556: cat stderr" echo calc.at:556 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:556: \$PREPARSER ./calc input" echo calc.at:556 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:556: cat stderr" echo calc.at:556 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 76 ) # 76. calc.at:557: Calculator %error-verbose at_setup_line='calc.at:557' at_desc='Calculator %error-verbose' $at_quiet $ECHO_N " 76: Calculator %error-verbose $ECHO_C" at_xfail=no ( echo "76. calc.at:557: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %error-verbose %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:557: bison -o calc.c calc.y" echo calc.at:557 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:557: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:557 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:557: \$PREPARSER ./calc input" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:557: \$PREPARSER ./calc input" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:557: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:557: cat stderr" echo calc.at:557 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:557: \$PREPARSER ./calc input" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:557: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:557: cat stderr" echo calc.at:557 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:557: \$PREPARSER ./calc input" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:557: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:557: cat stderr" echo calc.at:557 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:557: \$PREPARSER ./calc input" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:557: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:557: cat stderr" echo calc.at:557 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:557: \$PREPARSER ./calc input" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:557: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:557: cat stderr" echo calc.at:557 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:557: \$PREPARSER ./calc /dev/null" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:557: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:557: cat stderr" echo calc.at:557 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:557: \$PREPARSER ./calc input" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:557: cat stderr" echo calc.at:557 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:557: \$PREPARSER ./calc input" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:557: cat stderr" echo calc.at:557 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:557: \$PREPARSER ./calc input" echo calc.at:557 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:557: cat stderr" echo calc.at:557 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:557: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 77 ) # 77. calc.at:559: Calculator %pure-parser %locations at_setup_line='calc.at:559' at_desc='Calculator %pure-parser %locations' $at_quiet $ECHO_N " 77: Calculator %pure-parser %locations $ECHO_C" at_xfail=no ( echo "77. calc.at:559: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %pure-parser %locations %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:559: bison -o calc.c calc.y" echo calc.at:559 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:559: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:559 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:559: \$PREPARSER ./calc input" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:559: \$PREPARSER ./calc input" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:559: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:559: cat stderr" echo calc.at:559 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:559: \$PREPARSER ./calc input" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:559: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:559: cat stderr" echo calc.at:559 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:559: \$PREPARSER ./calc input" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:559: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:559: cat stderr" echo calc.at:559 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:559: \$PREPARSER ./calc input" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:559: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:559: cat stderr" echo calc.at:559 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:559: \$PREPARSER ./calc input" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:559: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:559: cat stderr" echo calc.at:559 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:559: \$PREPARSER ./calc /dev/null" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:559: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:559: cat stderr" echo calc.at:559 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:559: \$PREPARSER ./calc input" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:559: cat stderr" echo calc.at:559 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:559: \$PREPARSER ./calc input" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:559: cat stderr" echo calc.at:559 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:559: \$PREPARSER ./calc input" echo calc.at:559 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:559: cat stderr" echo calc.at:559 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:559: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 78 ) # 78. calc.at:560: Calculator %error-verbose %locations at_setup_line='calc.at:560' at_desc='Calculator %error-verbose %locations' $at_quiet $ECHO_N " 78: Calculator %error-verbose %locations $ECHO_C" at_xfail=no ( echo "78. calc.at:560: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %error-verbose %locations %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%d.%d", (yylloc).first_line, (yylloc).first_column); if ((yylloc).first_line != (yylloc).last_line) fprintf (stderr, "-%d.%d", (yylloc).last_line, (yylloc).last_column - 1); else if ((yylloc).first_column != (yylloc).last_column - 1) fprintf (stderr, "-%d", (yylloc).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (void) { int res = getc (input); ; last_yylloc = (yylloc); if (res == '\n') { (yylloc).last_line++; (yylloc).last_column = 0; } else (yylloc).last_column++; return res; } static void unget_char ( int c) { ; /* Wrong when C == `\n'. */ (yylloc) = last_yylloc; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; (yylloc).last_column = 0; (yylloc).last_line = 1; } (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:560: bison -o calc.c calc.y" echo calc.at:560 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:560: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:560 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:560: \$PREPARSER ./calc input" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:560: \$PREPARSER ./calc input" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:560: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:560: cat stderr" echo calc.at:560 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:560: \$PREPARSER ./calc input" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:560: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:560: cat stderr" echo calc.at:560 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:560: \$PREPARSER ./calc input" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:560: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:560: cat stderr" echo calc.at:560 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:560: \$PREPARSER ./calc input" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:560: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:560: cat stderr" echo calc.at:560 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:560: \$PREPARSER ./calc input" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:560: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:560: cat stderr" echo calc.at:560 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:560: \$PREPARSER ./calc /dev/null" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:560: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:560: cat stderr" echo calc.at:560 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:560: \$PREPARSER ./calc input" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:560: cat stderr" echo calc.at:560 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:560: \$PREPARSER ./calc input" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:560: cat stderr" echo calc.at:560 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:560: \$PREPARSER ./calc input" echo calc.at:560 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:560: cat stderr" echo calc.at:560 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:560: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 79 ) # 79. calc.at:562: Calculator %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:562' at_desc='Calculator %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N " 79: Calculator %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "79. calc.at:562: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%d.%d", (yylloc).first_line, (yylloc).first_column); if ((yylloc).first_line != (yylloc).last_line) fprintf (stderr, "-%d.%d", (yylloc).last_line, (yylloc).last_column - 1); else if ((yylloc).first_column != (yylloc).last_column - 1) fprintf (stderr, "-%d", (yylloc).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (void) { int res = getc (input); ; last_yylloc = (yylloc); if (res == '\n') { (yylloc).last_line++; (yylloc).last_column = 0; } else (yylloc).last_column++; return res; } static void unget_char ( int c) { ; /* Wrong when C == `\n'. */ (yylloc) = last_yylloc; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; (yylloc).last_column = 0; (yylloc).last_line = 1; } (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:562: bison -o calc.c calc.y" echo calc.at:562 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:562: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:562 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:562: \$PREPARSER ./calc input" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:562: \$PREPARSER ./calc input" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:562: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:562: cat stderr" echo calc.at:562 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:562: \$PREPARSER ./calc input" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:562: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:562: cat stderr" echo calc.at:562 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:562: \$PREPARSER ./calc input" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:562: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:562: cat stderr" echo calc.at:562 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:562: \$PREPARSER ./calc input" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:562: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:562: cat stderr" echo calc.at:562 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:562: \$PREPARSER ./calc input" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:562: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:562: cat stderr" echo calc.at:562 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:562: \$PREPARSER ./calc /dev/null" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:562: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:562: cat stderr" echo calc.at:562 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:562: \$PREPARSER ./calc input" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:562: cat stderr" echo calc.at:562 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:562: \$PREPARSER ./calc input" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:562: cat stderr" echo calc.at:562 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:562: \$PREPARSER ./calc input" echo calc.at:562 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:562: cat stderr" echo calc.at:562 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:562: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 80 ) # 80. calc.at:564: Calculator %debug at_setup_line='calc.at:564' at_desc='Calculator %debug' $at_quiet $ECHO_N " 80: Calculator %debug $ECHO_C" at_xfail=no ( echo "80. calc.at:564: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %debug %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } yydebug = 1; status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:564: bison -o calc.c calc.y" echo calc.at:564 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:564: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:564 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:564: \$PREPARSER ./calc input" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:564: \$PREPARSER ./calc input" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:564: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:564: cat stderr" echo calc.at:564 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:564: \$PREPARSER ./calc input" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:564: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:564: cat stderr" echo calc.at:564 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:564: \$PREPARSER ./calc input" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:564: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:564: cat stderr" echo calc.at:564 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:564: \$PREPARSER ./calc input" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:564: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:564: cat stderr" echo calc.at:564 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:564: \$PREPARSER ./calc input" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:564: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:564: cat stderr" echo calc.at:564 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:564: \$PREPARSER ./calc /dev/null" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:564: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:564: cat stderr" echo calc.at:564 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:564: \$PREPARSER ./calc input" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:564: cat stderr" echo calc.at:564 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:564: \$PREPARSER ./calc input" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:564: cat stderr" echo calc.at:564 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:564: \$PREPARSER ./calc input" echo calc.at:564 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:564: cat stderr" echo calc.at:564 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:564: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 81 ) # 81. calc.at:565: Calculator %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:565' at_desc='Calculator %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N " 81: Calculator %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "81. calc.at:565: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%d.%d", (yylloc).first_line, (yylloc).first_column); if ((yylloc).first_line != (yylloc).last_line) fprintf (stderr, "-%d.%d", (yylloc).last_line, (yylloc).last_column - 1); else if ((yylloc).first_column != (yylloc).last_column - 1) fprintf (stderr, "-%d", (yylloc).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (void) { int res = getc (input); ; last_yylloc = (yylloc); if (res == '\n') { (yylloc).last_line++; (yylloc).last_column = 0; } else (yylloc).last_column++; return res; } static void unget_char ( int c) { ; /* Wrong when C == `\n'. */ (yylloc) = last_yylloc; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; (yylloc).last_column = 0; (yylloc).last_line = 1; } (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } yydebug = 1; status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:565: bison -o calc.c calc.y" echo calc.at:565 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:565: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:565 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:565: \$PREPARSER ./calc input" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:565: \$PREPARSER ./calc input" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:565: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:565: cat stderr" echo calc.at:565 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:565: \$PREPARSER ./calc input" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:565: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:565: cat stderr" echo calc.at:565 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:565: \$PREPARSER ./calc input" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:565: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:565: cat stderr" echo calc.at:565 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:565: \$PREPARSER ./calc input" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:565: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:565: cat stderr" echo calc.at:565 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:565: \$PREPARSER ./calc input" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:565: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:565: cat stderr" echo calc.at:565 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:565: \$PREPARSER ./calc /dev/null" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:565: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:565: cat stderr" echo calc.at:565 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:565: \$PREPARSER ./calc input" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:565: cat stderr" echo calc.at:565 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:565: \$PREPARSER ./calc input" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:565: cat stderr" echo calc.at:565 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:565: \$PREPARSER ./calc input" echo calc.at:565 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:565: cat stderr" echo calc.at:565 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:565: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 82 ) # 82. calc.at:567: Calculator %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:567' at_desc='Calculator %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N " 82: Calculator %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "82. calc.at:567: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } yydebug = 1; status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:567: bison -o calc.c calc.y" echo calc.at:567 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:567: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:567 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:567: \$PREPARSER ./calc input" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:567: \$PREPARSER ./calc input" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:567: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:567: cat stderr" echo calc.at:567 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:567: \$PREPARSER ./calc input" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:567: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:567: cat stderr" echo calc.at:567 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:567: \$PREPARSER ./calc input" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:567: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:567: cat stderr" echo calc.at:567 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:567: \$PREPARSER ./calc input" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:567: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:567: cat stderr" echo calc.at:567 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:567: \$PREPARSER ./calc input" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:567: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:567: cat stderr" echo calc.at:567 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:567: \$PREPARSER ./calc /dev/null" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:567: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:567: cat stderr" echo calc.at:567 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:567: \$PREPARSER ./calc input" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:567: cat stderr" echo calc.at:567 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:567: \$PREPARSER ./calc input" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:567: cat stderr" echo calc.at:567 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:567: \$PREPARSER ./calc input" echo calc.at:567 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:567: cat stderr" echo calc.at:567 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:567: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 83 ) # 83. calc.at:569: Calculator %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count} at_setup_line='calc.at:569' at_desc='Calculator %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}' $at_quiet $ECHO_N " 83: Calculator %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}$ECHO_C" at_xfail=no ( echo "83. calc.at:569: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count} %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror (YYLTYPE *llocp, semantic_value *result, int *count, const char *s ); static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { ++*count; ++global_count; } ; line: '\n' | exp '\n' { *result = global_result = $1; } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror (YYLTYPE *llocp, semantic_value *result, int *count, const char *s) { (void) result; (void) count; fprintf (stderr, "%d.%d", (*llocp).first_line, (*llocp).first_column); if ((*llocp).first_line != (*llocp).last_line) fprintf (stderr, "-%d.%d", (*llocp).last_line, (*llocp).last_column - 1); else if ((*llocp).first_column != (*llocp).last_column - 1) fprintf (stderr, "-%d", (*llocp).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } yydebug = 1; status = yyparse (&result, &count); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:569: bison -o calc.c calc.y" echo calc.at:569 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:569: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:569 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:569: \$PREPARSER ./calc input" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:569: \$PREPARSER ./calc input" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:569: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:569: cat stderr" echo calc.at:569 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:569: \$PREPARSER ./calc input" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:569: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:569: cat stderr" echo calc.at:569 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:569: \$PREPARSER ./calc input" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:569: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:569: cat stderr" echo calc.at:569 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:569: \$PREPARSER ./calc input" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:569: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:569: cat stderr" echo calc.at:569 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:569: \$PREPARSER ./calc input" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:569: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:569: cat stderr" echo calc.at:569 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:569: \$PREPARSER ./calc /dev/null" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:569: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:569: cat stderr" echo calc.at:569 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:569: \$PREPARSER ./calc input" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:569: cat stderr" echo calc.at:569 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:569: \$PREPARSER ./calc input" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:569: cat stderr" echo calc.at:569 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:569: \$PREPARSER ./calc input" echo calc.at:569 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:569: cat stderr" echo calc.at:569 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:569: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-10 ) # Banner 10. calc.at:576 cat <<\_ATEOF Simple GLR Calculator. _ATEOF ;; 84 ) # 84. calc.at:586: Calculator %glr-parser at_setup_line='calc.at:586' at_desc='Calculator %glr-parser ' $at_quiet $ECHO_N " 84: Calculator %glr-parser $ECHO_C" at_xfail=no ( echo "84. calc.at:586: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:586: bison -o calc.c calc.y" echo calc.at:586 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:586: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:586 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:586: \$PREPARSER ./calc input" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:586: \$PREPARSER ./calc input" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:586: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:586: cat stderr" echo calc.at:586 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:586: \$PREPARSER ./calc input" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:586: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:586: cat stderr" echo calc.at:586 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:586: \$PREPARSER ./calc input" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:586: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:586: cat stderr" echo calc.at:586 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:586: \$PREPARSER ./calc input" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:586: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:586: cat stderr" echo calc.at:586 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:586: \$PREPARSER ./calc input" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:586: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:586: cat stderr" echo calc.at:586 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:586: \$PREPARSER ./calc /dev/null" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:586: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:586: cat stderr" echo calc.at:586 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:586: \$PREPARSER ./calc input" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:586: cat stderr" echo calc.at:586 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:586: \$PREPARSER ./calc input" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:586: cat stderr" echo calc.at:586 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:586: \$PREPARSER ./calc input" echo calc.at:586 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:586: cat stderr" echo calc.at:586 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:586: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 85 ) # 85. calc.at:588: Calculator %glr-parser %defines at_setup_line='calc.at:588' at_desc='Calculator %glr-parser %defines' $at_quiet $ECHO_N " 85: Calculator %glr-parser %defines $ECHO_C" at_xfail=no ( echo "85. calc.at:588: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %defines %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:588: bison -o calc.c calc.y" echo calc.at:588 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:588: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:588 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:588: \$PREPARSER ./calc input" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:588: \$PREPARSER ./calc input" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:588: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:588: cat stderr" echo calc.at:588 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:588: \$PREPARSER ./calc input" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:588: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:588: cat stderr" echo calc.at:588 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:588: \$PREPARSER ./calc input" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:588: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:588: cat stderr" echo calc.at:588 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:588: \$PREPARSER ./calc input" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:588: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:588: cat stderr" echo calc.at:588 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:588: \$PREPARSER ./calc input" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:588: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:588: cat stderr" echo calc.at:588 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:588: \$PREPARSER ./calc /dev/null" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:588: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:588: cat stderr" echo calc.at:588 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:588: \$PREPARSER ./calc input" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:588: cat stderr" echo calc.at:588 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:588: \$PREPARSER ./calc input" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:588: cat stderr" echo calc.at:588 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:588: \$PREPARSER ./calc input" echo calc.at:588 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:588: cat stderr" echo calc.at:588 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:588: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 86 ) # 86. calc.at:589: Calculator %glr-parser %locations at_setup_line='calc.at:589' at_desc='Calculator %glr-parser %locations' $at_quiet $ECHO_N " 86: Calculator %glr-parser %locations $ECHO_C" at_xfail=no ( echo "86. calc.at:589: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %locations %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%d.%d", (yylloc).first_line, (yylloc).first_column); if ((yylloc).first_line != (yylloc).last_line) fprintf (stderr, "-%d.%d", (yylloc).last_line, (yylloc).last_column - 1); else if ((yylloc).first_column != (yylloc).last_column - 1) fprintf (stderr, "-%d", (yylloc).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (void) { int res = getc (input); ; last_yylloc = (yylloc); if (res == '\n') { (yylloc).last_line++; (yylloc).last_column = 0; } else (yylloc).last_column++; return res; } static void unget_char ( int c) { ; /* Wrong when C == `\n'. */ (yylloc) = last_yylloc; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; (yylloc).last_column = 0; (yylloc).last_line = 1; } (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:589: bison -o calc.c calc.y" echo calc.at:589 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:589: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:589 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:589: \$PREPARSER ./calc input" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:589: \$PREPARSER ./calc input" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:589: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:589: cat stderr" echo calc.at:589 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:589: \$PREPARSER ./calc input" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:589: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:589: cat stderr" echo calc.at:589 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:589: \$PREPARSER ./calc input" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:589: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:589: cat stderr" echo calc.at:589 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:589: \$PREPARSER ./calc input" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:589: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:589: cat stderr" echo calc.at:589 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:589: \$PREPARSER ./calc input" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:589: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:589: cat stderr" echo calc.at:589 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:589: \$PREPARSER ./calc /dev/null" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:589: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:589: cat stderr" echo calc.at:589 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:589: \$PREPARSER ./calc input" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:589: cat stderr" echo calc.at:589 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:589: \$PREPARSER ./calc input" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:589: cat stderr" echo calc.at:589 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:589: \$PREPARSER ./calc input" echo calc.at:589 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:589: cat stderr" echo calc.at:589 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:589: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 87 ) # 87. calc.at:590: Calculator %glr-parser %name-prefix="calc" at_setup_line='calc.at:590' at_desc='Calculator %glr-parser %name-prefix="calc"' $at_quiet $ECHO_N " 87: Calculator %glr-parser %name-prefix="calc" $ECHO_C" at_xfail=no ( echo "87. calc.at:590: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %name-prefix="calc" %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:590: bison -o calc.c calc.y" echo calc.at:590 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:590: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:590 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:590: \$PREPARSER ./calc input" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:590: \$PREPARSER ./calc input" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:590: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:590: cat stderr" echo calc.at:590 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:590: \$PREPARSER ./calc input" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:590: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:590: cat stderr" echo calc.at:590 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:590: \$PREPARSER ./calc input" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:590: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:590: cat stderr" echo calc.at:590 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:590: \$PREPARSER ./calc input" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:590: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:590: cat stderr" echo calc.at:590 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:590: \$PREPARSER ./calc input" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:590: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:590: cat stderr" echo calc.at:590 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:590: \$PREPARSER ./calc /dev/null" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:590: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:590: cat stderr" echo calc.at:590 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:590: \$PREPARSER ./calc input" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:590: cat stderr" echo calc.at:590 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:590: \$PREPARSER ./calc input" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:590: cat stderr" echo calc.at:590 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:590: \$PREPARSER ./calc input" echo calc.at:590 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:590: cat stderr" echo calc.at:590 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:590: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 88 ) # 88. calc.at:591: Calculator %glr-parser %verbose at_setup_line='calc.at:591' at_desc='Calculator %glr-parser %verbose' $at_quiet $ECHO_N " 88: Calculator %glr-parser %verbose $ECHO_C" at_xfail=no ( echo "88. calc.at:591: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %verbose %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:591: bison -o calc.c calc.y" echo calc.at:591 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:591: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:591 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:591: \$PREPARSER ./calc input" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:591: \$PREPARSER ./calc input" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:591: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:591: cat stderr" echo calc.at:591 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:591: \$PREPARSER ./calc input" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:591: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:591: cat stderr" echo calc.at:591 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:591: \$PREPARSER ./calc input" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:591: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:591: cat stderr" echo calc.at:591 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:591: \$PREPARSER ./calc input" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:591: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:591: cat stderr" echo calc.at:591 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:591: \$PREPARSER ./calc input" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:591: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:591: cat stderr" echo calc.at:591 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:591: \$PREPARSER ./calc /dev/null" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:591: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:591: cat stderr" echo calc.at:591 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:591: \$PREPARSER ./calc input" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:591: cat stderr" echo calc.at:591 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:591: \$PREPARSER ./calc input" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:591: cat stderr" echo calc.at:591 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:591: \$PREPARSER ./calc input" echo calc.at:591 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:591: cat stderr" echo calc.at:591 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:591: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 89 ) # 89. calc.at:592: Calculator %glr-parser %yacc at_setup_line='calc.at:592' at_desc='Calculator %glr-parser %yacc' $at_quiet $ECHO_N " 89: Calculator %glr-parser %yacc $ECHO_C" at_xfail=no ( echo "89. calc.at:592: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %yacc %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:592: bison -o calc.c calc.y" echo calc.at:592 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:592: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:592 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:592: \$PREPARSER ./calc input" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:592: \$PREPARSER ./calc input" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:592: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:592: cat stderr" echo calc.at:592 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:592: \$PREPARSER ./calc input" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:592: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:592: cat stderr" echo calc.at:592 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:592: \$PREPARSER ./calc input" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:592: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:592: cat stderr" echo calc.at:592 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:592: \$PREPARSER ./calc input" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:592: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:592: cat stderr" echo calc.at:592 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:592: \$PREPARSER ./calc input" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:592: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:592: cat stderr" echo calc.at:592 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:592: \$PREPARSER ./calc /dev/null" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:592: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:592: cat stderr" echo calc.at:592 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:592: \$PREPARSER ./calc input" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:592: cat stderr" echo calc.at:592 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:592: \$PREPARSER ./calc input" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:592: cat stderr" echo calc.at:592 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:592: \$PREPARSER ./calc input" echo calc.at:592 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:592: cat stderr" echo calc.at:592 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:592: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 90 ) # 90. calc.at:593: Calculator %glr-parser %error-verbose at_setup_line='calc.at:593' at_desc='Calculator %glr-parser %error-verbose' $at_quiet $ECHO_N " 90: Calculator %glr-parser %error-verbose $ECHO_C" at_xfail=no ( echo "90. calc.at:593: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %error-verbose %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:593: bison -o calc.c calc.y" echo calc.at:593 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:593: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:593 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:593: \$PREPARSER ./calc input" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:593: \$PREPARSER ./calc input" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:593: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:593: cat stderr" echo calc.at:593 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:593: \$PREPARSER ./calc input" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:593: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:593: cat stderr" echo calc.at:593 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:593: \$PREPARSER ./calc input" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:593: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:593: cat stderr" echo calc.at:593 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:593: \$PREPARSER ./calc input" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:593: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:593: cat stderr" echo calc.at:593 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:593: \$PREPARSER ./calc input" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:593: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:593: cat stderr" echo calc.at:593 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:593: \$PREPARSER ./calc /dev/null" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:593: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:593: cat stderr" echo calc.at:593 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:593: \$PREPARSER ./calc input" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:593: cat stderr" echo calc.at:593 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:593: \$PREPARSER ./calc input" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:593: cat stderr" echo calc.at:593 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:593: \$PREPARSER ./calc input" echo calc.at:593 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:593: cat stderr" echo calc.at:593 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:593: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 91 ) # 91. calc.at:595: Calculator %glr-parser %pure-parser %locations at_setup_line='calc.at:595' at_desc='Calculator %glr-parser %pure-parser %locations' $at_quiet $ECHO_N " 91: Calculator %glr-parser %pure-parser %locations$ECHO_C" at_xfail=no ( echo "91. calc.at:595: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %pure-parser %locations %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror (YYLTYPE *llocp, const char *s ); static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror (YYLTYPE *llocp, const char *s) { fprintf (stderr, "%d.%d", (*llocp).first_line, (*llocp).first_column); if ((*llocp).first_line != (*llocp).last_line) fprintf (stderr, "-%d.%d", (*llocp).last_line, (*llocp).last_column - 1); else if ((*llocp).first_column != (*llocp).last_column - 1) fprintf (stderr, "-%d", (*llocp).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:595: bison -o calc.c calc.y" echo calc.at:595 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:595: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:595 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:595: \$PREPARSER ./calc input" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:595: \$PREPARSER ./calc input" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:595: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:595: cat stderr" echo calc.at:595 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:595: \$PREPARSER ./calc input" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:595: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:595: cat stderr" echo calc.at:595 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:595: \$PREPARSER ./calc input" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:595: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:595: cat stderr" echo calc.at:595 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:595: \$PREPARSER ./calc input" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:595: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:595: cat stderr" echo calc.at:595 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:595: \$PREPARSER ./calc input" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:595: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:595: cat stderr" echo calc.at:595 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:595: \$PREPARSER ./calc /dev/null" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:595: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:595: cat stderr" echo calc.at:595 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:595: \$PREPARSER ./calc input" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:595: cat stderr" echo calc.at:595 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:595: \$PREPARSER ./calc input" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:595: cat stderr" echo calc.at:595 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:595: \$PREPARSER ./calc input" echo calc.at:595 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:595: cat stderr" echo calc.at:595 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:595: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 92 ) # 92. calc.at:596: Calculator %glr-parser %error-verbose %locations at_setup_line='calc.at:596' at_desc='Calculator %glr-parser %error-verbose %locations' $at_quiet $ECHO_N " 92: Calculator %glr-parser %error-verbose %locations$ECHO_C" at_xfail=no ( echo "92. calc.at:596: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %error-verbose %locations %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%d.%d", (yylloc).first_line, (yylloc).first_column); if ((yylloc).first_line != (yylloc).last_line) fprintf (stderr, "-%d.%d", (yylloc).last_line, (yylloc).last_column - 1); else if ((yylloc).first_column != (yylloc).last_column - 1) fprintf (stderr, "-%d", (yylloc).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (void) { int res = getc (input); ; last_yylloc = (yylloc); if (res == '\n') { (yylloc).last_line++; (yylloc).last_column = 0; } else (yylloc).last_column++; return res; } static void unget_char ( int c) { ; /* Wrong when C == `\n'. */ (yylloc) = last_yylloc; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; (yylloc).last_column = 0; (yylloc).last_line = 1; } (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:596: bison -o calc.c calc.y" echo calc.at:596 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:596: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:596 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:596: \$PREPARSER ./calc input" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:596: \$PREPARSER ./calc input" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:596: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:596: cat stderr" echo calc.at:596 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:596: \$PREPARSER ./calc input" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:596: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:596: cat stderr" echo calc.at:596 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:596: \$PREPARSER ./calc input" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:596: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:596: cat stderr" echo calc.at:596 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:596: \$PREPARSER ./calc input" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:596: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:596: cat stderr" echo calc.at:596 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:596: \$PREPARSER ./calc input" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:596: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:596: cat stderr" echo calc.at:596 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:596: \$PREPARSER ./calc /dev/null" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:596: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:596: cat stderr" echo calc.at:596 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:596: \$PREPARSER ./calc input" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:596: cat stderr" echo calc.at:596 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:596: \$PREPARSER ./calc input" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:596: cat stderr" echo calc.at:596 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:596: \$PREPARSER ./calc input" echo calc.at:596 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:596: cat stderr" echo calc.at:596 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:596: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 93 ) # 93. calc.at:598: Calculator %glr-parser %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:598' at_desc='Calculator %glr-parser %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N " 93: Calculator %glr-parser %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "93. calc.at:598: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %error-verbose %locations %defines %name-prefix="calc" %verbose %yacc %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%d.%d", (yylloc).first_line, (yylloc).first_column); if ((yylloc).first_line != (yylloc).last_line) fprintf (stderr, "-%d.%d", (yylloc).last_line, (yylloc).last_column - 1); else if ((yylloc).first_column != (yylloc).last_column - 1) fprintf (stderr, "-%d", (yylloc).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (void) { int res = getc (input); ; last_yylloc = (yylloc); if (res == '\n') { (yylloc).last_line++; (yylloc).last_column = 0; } else (yylloc).last_column++; return res; } static void unget_char ( int c) { ; /* Wrong when C == `\n'. */ (yylloc) = last_yylloc; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; (yylloc).last_column = 0; (yylloc).last_line = 1; } (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:598: bison -o calc.c calc.y" echo calc.at:598 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:598: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:598 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:598: \$PREPARSER ./calc input" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:598: \$PREPARSER ./calc input" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:598: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:598: cat stderr" echo calc.at:598 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:598: \$PREPARSER ./calc input" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:598: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:598: cat stderr" echo calc.at:598 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:598: \$PREPARSER ./calc input" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:598: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:598: cat stderr" echo calc.at:598 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:598: \$PREPARSER ./calc input" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:598: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:598: cat stderr" echo calc.at:598 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:598: \$PREPARSER ./calc input" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:598: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:598: cat stderr" echo calc.at:598 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:598: \$PREPARSER ./calc /dev/null" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:598: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:598: cat stderr" echo calc.at:598 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:598: \$PREPARSER ./calc input" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:598: cat stderr" echo calc.at:598 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:598: \$PREPARSER ./calc input" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:598: cat stderr" echo calc.at:598 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:598: \$PREPARSER ./calc input" echo calc.at:598 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:598: cat stderr" echo calc.at:598 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:598: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 94 ) # 94. calc.at:600: Calculator %glr-parser %debug at_setup_line='calc.at:600' at_desc='Calculator %glr-parser %debug' $at_quiet $ECHO_N " 94: Calculator %glr-parser %debug $ECHO_C" at_xfail=no ( echo "94. calc.at:600: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %debug %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%s\n", s); } static int get_char (void) { int res = getc (input); ; return res; } static void unget_char ( int c) { ; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; } /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } yydebug = 1; status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:600: bison -o calc.c calc.y" echo calc.at:600 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:600: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:600 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:600: \$PREPARSER ./calc input" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:600: \$PREPARSER ./calc input" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:600: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:600: cat stderr" echo calc.at:600 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:600: \$PREPARSER ./calc input" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:600: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:600: cat stderr" echo calc.at:600 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:600: \$PREPARSER ./calc input" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:600: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:600: cat stderr" echo calc.at:600 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:600: \$PREPARSER ./calc input" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:600: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:600: cat stderr" echo calc.at:600 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:600: \$PREPARSER ./calc input" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:600: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:600: cat stderr" echo calc.at:600 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:600: \$PREPARSER ./calc /dev/null" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:600: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:600: cat stderr" echo calc.at:600 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:600: \$PREPARSER ./calc input" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:600: cat stderr" echo calc.at:600 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:600: \$PREPARSER ./calc input" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:600: cat stderr" echo calc.at:600 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:600: \$PREPARSER ./calc input" echo calc.at:600 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:600: cat stderr" echo calc.at:600 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:600: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 95 ) # 95. calc.at:601: Calculator %glr-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:601' at_desc='Calculator %glr-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N " 95: Calculator %glr-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "95. calc.at:601: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror ( const char *s ); static int yylex (void); static int get_char (void); static void unget_char ( int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror ( const char *s) { fprintf (stderr, "%d.%d", (yylloc).first_line, (yylloc).first_column); if ((yylloc).first_line != (yylloc).last_line) fprintf (stderr, "-%d.%d", (yylloc).last_line, (yylloc).last_column - 1); else if ((yylloc).first_column != (yylloc).last_column - 1) fprintf (stderr, "-%d", (yylloc).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (void) { int res = getc (input); ; last_yylloc = (yylloc); if (res == '\n') { (yylloc).last_line++; (yylloc).last_column = 0; } else (yylloc).last_column++; return res; } static void unget_char ( int c) { ; /* Wrong when C == `\n'. */ (yylloc) = last_yylloc; ungetc (c, input); } static int read_signed_integer (void) { int c = get_char (); int sign = 1; int n = 0; ; if (c == '-') { c = get_char (); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (); } unget_char ( c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (void) { static int init = 1; int c; if (init) { init = 0; (yylloc).last_column = 0; (yylloc).last_line = 1; } (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; /* Skip white space. */ while ((c = get_char ()) == ' ' || c == '\t') { (yylloc).first_column = (yylloc).last_column; (yylloc).first_line = (yylloc).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char ( c); (yylval).ival = read_signed_integer (); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } yydebug = 1; status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:601: bison -o calc.c calc.y" echo calc.at:601 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:601: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:601 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:601: \$PREPARSER ./calc input" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:601: \$PREPARSER ./calc input" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:601: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:601: cat stderr" echo calc.at:601 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:601: \$PREPARSER ./calc input" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:601: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:601: cat stderr" echo calc.at:601 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:601: \$PREPARSER ./calc input" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:601: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:601: cat stderr" echo calc.at:601 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:601: \$PREPARSER ./calc input" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:601: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:601: cat stderr" echo calc.at:601 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:601: \$PREPARSER ./calc input" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:601: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:601: cat stderr" echo calc.at:601 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:601: \$PREPARSER ./calc /dev/null" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:601: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:601: cat stderr" echo calc.at:601 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:601: \$PREPARSER ./calc input" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:601: cat stderr" echo calc.at:601 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:601: \$PREPARSER ./calc input" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:601: cat stderr" echo calc.at:601 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:601: \$PREPARSER ./calc input" echo calc.at:601 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:601: cat stderr" echo calc.at:601 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:601: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 96 ) # 96. calc.at:603: Calculator %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:603' at_desc='Calculator %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N " 96: Calculator %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "96. calc.at:603: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror (YYLTYPE *llocp, const char *s ); static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror (YYLTYPE *llocp, const char *s) { fprintf (stderr, "%d.%d", (*llocp).first_line, (*llocp).first_column); if ((*llocp).first_line != (*llocp).last_line) fprintf (stderr, "-%d.%d", (*llocp).last_line, (*llocp).last_column - 1); else if ((*llocp).first_column != (*llocp).last_column - 1) fprintf (stderr, "-%d", (*llocp).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } yydebug = 1; status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:603: bison -o calc.c calc.y" echo calc.at:603 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:603: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:603 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:603: \$PREPARSER ./calc input" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:603: \$PREPARSER ./calc input" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:603: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:603: cat stderr" echo calc.at:603 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:603: \$PREPARSER ./calc input" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:603: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:603: cat stderr" echo calc.at:603 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:603: \$PREPARSER ./calc input" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:603: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:603: cat stderr" echo calc.at:603 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:603: \$PREPARSER ./calc input" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:603: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:603: cat stderr" echo calc.at:603 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:603: \$PREPARSER ./calc input" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:603: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:603: cat stderr" echo calc.at:603 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:603: \$PREPARSER ./calc /dev/null" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:603: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:603: cat stderr" echo calc.at:603 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:603: \$PREPARSER ./calc input" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:603: cat stderr" echo calc.at:603 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:603: \$PREPARSER ./calc input" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:603: cat stderr" echo calc.at:603 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:603: \$PREPARSER ./calc input" echo calc.at:603 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:603: cat stderr" echo calc.at:603 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:603: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 97 ) # 97. calc.at:605: Calculator %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count} at_setup_line='calc.at:605' at_desc='Calculator %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}' $at_quiet $ECHO_N " 97: Calculator %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}$ECHO_C" at_xfail=no ( echo "97. calc.at:605: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %glr-parser %pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count} %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ static void yyerror (YYLTYPE *llocp, semantic_value *result, int *count, const char *s ); static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { ++*count; ++global_count; } ; line: '\n' | exp '\n' { *result = global_result = $1; } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; static void yyerror (YYLTYPE *llocp, semantic_value *result, int *count, const char *s) { (void) result; (void) count; fprintf (stderr, "%d.%d", (*llocp).first_line, (*llocp).first_column); if ((*llocp).first_line != (*llocp).last_line) fprintf (stderr, "-%d.%d", (*llocp).last_line, (*llocp).last_column - 1); else if ((*llocp).first_column != (*llocp).last_column - 1) fprintf (stderr, "-%d", (*llocp).last_column - 1); fprintf (stderr, ": "); fprintf (stderr, "%s\n", s); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } yydebug = 1; status = yyparse (&result, &count); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:605: bison -o calc.c calc.y" echo calc.at:605 >$at_check_line_file ( $at_traceon; bison -o calc.c calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:605: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.c \$LIBS" echo calc.at:605 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:605: \$PREPARSER ./calc input" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:605: \$PREPARSER ./calc input" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:605: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:605: cat stderr" echo calc.at:605 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:605: \$PREPARSER ./calc input" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:605: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:605: cat stderr" echo calc.at:605 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:605: \$PREPARSER ./calc input" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:605: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:605: cat stderr" echo calc.at:605 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:605: \$PREPARSER ./calc input" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:605: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:605: cat stderr" echo calc.at:605 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:605: \$PREPARSER ./calc input" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:605: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:605: cat stderr" echo calc.at:605 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:605: \$PREPARSER ./calc /dev/null" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:605: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:605: cat stderr" echo calc.at:605 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:605: \$PREPARSER ./calc input" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:605: cat stderr" echo calc.at:605 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:605: \$PREPARSER ./calc input" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:605: cat stderr" echo calc.at:605 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:605: \$PREPARSER ./calc input" echo calc.at:605 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:605: cat stderr" echo calc.at:605 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:605: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-11 ) # Banner 11. calc.at:612 cat <<\_ATEOF Simple LALR(1) C++ Calculator. _ATEOF ;; 98 ) # 98. calc.at:621: Calculator %skeleton "lalr1.cc" %defines %locations at_setup_line='calc.at:621' at_desc='Calculator %skeleton "lalr1.cc" %defines %locations ' $at_quiet $ECHO_N " 98: Calculator %skeleton "lalr1.cc" %defines %locations $ECHO_C" at_xfail=no ( echo "98. calc.at:621: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %skeleton "lalr1.cc" %defines %locations %define "global_tokens_and_yystype" %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); #ifndef YYLTYPE # define YYLTYPE yy::location #endif #define first_line begin.line #define first_column begin.column #define last_line end.line #define last_column end.column static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* The lalr1.cc skeleton, for backward compatibility, defines a constructor for position that initializes the filename. The glr.cc skeleton does not (and in fact cannot: location/position are stored in a union, from which objects with constructors are excluded in C++. */ %initial-action { @$.initialize (0); } /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; /* A C++ error reporting function. */ void yy::parser::error (const location& l, const std::string& m) { (void) l; std::cerr << l << ": " << m << std::endl; } int yyparse () { yy::parser parser; parser.set_debug_level (!!YYDEBUG); return parser.parse (); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:621: bison -o calc.cc calc.y" echo calc.at:621 >$at_check_line_file ( $at_traceon; bison -o calc.cc calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:621: \$BISON_CXX_WORKS" echo calc.at:621 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:621: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.cc \$LIBS" echo calc.at:621 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o calc calc.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:621: \$PREPARSER ./calc input" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:621: \$PREPARSER ./calc input" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:621: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:621: cat stderr" echo calc.at:621 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:621: \$PREPARSER ./calc input" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:621: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:621: cat stderr" echo calc.at:621 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:621: \$PREPARSER ./calc input" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:621: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:621: cat stderr" echo calc.at:621 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:621: \$PREPARSER ./calc input" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:621: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:621: cat stderr" echo calc.at:621 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:621: \$PREPARSER ./calc input" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:621: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:621: cat stderr" echo calc.at:621 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:621: \$PREPARSER ./calc /dev/null" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:621: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:621: cat stderr" echo calc.at:621 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:621: \$PREPARSER ./calc input" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:621: cat stderr" echo calc.at:621 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:621: \$PREPARSER ./calc input" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:621: cat stderr" echo calc.at:621 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:621: \$PREPARSER ./calc input" echo calc.at:621 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout # 5. Check $at_traceoff echo "calc.at:621: cat stderr" echo calc.at:621 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:621: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 99 ) # 99. calc.at:622: Calculator %skeleton "lalr1.cc" %defines %locations %error-verbose %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:622' at_desc='Calculator %skeleton "lalr1.cc" %defines %locations %error-verbose %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N " 99: Calculator %skeleton "lalr1.cc" %defines %locations %error-verbose %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "99. calc.at:622: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %skeleton "lalr1.cc" %defines %locations %error-verbose %name-prefix="calc" %verbose %yacc %define "global_tokens_and_yystype" %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); #ifndef YYLTYPE # define YYLTYPE calc::location #endif #define first_line begin.line #define first_column begin.column #define last_line end.line #define last_column end.column static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* The lalr1.cc skeleton, for backward compatibility, defines a constructor for position that initializes the filename. The glr.cc skeleton does not (and in fact cannot: location/position are stored in a union, from which objects with constructors are excluded in C++. */ %initial-action { @$.initialize (0); } /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; /* A C++ error reporting function. */ void calc::parser::error (const location& l, const std::string& m) { (void) l; std::cerr << l << ": " << m << std::endl; } int yyparse () { calc::parser parser; parser.set_debug_level (!!YYDEBUG); return parser.parse (); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:622: bison -o calc.cc calc.y" echo calc.at:622 >$at_check_line_file ( $at_traceon; bison -o calc.cc calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:622: \$BISON_CXX_WORKS" echo calc.at:622 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:622: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.cc \$LIBS" echo calc.at:622 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o calc calc.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:622: \$PREPARSER ./calc input" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:622: \$PREPARSER ./calc input" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:622: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:622: cat stderr" echo calc.at:622 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:622: \$PREPARSER ./calc input" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:622: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:622: cat stderr" echo calc.at:622 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:622: \$PREPARSER ./calc input" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:622: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:622: cat stderr" echo calc.at:622 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:622: \$PREPARSER ./calc input" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:622: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:622: cat stderr" echo calc.at:622 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:622: \$PREPARSER ./calc input" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:622: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:622: cat stderr" echo calc.at:622 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:622: \$PREPARSER ./calc /dev/null" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:622: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:622: cat stderr" echo calc.at:622 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:622: \$PREPARSER ./calc input" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:622: cat stderr" echo calc.at:622 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:622: \$PREPARSER ./calc input" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:622: cat stderr" echo calc.at:622 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:622: \$PREPARSER ./calc input" echo calc.at:622 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:622: cat stderr" echo calc.at:622 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:622: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 100 ) # 100. calc.at:624: Calculator %skeleton "lalr1.cc" %defines %locations %error-verbose %debug %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:624' at_desc='Calculator %skeleton "lalr1.cc" %defines %locations %error-verbose %debug %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N "100: Calculator %skeleton "lalr1.cc" %defines %locations %error-verbose %debug %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "100. calc.at:624: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %skeleton "lalr1.cc" %defines %locations %error-verbose %debug %name-prefix="calc" %verbose %yacc %define "global_tokens_and_yystype" %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); #ifndef YYLTYPE # define YYLTYPE calc::location #endif #define first_line begin.line #define first_column begin.column #define last_line end.line #define last_column end.column static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* The lalr1.cc skeleton, for backward compatibility, defines a constructor for position that initializes the filename. The glr.cc skeleton does not (and in fact cannot: location/position are stored in a union, from which objects with constructors are excluded in C++. */ %initial-action { @$.initialize (0); } /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; /* A C++ error reporting function. */ void calc::parser::error (const location& l, const std::string& m) { (void) l; std::cerr << l << ": " << m << std::endl; } int yyparse () { calc::parser parser; parser.set_debug_level (!!YYDEBUG); return parser.parse (); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:624: bison -o calc.cc calc.y" echo calc.at:624 >$at_check_line_file ( $at_traceon; bison -o calc.cc calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:624: \$BISON_CXX_WORKS" echo calc.at:624 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:624: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.cc \$LIBS" echo calc.at:624 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o calc calc.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:624: \$PREPARSER ./calc input" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:624: \$PREPARSER ./calc input" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:624: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:624: cat stderr" echo calc.at:624 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:624: \$PREPARSER ./calc input" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:624: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:624: cat stderr" echo calc.at:624 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:624: \$PREPARSER ./calc input" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:624: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:624: cat stderr" echo calc.at:624 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:624: \$PREPARSER ./calc input" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:624: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:624: cat stderr" echo calc.at:624 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:624: \$PREPARSER ./calc input" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:624: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:624: cat stderr" echo calc.at:624 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:624: \$PREPARSER ./calc /dev/null" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:624: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:624: cat stderr" echo calc.at:624 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:624: \$PREPARSER ./calc input" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:624: cat stderr" echo calc.at:624 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:624: \$PREPARSER ./calc input" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:624: cat stderr" echo calc.at:624 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:624: \$PREPARSER ./calc input" echo calc.at:624 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:624: cat stderr" echo calc.at:624 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:624: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 101 ) # 101. calc.at:626: Calculator %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:626' at_desc='Calculator %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N "101: Calculator %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "101. calc.at:626: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %define "global_tokens_and_yystype" %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); #ifndef YYLTYPE # define YYLTYPE calc::location #endif #define first_line begin.line #define first_column begin.column #define last_line end.line #define last_column end.column static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* The lalr1.cc skeleton, for backward compatibility, defines a constructor for position that initializes the filename. The glr.cc skeleton does not (and in fact cannot: location/position are stored in a union, from which objects with constructors are excluded in C++. */ %initial-action { @$.initialize (0); } /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; /* A C++ error reporting function. */ void calc::parser::error (const location& l, const std::string& m) { (void) l; std::cerr << l << ": " << m << std::endl; } int yyparse () { calc::parser parser; parser.set_debug_level (!!YYDEBUG); return parser.parse (); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:626: bison -o calc.cc calc.y" echo calc.at:626 >$at_check_line_file ( $at_traceon; bison -o calc.cc calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:626: \$BISON_CXX_WORKS" echo calc.at:626 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:626: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.cc \$LIBS" echo calc.at:626 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o calc calc.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:626: \$PREPARSER ./calc input" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:626: \$PREPARSER ./calc input" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:626: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:626: cat stderr" echo calc.at:626 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:626: \$PREPARSER ./calc input" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:626: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:626: cat stderr" echo calc.at:626 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:626: \$PREPARSER ./calc input" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:626: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:626: cat stderr" echo calc.at:626 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:626: \$PREPARSER ./calc input" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:626: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:626: cat stderr" echo calc.at:626 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:626: \$PREPARSER ./calc input" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:626: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:626: cat stderr" echo calc.at:626 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:626: \$PREPARSER ./calc /dev/null" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:626: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:626: cat stderr" echo calc.at:626 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:626: \$PREPARSER ./calc input" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:626: cat stderr" echo calc.at:626 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:626: \$PREPARSER ./calc input" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:626: cat stderr" echo calc.at:626 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:626: \$PREPARSER ./calc input" echo calc.at:626 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:626: cat stderr" echo calc.at:626 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:626: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 102 ) # 102. calc.at:628: Calculator %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count} at_setup_line='calc.at:628' at_desc='Calculator %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}' $at_quiet $ECHO_N "102: Calculator %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}$ECHO_C" at_xfail=no ( echo "102. calc.at:628: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %skeleton "lalr1.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count} %define "global_tokens_and_yystype" %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); #ifndef YYLTYPE # define YYLTYPE calc::location #endif #define first_line begin.line #define first_column begin.column #define last_line end.line #define last_column end.column static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* The lalr1.cc skeleton, for backward compatibility, defines a constructor for position that initializes the filename. The glr.cc skeleton does not (and in fact cannot: location/position are stored in a union, from which objects with constructors are excluded in C++. */ %initial-action { @$.initialize (0); } /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { ++*count; ++global_count; } ; line: '\n' | exp '\n' { *result = global_result = $1; } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; /* A C++ error reporting function. */ void calc::parser::error (const location& l, const std::string& m) { (void) l; std::cerr << l << ": " << m << std::endl; } int yyparse (semantic_value *result, int *count) { calc::parser parser (result, count); parser.set_debug_level (!!YYDEBUG); return parser.parse (); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (&result, &count); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:628: bison -o calc.cc calc.y" echo calc.at:628 >$at_check_line_file ( $at_traceon; bison -o calc.cc calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:628: \$BISON_CXX_WORKS" echo calc.at:628 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:628: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.cc \$LIBS" echo calc.at:628 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o calc calc.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:628: \$PREPARSER ./calc input" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:628: \$PREPARSER ./calc input" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:628: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:628: cat stderr" echo calc.at:628 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:628: \$PREPARSER ./calc input" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:628: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:628: cat stderr" echo calc.at:628 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:628: \$PREPARSER ./calc input" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:628: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:628: cat stderr" echo calc.at:628 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:628: \$PREPARSER ./calc input" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:628: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:628: cat stderr" echo calc.at:628 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:628: \$PREPARSER ./calc input" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:628: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:628: cat stderr" echo calc.at:628 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:628: \$PREPARSER ./calc /dev/null" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:628: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:628: cat stderr" echo calc.at:628 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:628: \$PREPARSER ./calc input" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:628: cat stderr" echo calc.at:628 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:628: \$PREPARSER ./calc input" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:628: cat stderr" echo calc.at:628 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:628: \$PREPARSER ./calc input" echo calc.at:628 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:628: cat stderr" echo calc.at:628 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-12 ) # Banner 12. calc.at:636 cat <<\_ATEOF Simple GLR C++ Calculator. _ATEOF ;; 103 ) # 103. calc.at:651: Calculator %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc at_setup_line='calc.at:651' at_desc='Calculator %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc' $at_quiet $ECHO_N "103: Calculator %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc$ECHO_C" at_xfail=no ( echo "103. calc.at:651: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %define "global_tokens_and_yystype" %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); #ifndef YYLTYPE # define YYLTYPE calc::location #endif #define first_line begin.line #define first_column begin.column #define last_line end.line #define last_column end.column static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* The lalr1.cc skeleton, for backward compatibility, defines a constructor for position that initializes the filename. The glr.cc skeleton does not (and in fact cannot: location/position are stored in a union, from which objects with constructors are excluded in C++. */ %initial-action { @$.initialize (0); } /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { } ; line: '\n' | exp '\n' { USE ($1); } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; /* A C++ error reporting function. */ void calc::parser::error (const location& l, const std::string& m) { (void) l; std::cerr << l << ": " << m << std::endl; } int yyparse () { calc::parser parser; parser.set_debug_level (!!YYDEBUG); return parser.parse (); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:651: bison -o calc.cc calc.y" echo calc.at:651 >$at_check_line_file ( $at_traceon; bison -o calc.cc calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:651: \$BISON_CXX_WORKS" echo calc.at:651 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:651: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.cc \$LIBS" echo calc.at:651 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o calc calc.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:651: \$PREPARSER ./calc input" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:651: \$PREPARSER ./calc input" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:651: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:651: cat stderr" echo calc.at:651 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:651: \$PREPARSER ./calc input" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:651: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:651: cat stderr" echo calc.at:651 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:651: \$PREPARSER ./calc input" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:651: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:651: cat stderr" echo calc.at:651 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:651: \$PREPARSER ./calc input" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:651: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:651: cat stderr" echo calc.at:651 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:651: \$PREPARSER ./calc input" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:651: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:651: cat stderr" echo calc.at:651 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:651: \$PREPARSER ./calc /dev/null" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:651: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:651: cat stderr" echo calc.at:651 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:651: \$PREPARSER ./calc input" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:651: cat stderr" echo calc.at:651 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:651: \$PREPARSER ./calc input" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:651: cat stderr" echo calc.at:651 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:651: \$PREPARSER ./calc input" echo calc.at:651 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:651: cat stderr" echo calc.at:651 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:651: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 104 ) # 104. calc.at:653: Calculator %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count} at_setup_line='calc.at:653' at_desc='Calculator %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}' $at_quiet $ECHO_N "104: Calculator %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}$ECHO_C" at_xfail=no ( echo "104. calc.at:653: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >calc.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Infix notation calculator--calc */ %skeleton "glr.cc" %defines %locations %pure-parser %error-verbose %debug %name-prefix="calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count} %define "global_tokens_and_yystype" %{ #include #include #include #if HAVE_UNISTD_H # include #else # undef alarm # define alarm(seconds) /* empty */ #endif #include #define USE(Var) /* Exercise pre-prologue dependency to %union. */ typedef int semantic_value; static semantic_value global_result = 0; static int global_count = 0; %} /* Exercise %union. */ %union { semantic_value ival; }; %{ static int power (int base, int exponent); #ifndef YYLTYPE # define YYLTYPE calc::location #endif #define first_line begin.line #define first_column begin.column #define last_line end.line #define last_column end.column static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp); static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c); %} /* The lalr1.cc skeleton, for backward compatibility, defines a constructor for position that initializes the filename. The glr.cc skeleton does not (and in fact cannot: location/position are stored in a union, from which objects with constructors are excluded in C++. */ %initial-action { @$.initialize (0); } /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp %nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: line | input line { ++*count; ++global_count; } ; line: '\n' | exp '\n' { *result = global_result = $1; } ; exp: NUM { $$ = $1; } | exp '=' exp { if ($1 != $3) fprintf (stderr, "calc: error: %d != %d\n", $1, $3); $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = power ($1, $3); } | '(' exp ')' { $$ = $2; } | '(' error ')' { $$ = 1111; } | '!' { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; } ; %% /* The input. */ static FILE *input; /* A C++ error reporting function. */ void calc::parser::error (const location& l, const std::string& m) { (void) l; std::cerr << l << ": " << m << std::endl; } int yyparse (semantic_value *result, int *count) { calc::parser parser (result, count); parser.set_debug_level (!!YYDEBUG); return parser.parse (); } static YYLTYPE last_yylloc; static int get_char (YYSTYPE *lvalp, YYLTYPE *llocp) { int res = getc (input); (void) lvalp;(void) llocp; last_yylloc = (*llocp); if (res == '\n') { (*llocp).last_line++; (*llocp).last_column = 0; } else (*llocp).last_column++; return res; } static void unget_char (YYSTYPE *lvalp, YYLTYPE *llocp, int c) { (void) lvalp;(void) llocp; /* Wrong when C == `\n'. */ (*llocp) = last_yylloc; ungetc (c, input); } static int read_signed_integer (YYSTYPE *lvalp, YYLTYPE *llocp) { int c = get_char (lvalp, llocp); int sign = 1; int n = 0; (void) lvalp;(void) llocp; if (c == '-') { c = get_char (lvalp, llocp); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); c = get_char (lvalp, llocp); } unget_char (lvalp, llocp, c); return sign * n; } /*---------------------------------------------------------------. | Lexical analyzer returns an integer on the stack and the token | | NUM, or the ASCII character read if not a number. Skips all | | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static int init = 1; int c; if (init) { init = 0; (*llocp).last_column = 0; (*llocp).last_line = 1; } (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; /* Skip white space. */ while ((c = get_char (lvalp, llocp)) == ' ' || c == '\t') { (*llocp).first_column = (*llocp).last_column; (*llocp).first_line = (*llocp).last_line; } /* process numbers */ if (c == '.' || isdigit (c)) { unget_char (lvalp, llocp, c); (*lvalp).ival = read_signed_integer (lvalp, llocp); return NUM; } /* Return end-of-file. */ if (c == EOF) return CALC_EOF; /* Return single chars. */ return c; } static int power (int base, int exponent) { int res = 1; if (exponent < 0) exit (3); for (/* Niente */; exponent; --exponent) res *= base; return res; } int main (int argc, const char **argv) { semantic_value result = 0; int count = 0; int status; /* This used to be alarm (10), but that isn't enough time for a July 1995 vintage DEC Alphastation 200 4/100 system, according to Nelson H. F. Beebe. 100 seconds is enough. */ alarm (100); if (argc == 2) input = fopen (argv[1], "r"); else input = stdin; if (!input) { perror (argv[1]); return 3; } status = yyparse (&result, &count); if (global_result != result) abort (); if (global_count != count) abort (); return status; } _ATEOF $at_traceoff echo "calc.at:653: bison -o calc.cc calc.y" echo calc.at:653 >$at_check_line_file ( $at_traceon; bison -o calc.cc calc.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:653: \$BISON_CXX_WORKS" echo calc.at:653 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "calc.at:653: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o calc calc.cc \$LIBS" echo calc.at:653 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o calc calc.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Test the priorities. cat >input <<'_ATEOF' 1 + 2 * 3 = 7 1 + 2 * -3 = -5 -1^2 = -1 (-1)^2 = 1 ---1 = -1 1 - 2 - 3 = -4 1 - (2 - 3) = 2 2^2^3 = 256 (2^2)^3 = 64 _ATEOF $at_traceoff echo "calc.at:653: \$PREPARSER ./calc input" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Some syntax errors. cat >input <<'_ATEOF' 0 0 _ATEOF $at_traceoff echo "calc.at:653: \$PREPARSER ./calc input" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:653: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected number _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:653: cat stderr" echo calc.at:653 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1//2 _ATEOF $at_traceoff echo "calc.at:653: \$PREPARSER ./calc input" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:653: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.2: syntax error, unexpected '/', expecting number or '-' or '(' or '!' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:653: cat stderr" echo calc.at:653 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' error _ATEOF $at_traceoff echo "calc.at:653: \$PREPARSER ./calc input" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:653: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected $undefined _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:653: cat stderr" echo calc.at:653 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' 1 = 2 = 3 _ATEOF $at_traceoff echo "calc.at:653: \$PREPARSER ./calc input" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:653: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.6: syntax error, unexpected '=' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:653: cat stderr" echo calc.at:653 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' +1 _ATEOF $at_traceoff echo "calc.at:653: \$PREPARSER ./calc input" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:653: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 2.0: syntax error, unexpected '+' _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:653: cat stderr" echo calc.at:653 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise error messages with EOF: work on an empty file. $at_traceoff echo "calc.at:653: \$PREPARSER ./calc /dev/null" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc /dev/null ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "calc.at:653: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.0: syntax error, unexpected end of input _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:653: cat stderr" echo calc.at:653 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Exercise the error token: without it, we die at the first error, # hence be sure to # # - have several errors which exercise different shift/discardings # - (): nothing to pop, nothing to discard # - (1 + 1 + 1 +): a lot to pop, nothing to discard # - (* * *): nothing to pop, a lot to discard # - (1 + 2 * *): some to pop and discard # # - test the action associated to `error' # # - check the look-ahead that triggers an error is not discarded # when we enter error recovery. Below, the look-ahead causing the # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # cat >input <<'_ATEOF' () + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1 _ATEOF $at_traceoff echo "calc.at:653: \$PREPARSER ./calc input" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.17: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1.22: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.40: syntax error, unexpected '*', expecting number or '-' or '(' or '!' calc: error: 4444 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:653: cat stderr" echo calc.at:653 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # The same, but this time exercising explicitly triggered syntax errors. # POSIX says the look-ahead causing the error should not be discarded. cat >input <<'_ATEOF' (!) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:653: \$PREPARSER ./calc input" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.9: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:653: cat stderr" echo calc.at:653 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >input <<'_ATEOF' (- *) + (0 0) = 1 _ATEOF $at_traceoff echo "calc.at:653: \$PREPARSER ./calc input" echo calc.at:653 >$at_check_line_file ( $at_traceon; $PREPARSER ./calc input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; tee stderr <$at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Normalize the observed and expected error messages, depending upon the # options. # 1. Remove the traces from observed. sed '/^Starting/d /^Entering/d /^Stack/d /^Reading/d /^Reducing/d /^Shifting/d /^state/d /^Cleanup:/d /^Error:/d /^Next/d /^Discarding/d / \$[0-9$]* = /d /^yydestructor:/d' stderr >at-stderr mv at-stderr stderr # 2. Create the reference error message. cat >expout <<'_ATEOF' 1.3: syntax error, unexpected '*', expecting number or '-' or '(' or '!' 1.11: syntax error, unexpected number calc: error: 2222 != 1 _ATEOF # 3. If locations are not used, remove them. # 4. If error-verbose is not used, strip the`, unexpected....' part. # 5. Check $at_traceoff echo "calc.at:653: cat stderr" echo calc.at:653 >$at_check_line_file ( $at_traceon; cat stderr ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff expout $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "calc.at:653: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-13 ) # Banner 13. torture.at:19 cat <<\_ATEOF Torture Tests. _ATEOF ;; 105 ) # 105. torture.at:140: Big triangle at_setup_line='torture.at:140' at_desc='Big triangle' $at_quiet $ECHO_N "105: Big triangle $ECHO_C" at_xfail=no ( echo "105. torture.at:140: testing ..." $at_traceon # I have been able to go up to 2000 on my machine. # I tried 3000, a 29Mb grammar file, but then my system killed bison. # With 500 and the new parser, which consume far too much memory, # it gets killed too. Of course the parser is to be cleaned. cat >gengram.pl <<'_ATEOF' #! /usr/bin/perl -w use strict; my $max = $ARGV[0] || 10; print < /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %error-verbose %debug %{ #include #include static int yylex (void); static void yyerror (const char *msg); %} %union { int val; }; %token END "end" %type exp input EOF for my $size (1 .. $max) { print "%token t$size $size \"$size\"\n"; }; print < $max) return 0; else if (inner > outer) { inner = 1; ++outer; return END; } return inner++; } static void yyerror (const char *msg) { fprintf (stderr, "%s\\n", msg); } int main (void) { yydebug = !!getenv ("YYDEBUG"); return yyparse (); } EOF _ATEOF $at_traceoff echo "torture.at:146: perl -w ./gengram.pl 200 || exit 77" echo torture.at:146 >$at_check_line_file ( $at_traceon; perl -w ./gengram.pl 200 || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:146: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon mv stdout input.y $at_traceoff echo "torture.at:147: bison -v -o input.c input.y" echo torture.at:147 >$at_check_line_file ( $at_traceon; bison -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:147: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "torture.at:148: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo torture.at:148 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:148: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "torture.at:149: \$PREPARSER ./input" echo torture.at:149 >$at_check_line_file ( $at_traceon; $PREPARSER ./input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:149: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 106 ) # 106. torture.at:232: Big horizontal at_setup_line='torture.at:232' at_desc='Big horizontal' $at_quiet $ECHO_N "106: Big horizontal $ECHO_C" at_xfail=no ( echo "106. torture.at:232: testing ..." $at_traceon # I have been able to go up to 10000 on my machine, but I had to # increase the maximum stack size (* 100). It gave: # # input.y 263k # input.tab.c 1.3M # input 453k # # gengram.pl 10000 0.70s user 0.01s sys 99% cpu 0.711 total # bison input.y 730.56s user 0.53s sys 99% cpu 12:12.34 total # gcc -Wall input.tab.c -o input 5.81s user 0.20s sys 100% cpu 6.01 total # ./input 0.00s user 0.01s sys 108% cpu 0.01 total # cat >gengram.pl <<'_ATEOF' #! /usr/bin/perl -w use strict; my $max = $ARGV[0] || 10; print < /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %error-verbose %debug %{ #include #include static int yylex (void); static void yyerror (const char *msg); %} %token EOF for my $size (1 .. $max) { print " t$size $size \"$size\"\n"; }; print < $max) return 0; else return counter++; } static void yyerror (const char *msg) { fprintf (stderr, "%s\\n", msg); } int main (void) { yydebug = !!getenv ("YYDEBUG"); return yyparse (); } EOF _ATEOF $at_traceoff echo "torture.at:246: perl -w ./gengram.pl 1000 || exit 77" echo torture.at:246 >$at_check_line_file ( $at_traceon; perl -w ./gengram.pl 1000 || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:246: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon mv stdout input.y # GNU m4 requires about 70 MiB for this test on a 32-bit host. # Ask for 200 MiB, which should be plenty even on a 64-bit host. data_limit=`(ulimit -S -d) 2>/dev/null` case $data_limit in [0-9]*) if test "$data_limit" -lt 204000; then $at_traceoff echo "torture.at:250: ulimit -S -d 204000 || exit 77" echo torture.at:250 >$at_check_line_file ( $at_traceon; ulimit -S -d 204000 || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:250: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon ulimit -S -d 204000 fi esac $at_traceoff echo "torture.at:252: bison -v -o input.c input.y" echo torture.at:252 >$at_check_line_file ( $at_traceon; bison -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:252: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "torture.at:253: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo torture.at:253 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:253: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "torture.at:254: \$PREPARSER ./input" echo torture.at:254 >$at_check_line_file ( $at_traceon; $PREPARSER ./input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:254: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 107 ) # 107. torture.at:368: Many look-ahead tokens at_setup_line='torture.at:368' at_desc='Many look-ahead tokens' $at_quiet $ECHO_N "107: Many look-ahead tokens $ECHO_C" at_xfail=no ( echo "107. torture.at:368: testing ..." $at_traceon cat >gengram.pl <<'_ATEOF' #! /usr/bin/perl -w use strict; use Text::Wrap; my $max = $ARGV[0] || 10; print < # include # include static int yylex (void); static void yyerror (const char *msg); %} %union { int val; }; %type input exp %token token EOF print wrap ("%type ", " ", map { "n$_" } (1 .. $max)), "\n"; print "%token\n"; for my $count (1 .. $max) { print " t$count $count \"$count\"\n"; }; print < $max) return 0; if (return_token) { return_token = 0; return token; } return_token = 1; return counter++; } static void yyerror (const char *msg) { fprintf (stderr, "%s\\n", msg); } int main (void) { yydebug = !!getenv ("YYDEBUG"); return yyparse (); } EOF _ATEOF $at_traceoff echo "torture.at:370: perl -w ./gengram.pl 1000 || exit 77" echo torture.at:370 >$at_check_line_file ( $at_traceon; perl -w ./gengram.pl 1000 || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; tee stdout <$at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:370: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon mv stdout input.y # GNU m4 requires about 70 MiB for this test on a 32-bit host. # Ask for 200 MiB, which should be plenty even on a 64-bit host. data_limit=`(ulimit -S -d) 2>/dev/null` case $data_limit in [0-9]*) if test "$data_limit" -lt 204000; then $at_traceoff echo "torture.at:374: ulimit -S -d 204000 || exit 77" echo torture.at:374 >$at_check_line_file ( $at_traceon; ulimit -S -d 204000 || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:374: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon ulimit -S -d 204000 fi esac $at_traceoff echo "torture.at:376: bison -v -o input.c input.y" echo torture.at:376 >$at_check_line_file ( $at_traceon; bison -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:376: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "torture.at:377: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo torture.at:377 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:377: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "torture.at:378: \$PREPARSER ./input" echo torture.at:378 >$at_check_line_file ( $at_traceon; $PREPARSER ./input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:378: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 108 ) # 108. torture.at:445: Exploding the Stack Size with Alloca at_setup_line='torture.at:445' at_desc='Exploding the Stack Size with Alloca' $at_quiet $ECHO_N "108: Exploding the Stack Size with Alloca $ECHO_C" at_xfail=no ( echo "108. torture.at:445: testing ..." $at_traceon # A grammar of parens growing the stack thanks to right recursion. # exp: cat >input.y <<'_ATEOF' %{ #include #include #include #include #if (defined __GNUC__ || defined __BUILTIN_VA_ARG_INCR \ || defined _AIX || defined _MSC_VER || defined _ALLOCA_H) # define YYSTACK_USE_ALLOCA 1 #endif static int yylex (void); static void yyerror (const char *msg); %} %error-verbose %debug %token WAIT_FOR_EOF %% exp: WAIT_FOR_EOF exp | ; %% static void yyerror (const char *msg) { fprintf (stderr, "%s\n", msg); } static int yylex (void) { if (yylval--) return WAIT_FOR_EOF; else return EOF; } int main (int argc, const char **argv) { char *endp; if (argc != 2) abort (); yylval = strtol (argv[1], &endp, 10); if (! (argv[1] != endp && 0 <= yylval && yylval <= INT_MAX && errno != ERANGE)) abort (); yydebug = 1; return yyparse (); } _ATEOF $at_traceoff echo "torture.at:452: bison -o input.c input.y" echo torture.at:452 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:452: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "torture.at:452: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo torture.at:452 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:452: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Below the limit of 200. $at_traceoff echo "torture.at:455: \$PREPARSER ./input 20" echo torture.at:455 >$at_check_line_file ( $at_traceon; $PREPARSER ./input 20 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:455: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Two enlargements: 2 * 2 * 200. $at_traceoff echo "torture.at:457: \$PREPARSER ./input 900" echo torture.at:457 >$at_check_line_file ( $at_traceon; $PREPARSER ./input 900 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:457: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Fails: beyond the limit of 10,000 (which we don't reach anyway since we # multiply by two starting at 200 => 5120 is the last possible). $at_traceoff echo "torture.at:460: \$PREPARSER ./input 10000" echo torture.at:460 >$at_check_line_file ( $at_traceon; $PREPARSER ./input 10000 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 2) ;; *) echo "torture.at:460: exit code was $at_status, expected 2" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 109 ) # 109. torture.at:471: Exploding the Stack Size with Malloc at_setup_line='torture.at:471' at_desc='Exploding the Stack Size with Malloc' $at_quiet $ECHO_N "109: Exploding the Stack Size with Malloc $ECHO_C" at_xfail=no ( echo "109. torture.at:471: testing ..." $at_traceon # A grammar of parens growing the stack thanks to right recursion. # exp: cat >input.y <<'_ATEOF' %{ #include #include #include #include #define YYSTACK_USE_ALLOCA 0 static int yylex (void); static void yyerror (const char *msg); %} %error-verbose %debug %token WAIT_FOR_EOF %% exp: WAIT_FOR_EOF exp | ; %% static void yyerror (const char *msg) { fprintf (stderr, "%s\n", msg); } static int yylex (void) { if (yylval--) return WAIT_FOR_EOF; else return EOF; } int main (int argc, const char **argv) { char *endp; if (argc != 2) abort (); yylval = strtol (argv[1], &endp, 10); if (! (argv[1] != endp && 0 <= yylval && yylval <= INT_MAX && errno != ERANGE)) abort (); yydebug = 1; return yyparse (); } _ATEOF $at_traceoff echo "torture.at:473: bison -o input.c input.y" echo torture.at:473 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:473: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "torture.at:473: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo torture.at:473 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:473: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Below the limit of 200. $at_traceoff echo "torture.at:476: \$PREPARSER ./input 20" echo torture.at:476 >$at_check_line_file ( $at_traceon; $PREPARSER ./input 20 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:476: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Two enlargements: 2 * 2 * 200. $at_traceoff echo "torture.at:478: \$PREPARSER ./input 900" echo torture.at:478 >$at_check_line_file ( $at_traceon; $PREPARSER ./input 900 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "torture.at:478: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Fails: beyond the limit of 10,000 (which we don't reach anyway since we # multiply by two starting at 200 => 5120 is the possible). $at_traceoff echo "torture.at:481: \$PREPARSER ./input 10000" echo torture.at:481 >$at_check_line_file ( $at_traceon; $PREPARSER ./input 10000 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 2) ;; *) echo "torture.at:481: exit code was $at_status, expected 2" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-14 ) # Banner 14. existing.at:21 cat <<\_ATEOF Existing Grammars. _ATEOF ;; 110 ) # 110. existing.at:26: GNU AWK Grammar at_setup_line='existing.at:26' at_desc='GNU AWK Grammar' $at_quiet $ECHO_N "110: GNU AWK Grammar $ECHO_C" at_xfail=no ( echo "110. existing.at:26: testing ..." $at_traceon # We have been careful to strip all the actions excepts the # mid-rule actions. We rely on %expect to check that there are # indeed 65 SR conflicts. # # Bison was once wrong, due to an incorrect computation of nullable. # It reported 485 SR conflicts! cat >input.y <<'_ATEOF' %expect 65 %token FUNC_CALL NAME REGEXP %token ERROR %token YNUMBER YSTRING %token RELOP APPEND_OP %token ASSIGNOP MATCHOP NEWLINE CONCAT_OP %token LEX_BEGIN LEX_END LEX_IF LEX_ELSE LEX_RETURN LEX_DELETE %token LEX_WHILE LEX_DO LEX_FOR LEX_BREAK LEX_CONTINUE %token LEX_PRINT LEX_PRINTF LEX_NEXT LEX_EXIT LEX_FUNCTION %token LEX_GETLINE LEX_NEXTFILE %token LEX_IN %token LEX_AND LEX_OR INCREMENT DECREMENT %token LEX_BUILTIN LEX_LENGTH /* Lowest to highest */ %right ASSIGNOP %right '?' ':' %left LEX_OR %left LEX_AND %left LEX_GETLINE %nonassoc LEX_IN %left FUNC_CALL LEX_BUILTIN LEX_LENGTH %nonassoc ',' %nonassoc MATCHOP %nonassoc RELOP '<' '>' '|' APPEND_OP TWOWAYIO %left CONCAT_OP %left YSTRING YNUMBER %left '+' '-' %left '*' '/' '%' %right '!' UNARY %right '^' %left INCREMENT DECREMENT %left '$' %left '(' ')' %% start : opt_nls program opt_nls ; program : rule | program rule | error | program error | /* empty */ ; rule : LEX_BEGIN {} action | LEX_END {} action | LEX_BEGIN statement_term | LEX_END statement_term | pattern action | action | pattern statement_term | function_prologue function_body ; func_name : NAME | FUNC_CALL | lex_builtin ; lex_builtin : LEX_BUILTIN | LEX_LENGTH ; function_prologue : LEX_FUNCTION {} func_name '(' opt_param_list r_paren opt_nls ; function_body : l_brace statements r_brace opt_semi opt_nls | l_brace r_brace opt_semi opt_nls ; pattern : exp | exp ',' exp ; regexp /* * In this rule, want_regexp tells yylex that the next thing * is a regexp so it should read up to the closing slash. */ : '/' {} REGEXP '/' ; action : l_brace statements r_brace opt_semi opt_nls | l_brace r_brace opt_semi opt_nls ; statements : statement | statements statement | error | statements error ; statement_term : nls | semi opt_nls ; statement : semi opt_nls | l_brace r_brace | l_brace statements r_brace | if_statement | LEX_WHILE '(' exp r_paren opt_nls statement | LEX_DO opt_nls statement LEX_WHILE '(' exp r_paren opt_nls | LEX_FOR '(' NAME LEX_IN NAME r_paren opt_nls statement | LEX_FOR '(' opt_exp semi opt_nls exp semi opt_nls opt_exp r_paren opt_nls statement | LEX_FOR '(' opt_exp semi opt_nls semi opt_nls opt_exp r_paren opt_nls statement | LEX_BREAK statement_term | LEX_CONTINUE statement_term | print '(' expression_list r_paren output_redir statement_term | print opt_rexpression_list output_redir statement_term | LEX_NEXT statement_term | LEX_NEXTFILE statement_term | LEX_EXIT opt_exp statement_term | LEX_RETURN {} opt_exp statement_term | LEX_DELETE NAME '[' expression_list ']' statement_term | LEX_DELETE NAME statement_term | exp statement_term ; print : LEX_PRINT | LEX_PRINTF ; if_statement : LEX_IF '(' exp r_paren opt_nls statement | LEX_IF '(' exp r_paren opt_nls statement LEX_ELSE opt_nls statement ; nls : NEWLINE | nls NEWLINE ; opt_nls : /* empty */ | nls ; input_redir : /* empty */ | '<' simp_exp ; output_redir : /* empty */ | '>' exp | APPEND_OP exp | '|' exp | TWOWAYIO exp ; opt_param_list : /* empty */ | param_list ; param_list : NAME | param_list comma NAME | error | param_list error | param_list comma error ; /* optional expression, as in for loop */ opt_exp : /* empty */ | exp ; opt_rexpression_list : /* empty */ | rexpression_list ; rexpression_list : rexp | rexpression_list comma rexp | error | rexpression_list error | rexpression_list error rexp | rexpression_list comma error ; opt_expression_list : /* empty */ | expression_list ; expression_list : exp | expression_list comma exp | error | expression_list error | expression_list error exp | expression_list comma error ; /* Expressions, not including the comma operator. */ exp : variable ASSIGNOP {} exp | '(' expression_list r_paren LEX_IN NAME | exp '|' LEX_GETLINE opt_variable | exp TWOWAYIO LEX_GETLINE opt_variable | LEX_GETLINE opt_variable input_redir | exp LEX_AND exp | exp LEX_OR exp | exp MATCHOP exp | regexp | '!' regexp %prec UNARY | exp LEX_IN NAME | exp RELOP exp | exp '<' exp | exp '>' exp | exp '?' exp ':' exp | simp_exp | exp simp_exp %prec CONCAT_OP ; rexp : variable ASSIGNOP {} rexp | rexp LEX_AND rexp | rexp LEX_OR rexp | LEX_GETLINE opt_variable input_redir | regexp | '!' regexp %prec UNARY | rexp MATCHOP rexp | rexp LEX_IN NAME | rexp RELOP rexp | rexp '?' rexp ':' rexp | simp_exp | rexp simp_exp %prec CONCAT_OP ; simp_exp : non_post_simp_exp /* Binary operators in order of decreasing precedence. */ | simp_exp '^' simp_exp | simp_exp '*' simp_exp | simp_exp '/' simp_exp | simp_exp '%' simp_exp | simp_exp '+' simp_exp | simp_exp '-' simp_exp | variable INCREMENT | variable DECREMENT ; non_post_simp_exp : '!' simp_exp %prec UNARY | '(' exp r_paren | LEX_BUILTIN '(' opt_expression_list r_paren | LEX_LENGTH '(' opt_expression_list r_paren | LEX_LENGTH | FUNC_CALL '(' opt_expression_list r_paren | variable | INCREMENT variable | DECREMENT variable | YNUMBER | YSTRING | '-' simp_exp %prec UNARY | '+' simp_exp %prec UNARY ; opt_variable : /* empty */ | variable ; variable : NAME | NAME '[' expression_list ']' | '$' non_post_simp_exp ; l_brace : '{' opt_nls ; r_brace : '}' opt_nls ; r_paren : ')' ; opt_semi : /* empty */ | semi ; semi : ';' ; comma : ',' opt_nls ; %% _ATEOF # Pass plenty of options, to exercise plenty of code, even if we # don't actually check the output. But SEGV is watching us, and # so might do dmalloc. $at_traceoff echo "existing.at:356: bison --verbose --defines input.y" echo existing.at:356 >$at_check_line_file ( $at_traceon; bison --verbose --defines input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "existing.at:356: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 111 ) # 111. existing.at:364: GNU Cim Grammar at_setup_line='existing.at:364' at_desc='GNU Cim Grammar' $at_quiet $ECHO_N "111: GNU Cim Grammar $ECHO_C" at_xfail=no ( echo "111. existing.at:364: testing ..." $at_traceon # GNU Cim, the GNU Simula 87 Compiler. # Bison was once wrong, due to an incorrect computation of the RR conflicts. # It reported 80 SR && 99 RR conflicts instead of 78/10!!! cat >input.y <<'_ATEOF' %union {} %token HACTIVATE HAFTER /*HAND*/ HARRAY HAT HBEFORE HBEGIN HBOOLEAN HCHARACTER HCLASS /*HCOMMENT*/ HCONC HDELAY HDO HELSE HEND HEQ /*HEQV*/ HEXTERNAL HFOR HGE HGO HGOTO HGT HHIDDEN HIF /*HIMP*/ HIN HINNER HINSPECT HINTEGER HIS HLABEL HLE HLONG HLT HNAME HNE HNEW HNONE /*HNOT*/ HNOTEXT /*HOR*/ HOTHERWISE HPRIOR HPROCEDURE HPROTECTED HQUA HREACTIVATE HREAL HREF HSHORT HSTEP HSWITCH HTEXT HTHEN HTHIS HTO HUNTIL HVALUE HVAR HVIRTUAL HWHEN HWHILE HASSIGNVALUE HASSIGNREF /*HDOT*/ HPAREXPSEPARATOR HLABELSEPARATOR HSTATEMENTSEPARATOR HBEGPAR HENDPAR HEQR HNER HADD HSUB HMUL HDIV HINTDIV HEXP HDOTDOTDOT %token HIDENTIFIER %token HBOOLEANKONST HINTEGERKONST HCHARACTERKONST %token HREALKONST %token HTEXTKONST %right HASSIGN %left HORELSE %left HANDTHEN %left HEQV %left HIMP %left HOR %left HAND %left HNOT %left HVALRELOPERATOR HREFRELOPERATOR HOBJRELOPERATOR %left HCONC %left HTERMOPERATOR %left UNEAR %left HFACTOROPERATOR %left HPRIMARYOPERATOR %left HQUA %left HDOT %start MAIN_MODULE %% /* GRAMATIKK FOR PROGRAM MODULES */ MAIN_MODULE : {} MODULS | error HSTATEMENTSEPARATOR MBEE_DECLSTMS ; EXT_DECLARATION : HEXTERNAL MBEE_TYPE HPROCEDURE {} EXT_LIST | HEXTERNAL HIDENTIFIER HPROCEDURE {} HIDENTIFIER {} EXTERNAL_KIND_ITEM | HEXTERNAL HCLASS {} EXT_LIST ; EXTERNAL_KIND_ITEM: EXT_IDENT HOBJRELOPERATOR {} MBEE_TYPE HPROCEDURE HIDENTIFIER {} HEADING EMPTY_BLOCK {} /* | EXT_IDENT {} MBEE_REST_EXT_LIST ; MBEE_REST_EXT_LIST: /* EMPTY | HPAREXPSEPARATOR EXT_KIND_LIST ; EXT_KIND_LIST : EXT_KIND_ITEM | EXT_KIND_LIST HPAREXPSEPARATOR EXT_KIND_ITEM ; EXT_KIND_ITEM : HIDENTIFIER EXT_IDENT {}*/ ; EMPTY_BLOCK : /*EMPT*/ | HBEGIN HEND ; EXT_LIST : EXT_ITEM | EXT_LIST HPAREXPSEPARATOR EXT_ITEM ; EXT_ITEM : HIDENTIFIER EXT_IDENT ; EXT_IDENT : /* EMPTY */ | HVALRELOPERATOR {} HTEXTKONST ; /* GRAMATIKK FOR TYPER */ NO_TYPE : /*EMPT*/ ; MBEE_TYPE : NO_TYPE | TYPE ; TYPE : HREF HBEGPAR HIDENTIFIER {} HENDPAR | HTEXT | HBOOLEAN | HCHARACTER | HSHORT HINTEGER | HINTEGER | HREAL | HLONG HREAL ; /* GRAMATIKK FOR DEL AV SETNINGER */ MBEE_ELSE_PART : /*EMPT*/ /* | HELSE HIF EXPRESSION HTHEN {} BLOCK {} MBEE_ELSE_PART {}*/ | HELSE {} BLOCK ; FOR_LIST : FOR_LIST_ELEMENT | FOR_LIST_ELEMENT HPAREXPSEPARATOR FOR_LIST ; FOR_LIST_ELEMENT: EXPRESSION MBEE_F_L_EL_R_PT ; MBEE_F_L_EL_R_PT: /*EMPT*/ | HWHILE EXPRESSION | HSTEP EXPRESSION HUNTIL EXPRESSION ; GOTO : HGO HTO | HGOTO ; CONN_STATE_R_PT : WHEN_CLAUSE_LIST | HDO {} BLOCK ; WHEN_CLAUSE_LIST: HWHEN HIDENTIFIER HDO {} BLOCK | WHEN_CLAUSE_LIST HWHEN HIDENTIFIER HDO {} BLOCK ; MBEE_OTWI_CLAUS : /*EMPT*/ | HOTHERWISE {} BLOCK ; ACTIVATOR : HACTIVATE | HREACTIVATE ; SCHEDULE : /*EMPT*/ | ATDELAY EXPRESSION {} PRIOR | BEFOREAFTER {} EXPRESSION ; ATDELAY : HAT | HDELAY ; BEFOREAFTER : HBEFORE | HAFTER ; PRIOR : /*EMPT*/ | HPRIOR ; /* GRAMATIKK FOR SETNINGER OG DEKLARASJONER */ MODULSTATEMENT : HWHILE EXPRESSION HDO {} BLOCK | HIF EXPRESSION HTHEN {} BLOCK {} MBEE_ELSE_PART | HFOR HIDENTIFIER HASSIGN {} FOR_LIST HDO {} BLOCK | GOTO EXPRESSION | HINSPECT EXPRESSION {} CONN_STATE_R_PT {} MBEE_OTWI_CLAUS | HINNER | HIDENTIFIER HLABELSEPARATOR {} DECLSTATEMENT | EXPRESSION_SIMP HBEGIN {} IMPORT_SPEC_MODULE {} MBEE_DECLSTMS HEND | EXPRESSION_SIMP HBEGIN error HSTATEMENTSEPARATOR MBEE_DECLSTMS HEND | EXPRESSION_SIMP HBEGIN error HEND | EXPRESSION_SIMP | ACTIVATOR EXPRESSION SCHEDULE | HBEGIN {} MBEE_DECLSTMS HEND | MBEE_TYPE HPROCEDURE HIDENTIFIER {} HEADING BLOCK | HIDENTIFIER HCLASS NO_TYPE {} IMPORT_SPEC_MODULE HIDENTIFIER {} HEADING BLOCK | HCLASS NO_TYPE HIDENTIFIER {} HEADING BLOCK | EXT_DECLARATION | /*EMPT*/ ; IMPORT_SPEC_MODULE: ; DECLSTATEMENT : MODULSTATEMENT | TYPE HIDENTIFIER MBEE_CONSTANT HPAREXPSEPARATOR {} IDENTIFIER_LISTC | TYPE HIDENTIFIER MBEE_CONSTANT | MBEE_TYPE HARRAY {} ARR_SEGMENT_LIST | HSWITCH HIDENTIFIER HASSIGN {} SWITCH_LIST ; BLOCK : DECLSTATEMENT | HBEGIN MBEE_DECLSTMS HEND | HBEGIN error HSTATEMENTSEPARATOR MBEE_DECLSTMS HEND | HBEGIN error HEND ; MBEE_DECLSTMS : MBEE_DECLSTMSU ; MBEE_DECLSTMSU : DECLSTATEMENT | MBEE_DECLSTMSU HSTATEMENTSEPARATOR DECLSTATEMENT ; MODULS : MODULSTATEMENT | MODULS HSTATEMENTSEPARATOR MODULSTATEMENT ; /* GRAMATIKK FOR DEL AV DEKLARASJONER */ ARR_SEGMENT_LIST: ARR_SEGMENT | ARR_SEGMENT_LIST HPAREXPSEPARATOR ARR_SEGMENT ; ARR_SEGMENT : ARRAY_SEGMENT HBEGPAR BAUND_PAIR_LIST HENDPAR ; ARRAY_SEGMENT : ARRAY_SEGMENT_EL {} | ARRAY_SEGMENT_EL HPAREXPSEPARATOR ARRAY_SEGMENT ; ARRAY_SEGMENT_EL: HIDENTIFIER ; BAUND_PAIR_LIST : BAUND_PAIR | BAUND_PAIR HPAREXPSEPARATOR BAUND_PAIR_LIST ; BAUND_PAIR : EXPRESSION HLABELSEPARATOR EXPRESSION ; SWITCH_LIST : EXPRESSION | EXPRESSION HPAREXPSEPARATOR SWITCH_LIST ; HEADING : MBEE_FMAL_PAR_P HSTATEMENTSEPARATOR {} MBEE_MODE_PART {} MBEE_SPEC_PART {} MBEE_PROT_PART {} MBEE_VIRT_PART ; MBEE_FMAL_PAR_P : /*EMPT*/ | FMAL_PAR_PART ; FMAL_PAR_PART : HBEGPAR NO_TYPE MBEE_LISTV HENDPAR ; MBEE_LISTV : /*EMPT*/ | LISTV ; LISTV : HIDENTIFIER | FPP_CATEG HDOTDOTDOT | HIDENTIFIER {} HPAREXPSEPARATOR LISTV | FPP_SPEC | FPP_SPEC HPAREXPSEPARATOR LISTV ; FPP_HEADING : HBEGPAR NO_TYPE FPP_MBEE_LISTV HENDPAR ; FPP_MBEE_LISTV : /*EMPT*/ | FPP_LISTV ; FPP_LISTV : FPP_CATEG HDOTDOTDOT | FPP_SPEC | FPP_SPEC HPAREXPSEPARATOR LISTV ; FPP_SPEC : FPP_CATEG SPECIFIER HIDENTIFIER | FPP_CATEG FPP_PROC_DECL_IN_SPEC ; FPP_CATEG : HNAME HLABELSEPARATOR | HVALUE HLABELSEPARATOR | HVAR HLABELSEPARATOR | /*EMPT*/ ; FPP_PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE HIDENTIFIER {} FPP_HEADING {} { /* Yes, two "final" actions. */ } ; IDENTIFIER_LISTV: HIDENTIFIER | HDOTDOTDOT | HIDENTIFIER {} HPAREXPSEPARATOR IDENTIFIER_LISTV ; MBEE_MODE_PART : /*EMPT*/ | MODE_PART ; MODE_PART : NAME_PART | VALUE_PART | VAR_PART | NAME_PART VALUE_PART | VALUE_PART NAME_PART | NAME_PART VAR_PART | VAR_PART NAME_PART | VALUE_PART VAR_PART | VAR_PART VALUE_PART | VAR_PART NAME_PART VALUE_PART | NAME_PART VAR_PART VALUE_PART | NAME_PART VALUE_PART VAR_PART | VAR_PART VALUE_PART NAME_PART | VALUE_PART VAR_PART NAME_PART | VALUE_PART NAME_PART VAR_PART ; NAME_PART : HNAME {} IDENTIFIER_LISTV HSTATEMENTSEPARATOR ; VAR_PART : HVAR {} IDENTIFIER_LISTV HSTATEMENTSEPARATOR ; VALUE_PART : HVALUE {} IDENTIFIER_LISTV HSTATEMENTSEPARATOR ; MBEE_SPEC_PART : /*EMPT*/ | SPEC_PART ; SPEC_PART : ONE_SPEC | SPEC_PART ONE_SPEC ; ONE_SPEC : SPECIFIER IDENTIFIER_LIST HSTATEMENTSEPARATOR | NO_TYPE HPROCEDURE HIDENTIFIER HOBJRELOPERATOR {} PROC_DECL_IN_SPEC HSTATEMENTSEPARATOR | FPP_PROC_DECL_IN_SPEC HSTATEMENTSEPARATOR | MBEE_TYPE HPROCEDURE HIDENTIFIER HSTATEMENTSEPARATOR | MBEE_TYPE HPROCEDURE HIDENTIFIER HPAREXPSEPARATOR IDENTIFIER_LIST HSTATEMENTSEPARATOR ; SPECIFIER : TYPE | MBEE_TYPE HARRAY | HLABEL | HSWITCH ; PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE HIDENTIFIER {} HEADING {} MBEE_BEGIN_END ; MBEE_BEGIN_END : /* EMPTY */ | HBEGIN HEND ; MBEE_PROT_PART : /*EMPT*/ | PROTECTION_PART ; PROTECTION_PART : PROT_SPECIFIER IDENTIFIER_LIST HSTATEMENTSEPARATOR | PROTECTION_PART PROT_SPECIFIER IDENTIFIER_LIST HSTATEMENTSEPARATOR ; PROT_SPECIFIER : HHIDDEN | HPROTECTED | HHIDDEN HPROTECTED | HPROTECTED HHIDDEN ; MBEE_VIRT_PART : /*EMPT*/ | VIRTUAL_PART ; VIRTUAL_PART : HVIRTUAL HLABELSEPARATOR MBEE_SPEC_PART ; IDENTIFIER_LIST : HIDENTIFIER | IDENTIFIER_LIST HPAREXPSEPARATOR HIDENTIFIER ; IDENTIFIER_LISTC: HIDENTIFIER MBEE_CONSTANT | IDENTIFIER_LISTC HPAREXPSEPARATOR HIDENTIFIER MBEE_CONSTANT ; MBEE_CONSTANT : /* EMPTY */ | HVALRELOPERATOR {} EXPRESSION ; /* GRAMATIKK FOR UTTRYKK */ EXPRESSION : EXPRESSION_SIMP | HIF EXPRESSION HTHEN EXPRESSION HELSE EXPRESSION ; EXPRESSION_SIMP : EXPRESSION_SIMP HASSIGN EXPRESSION | EXPRESSION_SIMP HCONC EXPRESSION_SIMP | EXPRESSION_SIMP HOR HELSE EXPRESSION_SIMP %prec HORELSE | EXPRESSION_SIMP HAND HTHEN EXPRESSION_SIMP %prec HANDTHEN | EXPRESSION_SIMP HEQV EXPRESSION_SIMP | EXPRESSION_SIMP HIMP EXPRESSION_SIMP | EXPRESSION_SIMP HOR EXPRESSION_SIMP | EXPRESSION_SIMP HAND EXPRESSION_SIMP | HNOT EXPRESSION_SIMP | EXPRESSION_SIMP HVALRELOPERATOR EXPRESSION_SIMP | EXPRESSION_SIMP HREFRELOPERATOR EXPRESSION_SIMP | EXPRESSION_SIMP HOBJRELOPERATOR EXPRESSION_SIMP | HTERMOPERATOR EXPRESSION_SIMP %prec UNEAR | EXPRESSION_SIMP HTERMOPERATOR EXPRESSION_SIMP | EXPRESSION_SIMP HFACTOROPERATOR EXPRESSION_SIMP | EXPRESSION_SIMP HPRIMARYOPERATOR EXPRESSION_SIMP | HBEGPAR EXPRESSION HENDPAR | HTEXTKONST | HCHARACTERKONST | HREALKONST | HINTEGERKONST | HBOOLEANKONST | HNONE | HIDENTIFIER {} MBEE_ARG_R_PT | HTHIS HIDENTIFIER | HNEW HIDENTIFIER ARG_R_PT | EXPRESSION_SIMP HDOT EXPRESSION_SIMP | EXPRESSION_SIMP HQUA HIDENTIFIER ; ARG_R_PT : /*EMPTY*/ | HBEGPAR ARGUMENT_LIST HENDPAR ; MBEE_ARG_R_PT : /*EMPTY*/ | HBEGPAR ARGUMENT_LIST HENDPAR ; ARGUMENT_LIST : EXPRESSION | EXPRESSION HPAREXPSEPARATOR ARGUMENT_LIST ; %% _ATEOF # Pass plenty of options, to exercise plenty of code, even if we # don't actually check the output. But SEGV is watching us, and # so might do dmalloc. $at_traceoff echo "existing.at:960: bison --verbose --defines input.y" echo existing.at:960 >$at_check_line_file ( $at_traceon; bison --verbose --defines input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y: conflicts: 78 shift/reduce, 10 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "existing.at:960: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "existing.at:972: grep '^State.*conflicts:' input.output" echo existing.at:972 >$at_check_line_file ( $at_traceon; grep '^State.*conflicts:' input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "State 64 conflicts: 14 shift/reduce State 164 conflicts: 1 shift/reduce State 201 conflicts: 33 shift/reduce, 4 reduce/reduce State 206 conflicts: 1 shift/reduce State 240 conflicts: 1 shift/reduce State 335 conflicts: 9 shift/reduce, 2 reduce/reduce State 356 conflicts: 1 shift/reduce State 360 conflicts: 9 shift/reduce, 2 reduce/reduce State 427 conflicts: 9 shift/reduce, 2 reduce/reduce " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "existing.at:972: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 112 ) # 112. existing.at:980: GNU pic Grammar at_setup_line='existing.at:980' at_desc='GNU pic Grammar' $at_quiet $ECHO_N "112: GNU pic Grammar $ECHO_C" at_xfail=no ( echo "112. existing.at:980: testing ..." $at_traceon # GNU pic, part of groff. # Bison once reported shift/reduce conflicts that it shouldn't have. cat >input.y <<'_ATEOF' %union {} %token LABEL %token VARIABLE %token NUMBER %token TEXT %token COMMAND_LINE %token DELIMITED %token ORDINAL %token TH %token LEFT_ARROW_HEAD %token RIGHT_ARROW_HEAD %token DOUBLE_ARROW_HEAD %token LAST %token UP %token DOWN %token LEFT %token RIGHT %token BOX %token CIRCLE %token ELLIPSE %token ARC %token LINE %token ARROW %token MOVE %token SPLINE %token HEIGHT %token RADIUS %token WIDTH %token DIAMETER %token FROM %token TO %token AT %token WITH %token BY %token THEN %token SOLID %token DOTTED %token DASHED %token CHOP %token SAME %token INVISIBLE %token LJUST %token RJUST %token ABOVE %token BELOW %token OF %token THE %token WAY %token BETWEEN %token AND %token HERE %token DOT_N %token DOT_E %token DOT_W %token DOT_S %token DOT_NE %token DOT_SE %token DOT_NW %token DOT_SW %token DOT_C %token DOT_START %token DOT_END %token DOT_X %token DOT_Y %token DOT_HT %token DOT_WID %token DOT_RAD %token SIN %token COS %token ATAN2 %token LOG %token EXP %token SQRT %token K_MAX %token K_MIN %token INT %token RAND %token SRAND %token COPY %token THRU %token TOP %token BOTTOM %token UPPER %token LOWER %token SH %token PRINT %token CW %token CCW %token FOR %token DO %token IF %token ELSE %token ANDAND %token OROR %token NOTEQUAL %token EQUALEQUAL %token LESSEQUAL %token GREATEREQUAL %token LEFT_CORNER %token RIGHT_CORNER %token NORTH %token SOUTH %token EAST %token WEST %token CENTER %token END %token START %token RESET %token UNTIL %token PLOT %token THICKNESS %token FILL %token COLORED %token OUTLINED %token SHADED %token ALIGNED %token SPRINTF %token COMMAND %left '.' /* this ensures that plot 17 "%g" parses as (plot 17 "%g") */ %left PLOT %left TEXT SPRINTF /* give text adjustments higher precedence than TEXT, so that box "foo" above ljust == box ("foo" above ljust) */ %left LJUST RJUST ABOVE BELOW %left LEFT RIGHT /* Give attributes that take an optional expression a higher precedence than left and right, so that eg `line chop left' parses properly. */ %left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED %left LABEL %left VARIABLE NUMBER '(' SIN COS ATAN2 LOG EXP SQRT K_MAX K_MIN INT RAND SRAND LAST %left ORDINAL HERE '`' %left BOX CIRCLE ELLIPSE ARC LINE ARROW SPLINE '[' /* ] */ /* these need to be lower than '-' */ %left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS /* these must have higher precedence than CHOP so that `label %prec CHOP' works */ %left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C %left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER %left UPPER LOWER NORTH SOUTH EAST WEST CENTER START END %left ',' %left OROR %left ANDAND %left EQUALEQUAL NOTEQUAL %left '<' '>' LESSEQUAL GREATEREQUAL %left BETWEEN OF %left AND %left '+' '-' %left '*' '/' '%' %right '!' %right '^' %% top: optional_separator | element_list ; element_list: optional_separator middle_element_list optional_separator ; middle_element_list: element | middle_element_list separator element ; optional_separator: /* empty */ | separator ; separator: ';' | separator ';' ; placeless_element: VARIABLE '=' any_expr | VARIABLE ':' '=' any_expr | UP | DOWN | LEFT | RIGHT | COMMAND_LINE | COMMAND print_args | PRINT print_args | SH {} DELIMITED | COPY TEXT | COPY TEXT THRU {} DELIMITED {} until | COPY THRU {} DELIMITED {} until | FOR VARIABLE '=' expr TO expr optional_by DO {} DELIMITED | simple_if | simple_if ELSE {} DELIMITED | reset_variables | RESET ; reset_variables: RESET VARIABLE | reset_variables VARIABLE | reset_variables ',' VARIABLE ; print_args: print_arg | print_args print_arg ; print_arg: expr %prec ',' | text | position %prec ',' ; simple_if: IF any_expr THEN {} DELIMITED ; until: /* empty */ | UNTIL TEXT ; any_expr: expr | text_expr ; text_expr: text EQUALEQUAL text | text NOTEQUAL text | text_expr ANDAND text_expr | text_expr ANDAND expr | expr ANDAND text_expr | text_expr OROR text_expr | text_expr OROR expr | expr OROR text_expr | '!' text_expr ; optional_by: /* empty */ | BY expr | BY '*' expr ; element: object_spec | LABEL ':' optional_separator element | LABEL ':' optional_separator position_not_place | LABEL ':' optional_separator place | '{}' {} optional_element | placeless_element ; optional_element: /* empty */ | element ; object_spec: BOX | CIRCLE | ELLIPSE | ARC | LINE | ARROW | MOVE | SPLINE | text %prec TEXT | PLOT expr | PLOT expr text | '[' {} element_list ']' | object_spec HEIGHT expr | object_spec RADIUS expr | object_spec WIDTH expr | object_spec DIAMETER expr | object_spec expr %prec HEIGHT | object_spec UP | object_spec UP expr | object_spec DOWN | object_spec DOWN expr | object_spec RIGHT | object_spec RIGHT expr | object_spec LEFT | object_spec LEFT expr | object_spec FROM position | object_spec TO position | object_spec AT position | object_spec WITH path | object_spec WITH position %prec ',' | object_spec BY expr_pair | object_spec THEN | object_spec SOLID | object_spec DOTTED | object_spec DOTTED expr | object_spec DASHED | object_spec DASHED expr | object_spec FILL | object_spec FILL expr | object_spec SHADED text | object_spec COLORED text | object_spec OUTLINED text | object_spec CHOP | object_spec CHOP expr | object_spec SAME | object_spec INVISIBLE | object_spec LEFT_ARROW_HEAD | object_spec RIGHT_ARROW_HEAD | object_spec DOUBLE_ARROW_HEAD | object_spec CW | object_spec CCW | object_spec text %prec TEXT | object_spec LJUST | object_spec RJUST | object_spec ABOVE | object_spec BELOW | object_spec THICKNESS expr | object_spec ALIGNED ; text: TEXT | SPRINTF '(' TEXT sprintf_args ')' ; sprintf_args: /* empty */ | sprintf_args ',' expr ; position: position_not_place | place ; position_not_place: expr_pair | position '+' expr_pair | position '-' expr_pair | '(' position ',' position ')' | expr between position AND position | expr '<' position ',' position '>' ; between: BETWEEN | OF THE WAY BETWEEN ; expr_pair: expr ',' expr | '(' expr_pair ')' ; place: /* line at A left == line (at A) left */ label %prec CHOP | label corner | corner label | corner OF label | HERE ; label: LABEL | nth_primitive | label '.' LABEL ; ordinal: ORDINAL | '`' any_expr TH ; optional_ordinal_last: LAST | ordinal LAST ; nth_primitive: ordinal object_type | optional_ordinal_last object_type ; object_type: BOX | CIRCLE | ELLIPSE | ARC | LINE | ARROW | SPLINE | '[' ']' | TEXT ; label_path: '.' LABEL | label_path '.' LABEL ; relative_path: corner %prec CHOP /* give this a lower precedence than LEFT and RIGHT so that [A: box] with .A left == [A: box] with (.A left) */ | label_path %prec TEXT | label_path corner ; path: relative_path | '(' relative_path ',' relative_path ')' {} /* The rest of these rules are a compatibility sop. */ | ORDINAL LAST object_type relative_path | LAST object_type relative_path | ORDINAL object_type relative_path | LABEL relative_path ; corner: DOT_N | DOT_E | DOT_W | DOT_S | DOT_NE | DOT_SE | DOT_NW | DOT_SW | DOT_C | DOT_START | DOT_END | TOP | BOTTOM | LEFT | RIGHT | UPPER LEFT | LOWER LEFT | UPPER RIGHT | LOWER RIGHT | LEFT_CORNER | RIGHT_CORNER | UPPER LEFT_CORNER | LOWER LEFT_CORNER | UPPER RIGHT_CORNER | LOWER RIGHT_CORNER | NORTH | SOUTH | EAST | WEST | CENTER | START | END ; expr: VARIABLE | NUMBER | place DOT_X | place DOT_Y | place DOT_HT | place DOT_WID | place DOT_RAD | expr '+' expr | expr '-' expr | expr '*' expr | expr '/' expr | expr '%' expr | expr '^' expr | '-' expr %prec '!' | '(' any_expr ')' | SIN '(' any_expr ')' | COS '(' any_expr ')' | ATAN2 '(' any_expr ',' any_expr ')' | LOG '(' any_expr ')' | EXP '(' any_expr ')' | SQRT '(' any_expr ')' | K_MAX '(' any_expr ',' any_expr ')' | K_MIN '(' any_expr ',' any_expr ')' | INT '(' any_expr ')' | RAND '(' any_expr ')' | RAND '(' ')' | SRAND '(' any_expr ')' | expr '<' expr | expr LESSEQUAL expr | expr '>' expr | expr GREATEREQUAL expr | expr EQUALEQUAL expr | expr NOTEQUAL expr | expr ANDAND expr | expr OROR expr | '!' expr ; _ATEOF # Pass plenty of options, to exercise plenty of code, even if we # don't actually check the output. But SEGV is watching us, and # so might do dmalloc. $at_traceoff echo "existing.at:1523: bison --verbose --defines input.y" echo existing.at:1523 >$at_check_line_file ( $at_traceon; bison --verbose --defines input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "existing.at:1523: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-15 ) # Banner 15. regression.at:21 cat <<\_ATEOF Regression tests. _ATEOF ;; 113 ) # 113. regression.at:28: Trivial grammars at_setup_line='regression.at:28' at_desc='Trivial grammars' $at_quiet $ECHO_N "113: Trivial grammars $ECHO_C" at_xfail=no ( echo "113. regression.at:28: testing ..." $at_traceon cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ void yyerror (char const *); int yylex (void); #define YYSTYPE int * %} %error-verbose %% program: 'x'; _ATEOF $at_traceoff echo "regression.at:44: bison -o input.c input.y" echo regression.at:44 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:44: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:45: \$CC \$CFLAGS \$CPPFLAGS -o input.o -c input.c" echo regression.at:45 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o input.o -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:45: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:46: \$CC \$CFLAGS \$CPPFLAGS -o input.o -DYYDEBUG -c input.c" echo regression.at:46 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o input.o -DYYDEBUG -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:46: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 114 ) # 114. regression.at:57: Early token definitions at_setup_line='regression.at:57' at_desc='Early token definitions' $at_quiet $ECHO_N "114: Early token definitions $ECHO_C" at_xfail=no ( echo "114. regression.at:57: testing ..." $at_traceon # Found in GCJ: they expect the tokens to be defined before the user # prologue, so that they can use the token definitions in it. cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ void yyerror (const char *s); int yylex (void); %} %union { int val; }; %{ #ifndef MY_TOKEN # error "MY_TOKEN not defined." #endif %} %token MY_TOKEN %% exp: MY_TOKEN; %% _ATEOF $at_traceoff echo "regression.at:83: bison -o input.c input.y" echo regression.at:83 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:83: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:84: \$CC \$CFLAGS \$CPPFLAGS -o input.o -c input.c" echo regression.at:84 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o input.o -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:84: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 115 ) # 115. regression.at:95: Braces parsing at_setup_line='regression.at:95' at_desc='Braces parsing' $at_quiet $ECHO_N "115: Braces parsing $ECHO_C" at_xfail=no ( echo "115. regression.at:95: testing ..." $at_traceon cat >input.y <<'_ATEOF' /* Bison used to swallow the character after `}'. */ %% exp: { tests = {{{{{{{{{{}}}}}}}}}}; }; %% _ATEOF $at_traceoff echo "regression.at:105: bison -v -o input.c input.y" echo regression.at:105 >$at_check_line_file ( $at_traceon; bison -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:105: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:107: grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c" echo regression.at:107 >$at_check_line_file ( $at_traceon; grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:107: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 116 ) # 116. regression.at:117: Duplicate string at_setup_line='regression.at:117' at_desc='Duplicate string' $at_quiet $ECHO_N "116: Duplicate string $ECHO_C" at_xfail=no ( echo "116. regression.at:117: testing ..." $at_traceon cat >input.y <<'_ATEOF' /* `Bison -v' used to dump core when two tokens are defined with the same string, as LE and GE below. */ %token NUM %token LE "<=" %token GE "<=" %% exp: '(' exp ')' | NUM ; %% _ATEOF $at_traceoff echo "regression.at:134: bison -v -o input.c input.y" echo regression.at:134 >$at_check_line_file ( $at_traceon; bison -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:6.8-14: warning: symbol \`\"<=\"' used more than once as a literal string " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:134: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 117 ) # 117. regression.at:143: Rule Line Numbers at_setup_line='regression.at:143' at_desc='Rule Line Numbers' $at_quiet $ECHO_N "117: Rule Line Numbers $ECHO_C" at_xfail=no ( echo "117. regression.at:143: testing ..." $at_traceon cat >input.y <<'_ATEOF' %% expr: 'a' { } 'b' { } | { } 'c' { }; _ATEOF $at_traceoff echo "regression.at:177: bison -o input.c -v input.y" echo regression.at:177 >$at_check_line_file ( $at_traceon; bison -o input.c -v input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:177: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check the contents of the report. $at_traceoff echo "regression.at:276: cat input.output" echo regression.at:276 >$at_check_line_file ( $at_traceon; cat input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Grammar 0 \$accept: expr \$end 1 @1: /* empty */ 2 expr: 'a' @1 'b' 3 @2: /* empty */ 4 expr: @2 'c' Terminals, with rules where they appear \$end (0) 0 'a' (97) 2 'b' (98) 2 'c' (99) 4 error (256) Nonterminals, with rules where they appear \$accept (6) on left: 0 expr (7) on left: 2 4, on right: 0 @1 (8) on left: 1, on right: 2 @2 (9) on left: 3, on right: 4 state 0 0 \$accept: . expr \$end 'a' shift, and go to state 1 \$default reduce using rule 3 (@2) expr go to state 2 @2 go to state 3 state 1 2 expr: 'a' . @1 'b' \$default reduce using rule 1 (@1) @1 go to state 4 state 2 0 \$accept: expr . \$end \$end shift, and go to state 5 state 3 4 expr: @2 . 'c' 'c' shift, and go to state 6 state 4 2 expr: 'a' @1 . 'b' 'b' shift, and go to state 7 state 5 0 \$accept: expr \$end . \$default accept state 6 4 expr: @2 'c' . \$default reduce using rule 4 (expr) state 7 2 expr: 'a' @1 'b' . \$default reduce using rule 2 (expr) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:276: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 118 ) # 118. regression.at:287: Mixing %token styles at_setup_line='regression.at:287' at_desc='Mixing %token styles' $at_quiet $ECHO_N "118: Mixing %token styles $ECHO_C" at_xfail=no ( echo "118. regression.at:287: testing ..." $at_traceon # Taken from the documentation. cat >input.y <<'_ATEOF' %token OR "||" %token LE 134 "<=" %left OR "<=" %% exp: ; %% _ATEOF $at_traceoff echo "regression.at:299: bison -v -o input.c input.y" echo regression.at:299 >$at_check_line_file ( $at_traceon; bison -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:299: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 119 ) # 119. regression.at:310: Invalid inputs at_setup_line='regression.at:310' at_desc='Invalid inputs' $at_quiet $ECHO_N "119: Invalid inputs $ECHO_C" at_xfail=no ( echo "119. regression.at:310: testing ..." $at_traceon cat >input.y <<'_ATEOF' %% ? default: 'a' } %& %a-does-not-exist %- %{ _ATEOF $at_traceoff echo "regression.at:331: bison input.y" echo regression.at:331 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:2.1: invalid character: \`?' input.y:3.14: invalid character: \`}' input.y:4.1: invalid character: \`%' input.y:4.2: invalid character: \`&' input.y:5.1-17: invalid directive: \`%a-does-not-exist' input.y:6.1: invalid character: \`%' input.y:6.2: invalid character: \`-' input.y:7.1-8.0: missing \`%}' at end of file " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "regression.at:331: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 120 ) # 120. regression.at:336: Invalid inputs with {} at_setup_line='regression.at:336' at_desc='Invalid inputs with {}' $at_quiet $ECHO_N "120: Invalid inputs with {} $ECHO_C" at_xfail=no ( echo "120. regression.at:336: testing ..." $at_traceon cat >input.y <<'_ATEOF' %destructor %initial-action %lex-param %parse-param %printer %union _ATEOF $at_traceoff echo "regression.at:352: bison input.y" echo regression.at:352 >$at_check_line_file ( $at_traceon; bison input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "input.y:3.1: missing \`{' in \"%destructor {...}\" input.y:4.1: missing \`{' in \"%initial-action {...}\" input.y:4.1: syntax error, unexpected %initial-action {...}, expecting string or identifier " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "regression.at:352: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 121 ) # 121. regression.at:363: Token definitions at_setup_line='regression.at:363' at_desc='Token definitions' $at_quiet $ECHO_N "121: Token definitions $ECHO_C" at_xfail=no ( echo "121. regression.at:363: testing ..." $at_traceon # Bison managed, when fed with `%token 'f' "f"' to #define 'f'! cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include void yyerror (const char *s); int yylex (void); %} %error-verbose %token MYEOF 0 "end of file" %token 'a' "a" %token B_TOKEN "b" %token C_TOKEN 'c' %token 'd' D_TOKEN %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!" %% exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"; %% void yyerror (char const *s) { fprintf (stderr, "%s\n", s); } int yylex (void) { return SPECIAL; } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "regression.at:401: bison -o input.c input.y" echo regression.at:401 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:401: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:402: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o input input.c \$LIBS" echo regression.at:402 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input input.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:402: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >experr <<'_ATEOF' syntax error, unexpected "\\'?\"\a\b\f\n\r\t\v\001\201\001\201?\?!", expecting a _ATEOF $at_traceoff echo "regression.at:406: \$PREPARSER ./input" echo regression.at:406 >$at_check_line_file ( $at_traceon; $PREPARSER ./input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff experr $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "regression.at:406: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 122 ) # 122. regression.at:416: Characters Escapes at_setup_line='regression.at:416' at_desc='Characters Escapes' $at_quiet $ECHO_N "122: Characters Escapes $ECHO_C" at_xfail=no ( echo "122. regression.at:416: testing ..." $at_traceon cat >input.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ void yyerror (const char *s); int yylex (void); %} %% exp: '\'' "\'" | '\"' "\"" | '"' "'" ; _ATEOF # Pacify font-lock-mode: " $at_traceoff echo "regression.at:432: bison -o input.c input.y" echo regression.at:432 >$at_check_line_file ( $at_traceon; bison -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:432: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:433: \$CC \$CFLAGS \$CPPFLAGS -o input.o -c input.c" echo regression.at:433 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS -o input.o -c input.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:433: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 123 ) # 123. regression.at:447: Web2c Report at_setup_line='regression.at:447' at_desc='Web2c Report' $at_quiet $ECHO_N "123: Web2c Report $ECHO_C" at_xfail=no ( echo "123. regression.at:447: testing ..." $at_traceon cat >input.y <<'_ATEOF' %token undef_id_tok const_id_tok %start CONST_DEC_PART %% CONST_DEC_PART: CONST_DEC_LIST ; CONST_DEC_LIST: CONST_DEC | CONST_DEC_LIST CONST_DEC ; CONST_DEC: { } undef_id_tok '=' const_id_tok ';' ; %% _ATEOF $at_traceoff echo "regression.at:472: bison -v input.y" echo regression.at:472 >$at_check_line_file ( $at_traceon; bison -v input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:472: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:597: cat input.output" echo regression.at:597 >$at_check_line_file ( $at_traceon; cat input.output ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Grammar 0 \$accept: CONST_DEC_PART \$end 1 CONST_DEC_PART: CONST_DEC_LIST 2 CONST_DEC_LIST: CONST_DEC 3 | CONST_DEC_LIST CONST_DEC 4 @1: /* empty */ 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';' Terminals, with rules where they appear \$end (0) 0 ';' (59) 5 '=' (61) 5 error (256) undef_id_tok (258) 5 const_id_tok (259) 5 Nonterminals, with rules where they appear \$accept (7) on left: 0 CONST_DEC_PART (8) on left: 1, on right: 0 CONST_DEC_LIST (9) on left: 2 3, on right: 1 3 CONST_DEC (10) on left: 5, on right: 2 3 @1 (11) on left: 4, on right: 5 state 0 0 \$accept: . CONST_DEC_PART \$end \$default reduce using rule 4 (@1) CONST_DEC_PART go to state 1 CONST_DEC_LIST go to state 2 CONST_DEC go to state 3 @1 go to state 4 state 1 0 \$accept: CONST_DEC_PART . \$end \$end shift, and go to state 5 state 2 1 CONST_DEC_PART: CONST_DEC_LIST . 3 CONST_DEC_LIST: CONST_DEC_LIST . CONST_DEC undef_id_tok reduce using rule 4 (@1) \$default reduce using rule 1 (CONST_DEC_PART) CONST_DEC go to state 6 @1 go to state 4 state 3 2 CONST_DEC_LIST: CONST_DEC . \$default reduce using rule 2 (CONST_DEC_LIST) state 4 5 CONST_DEC: @1 . undef_id_tok '=' const_id_tok ';' undef_id_tok shift, and go to state 7 state 5 0 \$accept: CONST_DEC_PART \$end . \$default accept state 6 3 CONST_DEC_LIST: CONST_DEC_LIST CONST_DEC . \$default reduce using rule 3 (CONST_DEC_LIST) state 7 5 CONST_DEC: @1 undef_id_tok . '=' const_id_tok ';' '=' shift, and go to state 8 state 8 5 CONST_DEC: @1 undef_id_tok '=' . const_id_tok ';' const_id_tok shift, and go to state 9 state 9 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok . ';' ';' shift, and go to state 10 state 10 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';' . \$default reduce using rule 5 (CONST_DEC) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:597: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 124 ) # 124. regression.at:624: Web2c Actions at_setup_line='regression.at:624' at_desc='Web2c Actions' $at_quiet $ECHO_N "124: Web2c Actions $ECHO_C" at_xfail=no ( echo "124. regression.at:624: testing ..." $at_traceon cat >input.y <<'_ATEOF' %% statement: struct_stat; struct_stat: /* empty. */ | if else; if: "if" "const" "then" statement; else: "else" statement; %% _ATEOF $at_traceoff echo "regression.at:637: bison -v -o input.c input.y" echo regression.at:637 >$at_check_line_file ( $at_traceon; bison -v -o input.c input.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:637: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon # Check only the tables. We don't use --no-parser, because it is # still to be implemented in the experimental branch of Bison. sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c >tables.c $at_traceoff echo "regression.at:735: cat tables.c" echo regression.at:735 >$at_check_line_file ( $at_traceon; cat tables.c ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6 }; static const yytype_uint8 yyprhs[] = { 0, 0, 3, 5, 6, 9, 14 }; static const yytype_int8 yyrhs[] = { 8, 0, -1, 9, -1, -1, 10, 11, -1, 3, 4, 5, 8, -1, 6, 8, -1 }; static const yytype_uint8 yyrline[] = { 0, 2, 2, 3, 3, 4, 5 }; static const char *const yytname[] = { \"\$end\", \"error\", \"\$undefined\", \"\\\"if\\\"\", \"\\\"const\\\"\", \"\\\"then\\\"\", \"\\\"else\\\"\", \"\$accept\", \"statement\", \"struct_stat\", \"if\", \"else\", 0 }; static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261 }; static const yytype_uint8 yyr1[] = { 0, 7, 8, 9, 9, 10, 11 }; static const yytype_uint8 yyr2[] = { 0, 2, 1, 0, 2, 4, 2 }; static const yytype_uint8 yydefact[] = { 3, 0, 0, 2, 0, 0, 1, 3, 4, 3, 6, 5 }; static const yytype_int8 yydefgoto[] = { -1, 2, 3, 4, 8 }; static const yytype_int8 yypact[] = { -2, -1, 4, -8, 0, 2, -8, -2, -8, -2, -8, -8 }; static const yytype_int8 yypgoto[] = { -8, -7, -8, -8, -8 }; static const yytype_uint8 yytable[] = { 10, 1, 11, 5, 6, 0, 7, 9 }; static const yytype_int8 yycheck[] = { 7, 3, 9, 4, 0, -1, 6, 5 }; static const yytype_uint8 yystos[] = { 0, 3, 8, 9, 10, 4, 0, 6, 11, 5, 8, 8 }; " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:735: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 125 ) # 125. regression.at:866: Dancer at_setup_line='regression.at:866' at_desc='Dancer ' $at_quiet $ECHO_N "125: Dancer $ECHO_C" at_xfail=no ( echo "125. regression.at:866: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >dancer.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ static int yylex (void); #include static void yyerror (const char *); %} %token ARROW INVALID NUMBER STRING DATA %defines %verbose %error-verbose /* Grammar follows */ %% line: header body ; header: '<' from ARROW to '>' type ':' | '<' ARROW to '>' type ':' | ARROW to type ':' | type ':' | '<' '>' ; from: DATA | STRING | INVALID ; to: DATA | STRING | INVALID ; type: DATA | STRING | INVALID ; body: /* empty */ | body member ; member: STRING | DATA | '+' NUMBER | '-' NUMBER | NUMBER | INVALID ; %% static void yyerror (const char *s) { fprintf (stderr, "%s\n", s); } static int yylex (void) { static int toknum = 0; static int tokens[] = { ':', -1 }; return tokens[toknum++]; } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "regression.at:866: bison -o dancer.c dancer.y" echo regression.at:866 >$at_check_line_file ( $at_traceon; bison -o dancer.c dancer.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:866: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:866: bison -o dancer.c dancer.y" echo regression.at:866 >$at_check_line_file ( $at_traceon; bison -o dancer.c dancer.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:866: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:866: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o dancer dancer.c \$LIBS" echo regression.at:866 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o dancer dancer.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:866: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:866: \$PREPARSER ./dancer" echo regression.at:866 >$at_check_line_file ( $at_traceon; $PREPARSER ./dancer ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected ':' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "regression.at:866: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 126 ) # 126. regression.at:867: Dancer %glr-parser at_setup_line='regression.at:867' at_desc='Dancer %glr-parser' $at_quiet $ECHO_N "126: Dancer %glr-parser $ECHO_C" at_xfail=no ( echo "126. regression.at:867: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >dancer.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ static int yylex (void); #include static void yyerror (const char *); %} %glr-parser %token ARROW INVALID NUMBER STRING DATA %defines %verbose %error-verbose /* Grammar follows */ %% line: header body ; header: '<' from ARROW to '>' type ':' | '<' ARROW to '>' type ':' | ARROW to type ':' | type ':' | '<' '>' ; from: DATA | STRING | INVALID ; to: DATA | STRING | INVALID ; type: DATA | STRING | INVALID ; body: /* empty */ | body member ; member: STRING | DATA | '+' NUMBER | '-' NUMBER | NUMBER | INVALID ; %% static void yyerror (const char *s) { fprintf (stderr, "%s\n", s); } static int yylex (void) { static int toknum = 0; static int tokens[] = { ':', -1 }; return tokens[toknum++]; } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "regression.at:867: bison -o dancer.c dancer.y" echo regression.at:867 >$at_check_line_file ( $at_traceon; bison -o dancer.c dancer.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:867: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:867: bison -o dancer.c dancer.y" echo regression.at:867 >$at_check_line_file ( $at_traceon; bison -o dancer.c dancer.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:867: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:867: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o dancer dancer.c \$LIBS" echo regression.at:867 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o dancer dancer.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:867: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:867: \$PREPARSER ./dancer" echo regression.at:867 >$at_check_line_file ( $at_traceon; $PREPARSER ./dancer ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected ':' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "regression.at:867: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 127 ) # 127. regression.at:868: Dancer %skeleton "lalr1.cc" at_setup_line='regression.at:868' at_desc='Dancer %skeleton "lalr1.cc"' $at_quiet $ECHO_N "127: Dancer %skeleton "lalr1.cc" $ECHO_C" at_xfail=no ( echo "127. regression.at:868: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >dancer.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ static int yylex (int *); %} %skeleton "lalr1.cc" %token ARROW INVALID NUMBER STRING DATA %defines %verbose %error-verbose /* Grammar follows */ %% line: header body ; header: '<' from ARROW to '>' type ':' | '<' ARROW to '>' type ':' | ARROW to type ':' | type ':' | '<' '>' ; from: DATA | STRING | INVALID ; to: DATA | STRING | INVALID ; type: DATA | STRING | INVALID ; body: /* empty */ | body member ; member: STRING | DATA | '+' NUMBER | '-' NUMBER | NUMBER | INVALID ; %% /* A C++ error reporting function. */ void yy::parser::error (const location&, const std::string& m) { std::cerr << m << std::endl; } int yyparse () { yy::parser parser; parser.set_debug_level (!!YYDEBUG); return parser.parse (); } static int yylex (int *lval) { static int toknum = 0; static int tokens[] = { ':', -1 }; *lval = 0; /* Pacify GCC. */ return tokens[toknum++]; } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "regression.at:868: bison -o dancer.c dancer.y" echo regression.at:868 >$at_check_line_file ( $at_traceon; bison -o dancer.c dancer.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:868: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:868: bison -o dancer.cc dancer.y" echo regression.at:868 >$at_check_line_file ( $at_traceon; bison -o dancer.cc dancer.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:868: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:868: \$BISON_CXX_WORKS" echo regression.at:868 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:868: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:868: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o dancer dancer.cc \$LIBS" echo regression.at:868 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o dancer dancer.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:868: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:868: \$PREPARSER ./dancer" echo regression.at:868 >$at_check_line_file ( $at_traceon; $PREPARSER ./dancer ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected ':' " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "regression.at:868: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 128 ) # 128. regression.at:963: Expecting two tokens at_setup_line='regression.at:963' at_desc='Expecting two tokens ' $at_quiet $ECHO_N "128: Expecting two tokens $ECHO_C" at_xfail=no ( echo "128. regression.at:963: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >expect2.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ static int yylex (void); #include static void yyerror (const char *); %} %defines %error-verbose %token A 1000 %token B %% program: /* empty */ | program e ';' | program error ';'; e: e '+' t | t; t: A | B; %% static void yyerror (const char *s) { fprintf (stderr, "%s\n", s); } static int yylex (void) { static int toknum = 0; static int tokens[] = { 1000, '+', '+', -1 }; return tokens[toknum++]; } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "regression.at:963: bison -o expect2.c expect2.y" echo regression.at:963 >$at_check_line_file ( $at_traceon; bison -o expect2.c expect2.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:963: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:963: bison -o expect2.c expect2.y" echo regression.at:963 >$at_check_line_file ( $at_traceon; bison -o expect2.c expect2.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:963: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:963: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o expect2 expect2.c \$LIBS" echo regression.at:963 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o expect2 expect2.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:963: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:963: \$PREPARSER ./expect2" echo regression.at:963 >$at_check_line_file ( $at_traceon; $PREPARSER ./expect2 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected '+', expecting A or B " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "regression.at:963: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 129 ) # 129. regression.at:964: Expecting two tokens %glr-parser at_setup_line='regression.at:964' at_desc='Expecting two tokens %glr-parser' $at_quiet $ECHO_N "129: Expecting two tokens %glr-parser $ECHO_C" at_xfail=no ( echo "129. regression.at:964: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >expect2.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ static int yylex (void); #include static void yyerror (const char *); %} %glr-parser %defines %error-verbose %token A 1000 %token B %% program: /* empty */ | program e ';' | program error ';'; e: e '+' t | t; t: A | B; %% static void yyerror (const char *s) { fprintf (stderr, "%s\n", s); } static int yylex (void) { static int toknum = 0; static int tokens[] = { 1000, '+', '+', -1 }; return tokens[toknum++]; } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "regression.at:964: bison -o expect2.c expect2.y" echo regression.at:964 >$at_check_line_file ( $at_traceon; bison -o expect2.c expect2.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:964: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:964: bison -o expect2.c expect2.y" echo regression.at:964 >$at_check_line_file ( $at_traceon; bison -o expect2.c expect2.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:964: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:964: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o expect2 expect2.c \$LIBS" echo regression.at:964 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o expect2 expect2.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:964: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:964: \$PREPARSER ./expect2" echo regression.at:964 >$at_check_line_file ( $at_traceon; $PREPARSER ./expect2 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected '+', expecting A or B " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "regression.at:964: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 130 ) # 130. regression.at:965: Expecting two tokens %skeleton "lalr1.cc" at_setup_line='regression.at:965' at_desc='Expecting two tokens %skeleton "lalr1.cc"' $at_quiet $ECHO_N "130: Expecting two tokens %skeleton "lalr1.cc" $ECHO_C" at_xfail=no ( echo "130. regression.at:965: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >expect2.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ static int yylex (int *); %} %skeleton "lalr1.cc" %defines %error-verbose %token A 1000 %token B %% program: /* empty */ | program e ';' | program error ';'; e: e '+' t | t; t: A | B; %% /* A C++ error reporting function. */ void yy::parser::error (const location&, const std::string& m) { std::cerr << m << std::endl; } int yyparse () { yy::parser parser; return parser.parse (); } static int yylex (int *lval) { static int toknum = 0; static int tokens[] = { 1000, '+', '+', -1 }; *lval = 0; /* Pacify GCC. */ return tokens[toknum++]; } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "regression.at:965: bison -o expect2.c expect2.y" echo regression.at:965 >$at_check_line_file ( $at_traceon; bison -o expect2.c expect2.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:965: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:965: bison -o expect2.cc expect2.y" echo regression.at:965 >$at_check_line_file ( $at_traceon; bison -o expect2.cc expect2.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:965: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:965: \$BISON_CXX_WORKS" echo regression.at:965 >$at_check_line_file ( $at_traceon; $BISON_CXX_WORKS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:965: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:965: \$CXX \$CXXFLAGS \$CPPFLAGS \$LDFLAGS -o expect2 expect2.cc \$LIBS" echo regression.at:965 >$at_check_line_file ( $at_traceon; $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o expect2 expect2.cc $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "regression.at:965: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "regression.at:965: \$PREPARSER ./expect2" echo regression.at:965 >$at_check_line_file ( $at_traceon; $PREPARSER ./expect2 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected '+', expecting A or B " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 1) ;; *) echo "regression.at:965: exit code was $at_status, expected 1" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-16 ) # Banner 16. c++.at:19 cat <<\_ATEOF C++ Features. _ATEOF ;; 131 ) # 131. c++.at:102: Doxygen Public Documentation at_setup_line='c++.at:102' at_desc='Doxygen Public Documentation' $at_quiet $ECHO_N "131: Doxygen Public Documentation $ECHO_C" at_xfail=no ( echo "131. c++.at:102: testing ..." $at_traceon cat >input.yy <<'_ATEOF' %skeleton "lalr1.cc" %locations %debug %defines %% exp:; %% yy::parser::error (const location& l, const std::string& m) { std::cerr << l << s << std::endl; } _ATEOF $at_traceoff echo "c++.at:102: bison -o input.cc input.yy" echo c++.at:102 >$at_check_line_file ( $at_traceon; bison -o input.cc input.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "c++.at:102: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >Doxyfile <<'_ATEOF' # The PROJECT_NAME tag is a single word (or a sequence of words # surrounded by quotes) that should identify the project. PROJECT_NAME = "Bison C++ Parser" # The QUIET tag can be used to turn on/off the messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages # that are generated by doxygen. Possible values are YES and NO. If # left blank NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then # this flag will automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings # for potential errors in the documentation, such as not documenting # some parameters in a documented function, or documenting parameters # that don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_FORMAT tag determines the format of the warning messages # that doxygen can produce. The string should contain the $file, # $line, and $text tags, which will be replaced by the file and line # number from which the warning originated and the warning text. WARN_FORMAT = "$file:$line: $text" # If the EXTRACT_ALL tag is set to YES doxygen will assume all # entities in documentation are documented, even if no documentation # was available. Private class members and static file members will # be hidden unless the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set # to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a # class will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO _ATEOF $at_traceoff echo "c++.at:102: doxygen --version || exit 77" echo c++.at:102 >$at_check_line_file ( $at_traceon; doxygen --version || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "c++.at:102: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "c++.at:102: doxygen" echo c++.at:102 >$at_check_line_file ( $at_traceon; doxygen ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "c++.at:102: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 132 ) # 132. c++.at:103: Doxygen Private Documentation at_setup_line='c++.at:103' at_desc='Doxygen Private Documentation' $at_quiet $ECHO_N "132: Doxygen Private Documentation $ECHO_C" at_xfail=no ( echo "132. c++.at:103: testing ..." $at_traceon cat >input.yy <<'_ATEOF' %skeleton "lalr1.cc" %locations %debug %defines %% exp:; %% yy::parser::error (const location& l, const std::string& m) { std::cerr << l << s << std::endl; } _ATEOF $at_traceoff echo "c++.at:103: bison -o input.cc input.yy" echo c++.at:103 >$at_check_line_file ( $at_traceon; bison -o input.cc input.yy ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "c++.at:103: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon cat >Doxyfile <<'_ATEOF' # The PROJECT_NAME tag is a single word (or a sequence of words # surrounded by quotes) that should identify the project. PROJECT_NAME = "Bison C++ Parser" # The QUIET tag can be used to turn on/off the messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages # that are generated by doxygen. Possible values are YES and NO. If # left blank NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then # this flag will automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings # for potential errors in the documentation, such as not documenting # some parameters in a documented function, or documenting parameters # that don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_FORMAT tag determines the format of the warning messages # that doxygen can produce. The string should contain the $file, # $line, and $text tags, which will be replaced by the file and line # number from which the warning originated and the warning text. WARN_FORMAT = "$file:$line: $text" # If the EXTRACT_ALL tag is set to YES doxygen will assume all # entities in documentation are documented, even if no documentation # was available. Private class members and static file members will # be hidden unless the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set # to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a # class will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES _ATEOF $at_traceoff echo "c++.at:103: doxygen --version || exit 77" echo c++.at:103 >$at_check_line_file ( $at_traceon; doxygen --version || exit 77 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "c++.at:103: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "c++.at:103: doxygen" echo c++.at:103 >$at_check_line_file ( $at_traceon; doxygen ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "c++.at:103: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-17 ) # Banner 17. cxx-type.at:19 cat <<\_ATEOF C++ Type Syntax (GLR). _ATEOF ;; 133 ) # 133. cxx-type.at:412: GLR: Resolve ambiguity, impure, no locations at_setup_line='cxx-type.at:412' at_desc='GLR: Resolve ambiguity, impure, no locations' $at_quiet $ECHO_N "133: GLR: Resolve ambiguity, impure, no locations $ECHO_C" at_xfail=no ( echo "133. cxx-type.at:412: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >types.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Simplified C++ Type and Expression Grammar. */ %{ #include union Node { struct { int isNterm; int parents; } nodeInfo; struct { int isNterm; /* 1 */ int parents; char const *form; union Node *children[3]; } nterm; struct { int isNterm; /* 0 */ int parents; char *text; } term; }; typedef union Node Node; static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); #define YYSTYPE Node * #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 struct YYLTYPE; #if YYPURE # if YYLSP_NEEDED # define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp # define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s # else # define LEX_PARAMETERS YYSTYPE *lvalp # endif #endif #ifndef LEX_PARAMETERS # define LEX_PARAMETERS void #endif #ifndef ERROR_PARAMETERS # define ERROR_PARAMETERS char const *s #endif int yylex (LEX_PARAMETERS); void yyerror (ERROR_PARAMETERS); %} %token TYPENAME ID %right '=' %left '+' %glr-parser %destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %% prog : | prog stmt { char *output; output = node_to_string ($2); printf ("%s\n", output); free (output); free_node ($2); } ; stmt : expr ';' %dprec 1 { $$ = $1; } | decl %dprec 2 | error ';' { $$ = new_nterm ("", 0, 0, 0); } | '@' { YYACCEPT; } ; expr : ID | TYPENAME '(' expr ')' { $$ = new_nterm ("(%s,%s)", $3, $1, 0); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", $1, $3, 0); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", $1, $3, 0); } ; decl : TYPENAME declarator ';' { $$ = new_nterm ("(%s,%s)", $1, $2, 0); } | TYPENAME declarator '=' expr ';' { $$ = new_nterm ("(%s,%s,%s)", $1, $2, $4); } ; declarator : ID | '(' declarator ')' { $$ = $2; } ; %% #include #include #include #include int main (int argc, char **argv) { if (argc != 2) abort (); if (!freopen (argv[1], "r", stdin)) return 3; return yyparse (); } int yylex (LEX_PARAMETERS) { char buffer[256]; int c; unsigned int i; static int lineNum = 1; static int colNum = 0; #if YYPURE # undef yylloc # define yylloc (*llocp) # undef yylval # define yylval (*lvalp) #endif while (1) { c = getchar (); switch (c) { case EOF: return 0; case '\t': colNum = (colNum + 7) & ~7; break; case ' ': case '\f': colNum += 1; break; case '\n': lineNum += 1; colNum = 0; break; default: { int tok; #if YYLSP_NEEDED yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_column = colNum; #endif if (isalpha (c)) { i = 0; do { buffer[i++] = c; colNum += 1; if (i == sizeof buffer - 1) abort (); c = getchar (); } while (isalnum (c) || c == '_'); ungetc (c, stdin); buffer[i++] = 0; tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = new_term (strcpy ((char *) malloc (i), buffer)); } else { colNum += 1; tok = c; yylval = 0; } #if YYLSP_NEEDED yylloc.last_column = colNum-1; #endif return tok; } } } } void yyerror (ERROR_PARAMETERS) { #if YYPURE && YYLSP_NEEDED /* Pacify GCC by using llocp. */ if (! llocp) abort (); #endif fprintf (stderr, "%s\n", s); } static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { Node *node = (Node *) malloc (sizeof (Node)); node->nterm.isNterm = 1; node->nterm.parents = 0; node->nterm.form = form; node->nterm.children[0] = child0; if (child0) child0->nodeInfo.parents += 1; node->nterm.children[1] = child1; if (child1) child1->nodeInfo.parents += 1; node->nterm.children[2] = child2; if (child2) child2->nodeInfo.parents += 1; return node; } static Node * new_term (char *text) { Node *node = (Node *) malloc (sizeof (Node)); node->term.isNterm = 0; node->term.parents = 0; node->term.text = text; return node; } static void free_node (Node *node) { if (!node) return; node->nodeInfo.parents -= 1; /* Free only if 0 (last parent) or -1 (no parents). */ if (node->nodeInfo.parents > 0) return; if (node->nodeInfo.isNterm == 1) { free_node (node->nterm.children[0]); free_node (node->nterm.children[1]); free_node (node->nterm.children[2]); } else free (node->term.text); free (node); } static char * node_to_string (Node *node) { char *child0; char *child1; char *child2; char *buffer; if (!node) { buffer = (char *) malloc (1); buffer[0] = 0; } else if (node->nodeInfo.isNterm == 1) { child0 = node_to_string (node->nterm.children[0]); child1 = node_to_string (node->nterm.children[1]); child2 = node_to_string (node->nterm.children[2]); buffer = (char *) malloc (strlen (node->nterm.form) + strlen (child0) + strlen (child1) + strlen (child2) + 1); sprintf (buffer, node->nterm.form, child0, child1, child2); free (child0); free (child1); free (child2); } else buffer = strdup (node->term.text); return buffer; } _ATEOF cat >test-input <<'_ATEOF' z + q; T x; T x = y; x = y; T (x) + y; T (x); T (y) = z + q; T (y y) = z + q; z + q; @ This is total garbage, but it should be ignored. _ATEOF $at_traceoff echo "cxx-type.at:414: bison -o types.c types.y" echo cxx-type.at:414 >$at_check_line_file ( $at_traceon; bison -o types.c types.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:414: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:414: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o types types.c \$LIBS" echo cxx-type.at:414 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o types types.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:414: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:416: \$PREPARSER ./types test-input" echo cxx-type.at:416 >$at_check_line_file ( $at_traceon; $PREPARSER ./types test-input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "+(z,q) (T,x) (T,x,y) =(x,y) +((x,T),y) (T,x) (T,y,+(z,q)) +(z,q) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:416: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 134 ) # 134. cxx-type.at:419: GLR: Resolve ambiguity, impure, locations at_setup_line='cxx-type.at:419' at_desc='GLR: Resolve ambiguity, impure, locations' $at_quiet $ECHO_N "134: GLR: Resolve ambiguity, impure, locations $ECHO_C" at_xfail=no ( echo "134. cxx-type.at:419: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >types.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Simplified C++ Type and Expression Grammar. */ %locations %{ #include union Node { struct { int isNterm; int parents; } nodeInfo; struct { int isNterm; /* 1 */ int parents; char const *form; union Node *children[3]; } nterm; struct { int isNterm; /* 0 */ int parents; char *text; } term; }; typedef union Node Node; static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); #define YYSTYPE Node * #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 struct YYLTYPE; #if YYPURE # if YYLSP_NEEDED # define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp # define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s # else # define LEX_PARAMETERS YYSTYPE *lvalp # endif #endif #ifndef LEX_PARAMETERS # define LEX_PARAMETERS void #endif #ifndef ERROR_PARAMETERS # define ERROR_PARAMETERS char const *s #endif int yylex (LEX_PARAMETERS); void yyerror (ERROR_PARAMETERS); %} %token TYPENAME ID %right '=' %left '+' %glr-parser %destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %% prog : | prog stmt { char *output; printf ("%d.%d-%d.%d: ", @2.first_line, @2.first_column, @2.last_line, @2.last_column); output = node_to_string ($2); printf ("%s\n", output); free (output); free_node ($2); } ; stmt : expr ';' %dprec 1 { $$ = $1; } | decl %dprec 2 | error ';' { $$ = new_nterm ("", 0, 0, 0); } | '@' { YYACCEPT; } ; expr : ID | TYPENAME '(' expr ')' { $$ = new_nterm ("(%s,%s)", $3, $1, 0); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", $1, $3, 0); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", $1, $3, 0); } ; decl : TYPENAME declarator ';' { $$ = new_nterm ("(%s,%s)", $1, $2, 0); } | TYPENAME declarator '=' expr ';' { $$ = new_nterm ("(%s,%s,%s)", $1, $2, $4); } ; declarator : ID | '(' declarator ')' { $$ = $2; } ; %% #include #include #include #include int main (int argc, char **argv) { if (argc != 2) abort (); if (!freopen (argv[1], "r", stdin)) return 3; return yyparse (); } int yylex (LEX_PARAMETERS) { char buffer[256]; int c; unsigned int i; static int lineNum = 1; static int colNum = 0; #if YYPURE # undef yylloc # define yylloc (*llocp) # undef yylval # define yylval (*lvalp) #endif while (1) { c = getchar (); switch (c) { case EOF: return 0; case '\t': colNum = (colNum + 7) & ~7; break; case ' ': case '\f': colNum += 1; break; case '\n': lineNum += 1; colNum = 0; break; default: { int tok; #if YYLSP_NEEDED yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_column = colNum; #endif if (isalpha (c)) { i = 0; do { buffer[i++] = c; colNum += 1; if (i == sizeof buffer - 1) abort (); c = getchar (); } while (isalnum (c) || c == '_'); ungetc (c, stdin); buffer[i++] = 0; tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = new_term (strcpy ((char *) malloc (i), buffer)); } else { colNum += 1; tok = c; yylval = 0; } #if YYLSP_NEEDED yylloc.last_column = colNum-1; #endif return tok; } } } } void yyerror (ERROR_PARAMETERS) { #if YYPURE && YYLSP_NEEDED /* Pacify GCC by using llocp. */ if (! llocp) abort (); #endif fprintf (stderr, "%s\n", s); } static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { Node *node = (Node *) malloc (sizeof (Node)); node->nterm.isNterm = 1; node->nterm.parents = 0; node->nterm.form = form; node->nterm.children[0] = child0; if (child0) child0->nodeInfo.parents += 1; node->nterm.children[1] = child1; if (child1) child1->nodeInfo.parents += 1; node->nterm.children[2] = child2; if (child2) child2->nodeInfo.parents += 1; return node; } static Node * new_term (char *text) { Node *node = (Node *) malloc (sizeof (Node)); node->term.isNterm = 0; node->term.parents = 0; node->term.text = text; return node; } static void free_node (Node *node) { if (!node) return; node->nodeInfo.parents -= 1; /* Free only if 0 (last parent) or -1 (no parents). */ if (node->nodeInfo.parents > 0) return; if (node->nodeInfo.isNterm == 1) { free_node (node->nterm.children[0]); free_node (node->nterm.children[1]); free_node (node->nterm.children[2]); } else free (node->term.text); free (node); } static char * node_to_string (Node *node) { char *child0; char *child1; char *child2; char *buffer; if (!node) { buffer = (char *) malloc (1); buffer[0] = 0; } else if (node->nodeInfo.isNterm == 1) { child0 = node_to_string (node->nterm.children[0]); child1 = node_to_string (node->nterm.children[1]); child2 = node_to_string (node->nterm.children[2]); buffer = (char *) malloc (strlen (node->nterm.form) + strlen (child0) + strlen (child1) + strlen (child2) + 1); sprintf (buffer, node->nterm.form, child0, child1, child2); free (child0); free (child1); free (child2); } else buffer = strdup (node->term.text); return buffer; } _ATEOF cat >test-input <<'_ATEOF' z + q; T x; T x = y; x = y; T (x) + y; T (x); T (y) = z + q; T (y y) = z + q; z + q; @ This is total garbage, but it should be ignored. _ATEOF $at_traceoff echo "cxx-type.at:420: bison -o types.c types.y" echo cxx-type.at:420 >$at_check_line_file ( $at_traceon; bison -o types.c types.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:420: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:420: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o types types.c \$LIBS" echo cxx-type.at:420 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o types types.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:420: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:422: \$PREPARSER ./types test-input" echo cxx-type.at:422 >$at_check_line_file ( $at_traceon; $PREPARSER ./types test-input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "3.0-3.5: +(z,q) 5.0-5.3: (T,x) 7.0-7.7: (T,x,y) 9.0-9.5: =(x,y) 11.0-11.9: +((x,T),y) 13.0-13.5: (T,x) 15.0-15.13: (T,y,+(z,q)) 17.0-17.15: 19.0-19.5: +(z,q) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:422: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 135 ) # 135. cxx-type.at:425: GLR: Resolve ambiguity, pure, no locations at_setup_line='cxx-type.at:425' at_desc='GLR: Resolve ambiguity, pure, no locations' $at_quiet $ECHO_N "135: GLR: Resolve ambiguity, pure, no locations $ECHO_C" at_xfail=no ( echo "135. cxx-type.at:425: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >types.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Simplified C++ Type and Expression Grammar. */ %pure-parser %{ #include union Node { struct { int isNterm; int parents; } nodeInfo; struct { int isNterm; /* 1 */ int parents; char const *form; union Node *children[3]; } nterm; struct { int isNterm; /* 0 */ int parents; char *text; } term; }; typedef union Node Node; static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); #define YYSTYPE Node * #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 struct YYLTYPE; #if YYPURE # if YYLSP_NEEDED # define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp # define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s # else # define LEX_PARAMETERS YYSTYPE *lvalp # endif #endif #ifndef LEX_PARAMETERS # define LEX_PARAMETERS void #endif #ifndef ERROR_PARAMETERS # define ERROR_PARAMETERS char const *s #endif int yylex (LEX_PARAMETERS); void yyerror (ERROR_PARAMETERS); %} %token TYPENAME ID %right '=' %left '+' %glr-parser %destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %% prog : | prog stmt { char *output; output = node_to_string ($2); printf ("%s\n", output); free (output); free_node ($2); } ; stmt : expr ';' %dprec 1 { $$ = $1; } | decl %dprec 2 | error ';' { $$ = new_nterm ("", 0, 0, 0); } | '@' { YYACCEPT; } ; expr : ID | TYPENAME '(' expr ')' { $$ = new_nterm ("(%s,%s)", $3, $1, 0); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", $1, $3, 0); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", $1, $3, 0); } ; decl : TYPENAME declarator ';' { $$ = new_nterm ("(%s,%s)", $1, $2, 0); } | TYPENAME declarator '=' expr ';' { $$ = new_nterm ("(%s,%s,%s)", $1, $2, $4); } ; declarator : ID | '(' declarator ')' { $$ = $2; } ; %% #include #include #include #include int main (int argc, char **argv) { if (argc != 2) abort (); if (!freopen (argv[1], "r", stdin)) return 3; return yyparse (); } int yylex (LEX_PARAMETERS) { char buffer[256]; int c; unsigned int i; static int lineNum = 1; static int colNum = 0; #if YYPURE # undef yylloc # define yylloc (*llocp) # undef yylval # define yylval (*lvalp) #endif while (1) { c = getchar (); switch (c) { case EOF: return 0; case '\t': colNum = (colNum + 7) & ~7; break; case ' ': case '\f': colNum += 1; break; case '\n': lineNum += 1; colNum = 0; break; default: { int tok; #if YYLSP_NEEDED yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_column = colNum; #endif if (isalpha (c)) { i = 0; do { buffer[i++] = c; colNum += 1; if (i == sizeof buffer - 1) abort (); c = getchar (); } while (isalnum (c) || c == '_'); ungetc (c, stdin); buffer[i++] = 0; tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = new_term (strcpy ((char *) malloc (i), buffer)); } else { colNum += 1; tok = c; yylval = 0; } #if YYLSP_NEEDED yylloc.last_column = colNum-1; #endif return tok; } } } } void yyerror (ERROR_PARAMETERS) { #if YYPURE && YYLSP_NEEDED /* Pacify GCC by using llocp. */ if (! llocp) abort (); #endif fprintf (stderr, "%s\n", s); } static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { Node *node = (Node *) malloc (sizeof (Node)); node->nterm.isNterm = 1; node->nterm.parents = 0; node->nterm.form = form; node->nterm.children[0] = child0; if (child0) child0->nodeInfo.parents += 1; node->nterm.children[1] = child1; if (child1) child1->nodeInfo.parents += 1; node->nterm.children[2] = child2; if (child2) child2->nodeInfo.parents += 1; return node; } static Node * new_term (char *text) { Node *node = (Node *) malloc (sizeof (Node)); node->term.isNterm = 0; node->term.parents = 0; node->term.text = text; return node; } static void free_node (Node *node) { if (!node) return; node->nodeInfo.parents -= 1; /* Free only if 0 (last parent) or -1 (no parents). */ if (node->nodeInfo.parents > 0) return; if (node->nodeInfo.isNterm == 1) { free_node (node->nterm.children[0]); free_node (node->nterm.children[1]); free_node (node->nterm.children[2]); } else free (node->term.text); free (node); } static char * node_to_string (Node *node) { char *child0; char *child1; char *child2; char *buffer; if (!node) { buffer = (char *) malloc (1); buffer[0] = 0; } else if (node->nodeInfo.isNterm == 1) { child0 = node_to_string (node->nterm.children[0]); child1 = node_to_string (node->nterm.children[1]); child2 = node_to_string (node->nterm.children[2]); buffer = (char *) malloc (strlen (node->nterm.form) + strlen (child0) + strlen (child1) + strlen (child2) + 1); sprintf (buffer, node->nterm.form, child0, child1, child2); free (child0); free (child1); free (child2); } else buffer = strdup (node->term.text); return buffer; } _ATEOF cat >test-input <<'_ATEOF' z + q; T x; T x = y; x = y; T (x) + y; T (x); T (y) = z + q; T (y y) = z + q; z + q; @ This is total garbage, but it should be ignored. _ATEOF $at_traceoff echo "cxx-type.at:427: bison -o types.c types.y" echo cxx-type.at:427 >$at_check_line_file ( $at_traceon; bison -o types.c types.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:427: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:427: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o types types.c \$LIBS" echo cxx-type.at:427 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o types types.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:427: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:429: \$PREPARSER ./types test-input" echo cxx-type.at:429 >$at_check_line_file ( $at_traceon; $PREPARSER ./types test-input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "+(z,q) (T,x) (T,x,y) =(x,y) +((x,T),y) (T,x) (T,y,+(z,q)) +(z,q) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:429: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 136 ) # 136. cxx-type.at:432: GLR: Resolve ambiguity, pure, locations at_setup_line='cxx-type.at:432' at_desc='GLR: Resolve ambiguity, pure, locations' $at_quiet $ECHO_N "136: GLR: Resolve ambiguity, pure, locations $ECHO_C" at_xfail=no ( echo "136. cxx-type.at:432: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >types.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Simplified C++ Type and Expression Grammar. */ %pure-parser %locations %{ #include union Node { struct { int isNterm; int parents; } nodeInfo; struct { int isNterm; /* 1 */ int parents; char const *form; union Node *children[3]; } nterm; struct { int isNterm; /* 0 */ int parents; char *text; } term; }; typedef union Node Node; static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); #define YYSTYPE Node * #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 struct YYLTYPE; #if YYPURE # if YYLSP_NEEDED # define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp # define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s # else # define LEX_PARAMETERS YYSTYPE *lvalp # endif #endif #ifndef LEX_PARAMETERS # define LEX_PARAMETERS void #endif #ifndef ERROR_PARAMETERS # define ERROR_PARAMETERS char const *s #endif int yylex (LEX_PARAMETERS); void yyerror (ERROR_PARAMETERS); %} %token TYPENAME ID %right '=' %left '+' %glr-parser %destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %% prog : | prog stmt { char *output; printf ("%d.%d-%d.%d: ", @2.first_line, @2.first_column, @2.last_line, @2.last_column); output = node_to_string ($2); printf ("%s\n", output); free (output); free_node ($2); } ; stmt : expr ';' %dprec 1 { $$ = $1; } | decl %dprec 2 | error ';' { $$ = new_nterm ("", 0, 0, 0); } | '@' { YYACCEPT; } ; expr : ID | TYPENAME '(' expr ')' { $$ = new_nterm ("(%s,%s)", $3, $1, 0); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", $1, $3, 0); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", $1, $3, 0); } ; decl : TYPENAME declarator ';' { $$ = new_nterm ("(%s,%s)", $1, $2, 0); } | TYPENAME declarator '=' expr ';' { $$ = new_nterm ("(%s,%s,%s)", $1, $2, $4); } ; declarator : ID | '(' declarator ')' { $$ = $2; } ; %% #include #include #include #include int main (int argc, char **argv) { if (argc != 2) abort (); if (!freopen (argv[1], "r", stdin)) return 3; return yyparse (); } int yylex (LEX_PARAMETERS) { char buffer[256]; int c; unsigned int i; static int lineNum = 1; static int colNum = 0; #if YYPURE # undef yylloc # define yylloc (*llocp) # undef yylval # define yylval (*lvalp) #endif while (1) { c = getchar (); switch (c) { case EOF: return 0; case '\t': colNum = (colNum + 7) & ~7; break; case ' ': case '\f': colNum += 1; break; case '\n': lineNum += 1; colNum = 0; break; default: { int tok; #if YYLSP_NEEDED yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_column = colNum; #endif if (isalpha (c)) { i = 0; do { buffer[i++] = c; colNum += 1; if (i == sizeof buffer - 1) abort (); c = getchar (); } while (isalnum (c) || c == '_'); ungetc (c, stdin); buffer[i++] = 0; tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = new_term (strcpy ((char *) malloc (i), buffer)); } else { colNum += 1; tok = c; yylval = 0; } #if YYLSP_NEEDED yylloc.last_column = colNum-1; #endif return tok; } } } } void yyerror (ERROR_PARAMETERS) { #if YYPURE && YYLSP_NEEDED /* Pacify GCC by using llocp. */ if (! llocp) abort (); #endif fprintf (stderr, "%s\n", s); } static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { Node *node = (Node *) malloc (sizeof (Node)); node->nterm.isNterm = 1; node->nterm.parents = 0; node->nterm.form = form; node->nterm.children[0] = child0; if (child0) child0->nodeInfo.parents += 1; node->nterm.children[1] = child1; if (child1) child1->nodeInfo.parents += 1; node->nterm.children[2] = child2; if (child2) child2->nodeInfo.parents += 1; return node; } static Node * new_term (char *text) { Node *node = (Node *) malloc (sizeof (Node)); node->term.isNterm = 0; node->term.parents = 0; node->term.text = text; return node; } static void free_node (Node *node) { if (!node) return; node->nodeInfo.parents -= 1; /* Free only if 0 (last parent) or -1 (no parents). */ if (node->nodeInfo.parents > 0) return; if (node->nodeInfo.isNterm == 1) { free_node (node->nterm.children[0]); free_node (node->nterm.children[1]); free_node (node->nterm.children[2]); } else free (node->term.text); free (node); } static char * node_to_string (Node *node) { char *child0; char *child1; char *child2; char *buffer; if (!node) { buffer = (char *) malloc (1); buffer[0] = 0; } else if (node->nodeInfo.isNterm == 1) { child0 = node_to_string (node->nterm.children[0]); child1 = node_to_string (node->nterm.children[1]); child2 = node_to_string (node->nterm.children[2]); buffer = (char *) malloc (strlen (node->nterm.form) + strlen (child0) + strlen (child1) + strlen (child2) + 1); sprintf (buffer, node->nterm.form, child0, child1, child2); free (child0); free (child1); free (child2); } else buffer = strdup (node->term.text); return buffer; } _ATEOF cat >test-input <<'_ATEOF' z + q; T x; T x = y; x = y; T (x) + y; T (x); T (y) = z + q; T (y y) = z + q; z + q; @ This is total garbage, but it should be ignored. _ATEOF $at_traceoff echo "cxx-type.at:434: bison -o types.c types.y" echo cxx-type.at:434 >$at_check_line_file ( $at_traceon; bison -o types.c types.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:434: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:434: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o types types.c \$LIBS" echo cxx-type.at:434 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o types types.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:434: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:436: \$PREPARSER ./types test-input" echo cxx-type.at:436 >$at_check_line_file ( $at_traceon; $PREPARSER ./types test-input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "3.0-3.5: +(z,q) 5.0-5.3: (T,x) 7.0-7.7: (T,x,y) 9.0-9.5: =(x,y) 11.0-11.9: +((x,T),y) 13.0-13.5: (T,x) 15.0-15.13: (T,y,+(z,q)) 17.0-17.15: 19.0-19.5: +(z,q) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:436: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 137 ) # 137. cxx-type.at:439: GLR: Merge conflicting parses, impure, no locations at_setup_line='cxx-type.at:439' at_desc='GLR: Merge conflicting parses, impure, no locations' $at_quiet $ECHO_N "137: GLR: Merge conflicting parses, impure, no locations$ECHO_C" at_xfail=no ( echo "137. cxx-type.at:439: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >types.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Simplified C++ Type and Expression Grammar. */ %{ #include union Node { struct { int isNterm; int parents; } nodeInfo; struct { int isNterm; /* 1 */ int parents; char const *form; union Node *children[3]; } nterm; struct { int isNterm; /* 0 */ int parents; char *text; } term; }; typedef union Node Node; static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); #define YYSTYPE Node * static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1); #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 struct YYLTYPE; #if YYPURE # if YYLSP_NEEDED # define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp # define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s # else # define LEX_PARAMETERS YYSTYPE *lvalp # endif #endif #ifndef LEX_PARAMETERS # define LEX_PARAMETERS void #endif #ifndef ERROR_PARAMETERS # define ERROR_PARAMETERS char const *s #endif int yylex (LEX_PARAMETERS); void yyerror (ERROR_PARAMETERS); %} %token TYPENAME ID %right '=' %left '+' %glr-parser %destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %% prog : | prog stmt { char *output; output = node_to_string ($2); printf ("%s\n", output); free (output); free_node ($2); } ; stmt : expr ';' %merge { $$ = $1; } | decl %merge | error ';' { $$ = new_nterm ("", 0, 0, 0); } | '@' { YYACCEPT; } ; expr : ID | TYPENAME '(' expr ')' { $$ = new_nterm ("(%s,%s)", $3, $1, 0); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", $1, $3, 0); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", $1, $3, 0); } ; decl : TYPENAME declarator ';' { $$ = new_nterm ("(%s,%s)", $1, $2, 0); } | TYPENAME declarator '=' expr ';' { $$ = new_nterm ("(%s,%s,%s)", $1, $2, $4); } ; declarator : ID | '(' declarator ')' { $$ = $2; } ; %% #include #include #include #include int main (int argc, char **argv) { if (argc != 2) abort (); if (!freopen (argv[1], "r", stdin)) return 3; return yyparse (); } int yylex (LEX_PARAMETERS) { char buffer[256]; int c; unsigned int i; static int lineNum = 1; static int colNum = 0; #if YYPURE # undef yylloc # define yylloc (*llocp) # undef yylval # define yylval (*lvalp) #endif while (1) { c = getchar (); switch (c) { case EOF: return 0; case '\t': colNum = (colNum + 7) & ~7; break; case ' ': case '\f': colNum += 1; break; case '\n': lineNum += 1; colNum = 0; break; default: { int tok; #if YYLSP_NEEDED yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_column = colNum; #endif if (isalpha (c)) { i = 0; do { buffer[i++] = c; colNum += 1; if (i == sizeof buffer - 1) abort (); c = getchar (); } while (isalnum (c) || c == '_'); ungetc (c, stdin); buffer[i++] = 0; tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = new_term (strcpy ((char *) malloc (i), buffer)); } else { colNum += 1; tok = c; yylval = 0; } #if YYLSP_NEEDED yylloc.last_column = colNum-1; #endif return tok; } } } } void yyerror (ERROR_PARAMETERS) { #if YYPURE && YYLSP_NEEDED /* Pacify GCC by using llocp. */ if (! llocp) abort (); #endif fprintf (stderr, "%s\n", s); } static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { Node *node = (Node *) malloc (sizeof (Node)); node->nterm.isNterm = 1; node->nterm.parents = 0; node->nterm.form = form; node->nterm.children[0] = child0; if (child0) child0->nodeInfo.parents += 1; node->nterm.children[1] = child1; if (child1) child1->nodeInfo.parents += 1; node->nterm.children[2] = child2; if (child2) child2->nodeInfo.parents += 1; return node; } static Node * new_term (char *text) { Node *node = (Node *) malloc (sizeof (Node)); node->term.isNterm = 0; node->term.parents = 0; node->term.text = text; return node; } static void free_node (Node *node) { if (!node) return; node->nodeInfo.parents -= 1; /* Free only if 0 (last parent) or -1 (no parents). */ if (node->nodeInfo.parents > 0) return; if (node->nodeInfo.isNterm == 1) { free_node (node->nterm.children[0]); free_node (node->nterm.children[1]); free_node (node->nterm.children[2]); } else free (node->term.text); free (node); } static char * node_to_string (Node *node) { char *child0; char *child1; char *child2; char *buffer; if (!node) { buffer = (char *) malloc (1); buffer[0] = 0; } else if (node->nodeInfo.isNterm == 1) { child0 = node_to_string (node->nterm.children[0]); child1 = node_to_string (node->nterm.children[1]); child2 = node_to_string (node->nterm.children[2]); buffer = (char *) malloc (strlen (node->nterm.form) + strlen (child0) + strlen (child1) + strlen (child2) + 1); sprintf (buffer, node->nterm.form, child0, child1, child2); free (child0); free (child1); free (child2); } else buffer = strdup (node->term.text); return buffer; } static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1) { return new_nterm ("(%s,%s)", x0, x1, 0); } _ATEOF cat >test-input <<'_ATEOF' z + q; T x; T x = y; x = y; T (x) + y; T (x); T (y) = z + q; T (y y) = z + q; z + q; @ This is total garbage, but it should be ignored. _ATEOF $at_traceoff echo "cxx-type.at:441: bison -o types.c types.y" echo cxx-type.at:441 >$at_check_line_file ( $at_traceon; bison -o types.c types.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:441: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:441: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o types types.c \$LIBS" echo cxx-type.at:441 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o types types.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:441: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:443: \$PREPARSER ./types test-input" echo cxx-type.at:443 >$at_check_line_file ( $at_traceon; $PREPARSER ./types test-input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "+(z,q) (T,x) (T,x,y) =(x,y) +((x,T),y) ((T,x),(x,T)) ((T,y,+(z,q)),=((y,T),+(z,q))) +(z,q) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:443: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 138 ) # 138. cxx-type.at:446: GLR: Merge conflicting parses, impure, locations at_setup_line='cxx-type.at:446' at_desc='GLR: Merge conflicting parses, impure, locations' $at_quiet $ECHO_N "138: GLR: Merge conflicting parses, impure, locations$ECHO_C" at_xfail=no ( echo "138. cxx-type.at:446: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >types.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Simplified C++ Type and Expression Grammar. */ %locations %{ #include union Node { struct { int isNterm; int parents; } nodeInfo; struct { int isNterm; /* 1 */ int parents; char const *form; union Node *children[3]; } nterm; struct { int isNterm; /* 0 */ int parents; char *text; } term; }; typedef union Node Node; static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); #define YYSTYPE Node * static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1); #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 struct YYLTYPE; #if YYPURE # if YYLSP_NEEDED # define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp # define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s # else # define LEX_PARAMETERS YYSTYPE *lvalp # endif #endif #ifndef LEX_PARAMETERS # define LEX_PARAMETERS void #endif #ifndef ERROR_PARAMETERS # define ERROR_PARAMETERS char const *s #endif int yylex (LEX_PARAMETERS); void yyerror (ERROR_PARAMETERS); %} %token TYPENAME ID %right '=' %left '+' %glr-parser %destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %% prog : | prog stmt { char *output; printf ("%d.%d-%d.%d: ", @2.first_line, @2.first_column, @2.last_line, @2.last_column); output = node_to_string ($2); printf ("%s\n", output); free (output); free_node ($2); } ; stmt : expr ';' %merge { $$ = $1; } | decl %merge | error ';' { $$ = new_nterm ("", 0, 0, 0); } | '@' { YYACCEPT; } ; expr : ID | TYPENAME '(' expr ')' { $$ = new_nterm ("(%s,%s)", $3, $1, 0); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", $1, $3, 0); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", $1, $3, 0); } ; decl : TYPENAME declarator ';' { $$ = new_nterm ("(%s,%s)", $1, $2, 0); } | TYPENAME declarator '=' expr ';' { $$ = new_nterm ("(%s,%s,%s)", $1, $2, $4); } ; declarator : ID | '(' declarator ')' { $$ = $2; } ; %% #include #include #include #include int main (int argc, char **argv) { if (argc != 2) abort (); if (!freopen (argv[1], "r", stdin)) return 3; return yyparse (); } int yylex (LEX_PARAMETERS) { char buffer[256]; int c; unsigned int i; static int lineNum = 1; static int colNum = 0; #if YYPURE # undef yylloc # define yylloc (*llocp) # undef yylval # define yylval (*lvalp) #endif while (1) { c = getchar (); switch (c) { case EOF: return 0; case '\t': colNum = (colNum + 7) & ~7; break; case ' ': case '\f': colNum += 1; break; case '\n': lineNum += 1; colNum = 0; break; default: { int tok; #if YYLSP_NEEDED yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_column = colNum; #endif if (isalpha (c)) { i = 0; do { buffer[i++] = c; colNum += 1; if (i == sizeof buffer - 1) abort (); c = getchar (); } while (isalnum (c) || c == '_'); ungetc (c, stdin); buffer[i++] = 0; tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = new_term (strcpy ((char *) malloc (i), buffer)); } else { colNum += 1; tok = c; yylval = 0; } #if YYLSP_NEEDED yylloc.last_column = colNum-1; #endif return tok; } } } } void yyerror (ERROR_PARAMETERS) { #if YYPURE && YYLSP_NEEDED /* Pacify GCC by using llocp. */ if (! llocp) abort (); #endif fprintf (stderr, "%s\n", s); } static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { Node *node = (Node *) malloc (sizeof (Node)); node->nterm.isNterm = 1; node->nterm.parents = 0; node->nterm.form = form; node->nterm.children[0] = child0; if (child0) child0->nodeInfo.parents += 1; node->nterm.children[1] = child1; if (child1) child1->nodeInfo.parents += 1; node->nterm.children[2] = child2; if (child2) child2->nodeInfo.parents += 1; return node; } static Node * new_term (char *text) { Node *node = (Node *) malloc (sizeof (Node)); node->term.isNterm = 0; node->term.parents = 0; node->term.text = text; return node; } static void free_node (Node *node) { if (!node) return; node->nodeInfo.parents -= 1; /* Free only if 0 (last parent) or -1 (no parents). */ if (node->nodeInfo.parents > 0) return; if (node->nodeInfo.isNterm == 1) { free_node (node->nterm.children[0]); free_node (node->nterm.children[1]); free_node (node->nterm.children[2]); } else free (node->term.text); free (node); } static char * node_to_string (Node *node) { char *child0; char *child1; char *child2; char *buffer; if (!node) { buffer = (char *) malloc (1); buffer[0] = 0; } else if (node->nodeInfo.isNterm == 1) { child0 = node_to_string (node->nterm.children[0]); child1 = node_to_string (node->nterm.children[1]); child2 = node_to_string (node->nterm.children[2]); buffer = (char *) malloc (strlen (node->nterm.form) + strlen (child0) + strlen (child1) + strlen (child2) + 1); sprintf (buffer, node->nterm.form, child0, child1, child2); free (child0); free (child1); free (child2); } else buffer = strdup (node->term.text); return buffer; } static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1) { return new_nterm ("(%s,%s)", x0, x1, 0); } _ATEOF cat >test-input <<'_ATEOF' z + q; T x; T x = y; x = y; T (x) + y; T (x); T (y) = z + q; T (y y) = z + q; z + q; @ This is total garbage, but it should be ignored. _ATEOF $at_traceoff echo "cxx-type.at:448: bison -o types.c types.y" echo cxx-type.at:448 >$at_check_line_file ( $at_traceon; bison -o types.c types.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:448: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:448: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o types types.c \$LIBS" echo cxx-type.at:448 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o types types.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:448: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:450: \$PREPARSER ./types test-input" echo cxx-type.at:450 >$at_check_line_file ( $at_traceon; $PREPARSER ./types test-input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "3.0-3.5: +(z,q) 5.0-5.3: (T,x) 7.0-7.7: (T,x,y) 9.0-9.5: =(x,y) 11.0-11.9: +((x,T),y) 13.0-13.5: ((T,x),(x,T)) 15.0-15.13: ((T,y,+(z,q)),=((y,T),+(z,q))) 17.0-17.15: 19.0-19.5: +(z,q) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:450: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 139 ) # 139. cxx-type.at:453: GLR: Merge conflicting parses, pure, no locations at_setup_line='cxx-type.at:453' at_desc='GLR: Merge conflicting parses, pure, no locations' $at_quiet $ECHO_N "139: GLR: Merge conflicting parses, pure, no locations$ECHO_C" at_xfail=no ( echo "139. cxx-type.at:453: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >types.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Simplified C++ Type and Expression Grammar. */ %pure-parser %{ #include union Node { struct { int isNterm; int parents; } nodeInfo; struct { int isNterm; /* 1 */ int parents; char const *form; union Node *children[3]; } nterm; struct { int isNterm; /* 0 */ int parents; char *text; } term; }; typedef union Node Node; static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); #define YYSTYPE Node * static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1); #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 struct YYLTYPE; #if YYPURE # if YYLSP_NEEDED # define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp # define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s # else # define LEX_PARAMETERS YYSTYPE *lvalp # endif #endif #ifndef LEX_PARAMETERS # define LEX_PARAMETERS void #endif #ifndef ERROR_PARAMETERS # define ERROR_PARAMETERS char const *s #endif int yylex (LEX_PARAMETERS); void yyerror (ERROR_PARAMETERS); %} %token TYPENAME ID %right '=' %left '+' %glr-parser %destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %% prog : | prog stmt { char *output; output = node_to_string ($2); printf ("%s\n", output); free (output); free_node ($2); } ; stmt : expr ';' %merge { $$ = $1; } | decl %merge | error ';' { $$ = new_nterm ("", 0, 0, 0); } | '@' { YYACCEPT; } ; expr : ID | TYPENAME '(' expr ')' { $$ = new_nterm ("(%s,%s)", $3, $1, 0); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", $1, $3, 0); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", $1, $3, 0); } ; decl : TYPENAME declarator ';' { $$ = new_nterm ("(%s,%s)", $1, $2, 0); } | TYPENAME declarator '=' expr ';' { $$ = new_nterm ("(%s,%s,%s)", $1, $2, $4); } ; declarator : ID | '(' declarator ')' { $$ = $2; } ; %% #include #include #include #include int main (int argc, char **argv) { if (argc != 2) abort (); if (!freopen (argv[1], "r", stdin)) return 3; return yyparse (); } int yylex (LEX_PARAMETERS) { char buffer[256]; int c; unsigned int i; static int lineNum = 1; static int colNum = 0; #if YYPURE # undef yylloc # define yylloc (*llocp) # undef yylval # define yylval (*lvalp) #endif while (1) { c = getchar (); switch (c) { case EOF: return 0; case '\t': colNum = (colNum + 7) & ~7; break; case ' ': case '\f': colNum += 1; break; case '\n': lineNum += 1; colNum = 0; break; default: { int tok; #if YYLSP_NEEDED yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_column = colNum; #endif if (isalpha (c)) { i = 0; do { buffer[i++] = c; colNum += 1; if (i == sizeof buffer - 1) abort (); c = getchar (); } while (isalnum (c) || c == '_'); ungetc (c, stdin); buffer[i++] = 0; tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = new_term (strcpy ((char *) malloc (i), buffer)); } else { colNum += 1; tok = c; yylval = 0; } #if YYLSP_NEEDED yylloc.last_column = colNum-1; #endif return tok; } } } } void yyerror (ERROR_PARAMETERS) { #if YYPURE && YYLSP_NEEDED /* Pacify GCC by using llocp. */ if (! llocp) abort (); #endif fprintf (stderr, "%s\n", s); } static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { Node *node = (Node *) malloc (sizeof (Node)); node->nterm.isNterm = 1; node->nterm.parents = 0; node->nterm.form = form; node->nterm.children[0] = child0; if (child0) child0->nodeInfo.parents += 1; node->nterm.children[1] = child1; if (child1) child1->nodeInfo.parents += 1; node->nterm.children[2] = child2; if (child2) child2->nodeInfo.parents += 1; return node; } static Node * new_term (char *text) { Node *node = (Node *) malloc (sizeof (Node)); node->term.isNterm = 0; node->term.parents = 0; node->term.text = text; return node; } static void free_node (Node *node) { if (!node) return; node->nodeInfo.parents -= 1; /* Free only if 0 (last parent) or -1 (no parents). */ if (node->nodeInfo.parents > 0) return; if (node->nodeInfo.isNterm == 1) { free_node (node->nterm.children[0]); free_node (node->nterm.children[1]); free_node (node->nterm.children[2]); } else free (node->term.text); free (node); } static char * node_to_string (Node *node) { char *child0; char *child1; char *child2; char *buffer; if (!node) { buffer = (char *) malloc (1); buffer[0] = 0; } else if (node->nodeInfo.isNterm == 1) { child0 = node_to_string (node->nterm.children[0]); child1 = node_to_string (node->nterm.children[1]); child2 = node_to_string (node->nterm.children[2]); buffer = (char *) malloc (strlen (node->nterm.form) + strlen (child0) + strlen (child1) + strlen (child2) + 1); sprintf (buffer, node->nterm.form, child0, child1, child2); free (child0); free (child1); free (child2); } else buffer = strdup (node->term.text); return buffer; } static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1) { return new_nterm ("(%s,%s)", x0, x1, 0); } _ATEOF cat >test-input <<'_ATEOF' z + q; T x; T x = y; x = y; T (x) + y; T (x); T (y) = z + q; T (y y) = z + q; z + q; @ This is total garbage, but it should be ignored. _ATEOF $at_traceoff echo "cxx-type.at:455: bison -o types.c types.y" echo cxx-type.at:455 >$at_check_line_file ( $at_traceon; bison -o types.c types.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:455: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:455: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o types types.c \$LIBS" echo cxx-type.at:455 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o types types.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:455: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:457: \$PREPARSER ./types test-input" echo cxx-type.at:457 >$at_check_line_file ( $at_traceon; $PREPARSER ./types test-input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "+(z,q) (T,x) (T,x,y) =(x,y) +((x,T),y) ((T,x),(x,T)) ((T,y,+(z,q)),=((y,T),+(z,q))) +(z,q) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:457: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 140 ) # 140. cxx-type.at:459: GLR: Merge conflicting parses, pure, locations at_setup_line='cxx-type.at:459' at_desc='GLR: Merge conflicting parses, pure, locations' $at_quiet $ECHO_N "140: GLR: Merge conflicting parses, pure, locations$ECHO_C" at_xfail=no ( echo "140. cxx-type.at:459: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >types.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Simplified C++ Type and Expression Grammar. */ %pure-parser %locations %{ #include union Node { struct { int isNterm; int parents; } nodeInfo; struct { int isNterm; /* 1 */ int parents; char const *form; union Node *children[3]; } nterm; struct { int isNterm; /* 0 */ int parents; char *text; } term; }; typedef union Node Node; static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); #define YYSTYPE Node * static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1); #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 struct YYLTYPE; #if YYPURE # if YYLSP_NEEDED # define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp # define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s # else # define LEX_PARAMETERS YYSTYPE *lvalp # endif #endif #ifndef LEX_PARAMETERS # define LEX_PARAMETERS void #endif #ifndef ERROR_PARAMETERS # define ERROR_PARAMETERS char const *s #endif int yylex (LEX_PARAMETERS); void yyerror (ERROR_PARAMETERS); %} %token TYPENAME ID %right '=' %left '+' %glr-parser %destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %% prog : | prog stmt { char *output; printf ("%d.%d-%d.%d: ", @2.first_line, @2.first_column, @2.last_line, @2.last_column); output = node_to_string ($2); printf ("%s\n", output); free (output); free_node ($2); } ; stmt : expr ';' %merge { $$ = $1; } | decl %merge | error ';' { $$ = new_nterm ("", 0, 0, 0); } | '@' { YYACCEPT; } ; expr : ID | TYPENAME '(' expr ')' { $$ = new_nterm ("(%s,%s)", $3, $1, 0); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", $1, $3, 0); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", $1, $3, 0); } ; decl : TYPENAME declarator ';' { $$ = new_nterm ("(%s,%s)", $1, $2, 0); } | TYPENAME declarator '=' expr ';' { $$ = new_nterm ("(%s,%s,%s)", $1, $2, $4); } ; declarator : ID | '(' declarator ')' { $$ = $2; } ; %% #include #include #include #include int main (int argc, char **argv) { if (argc != 2) abort (); if (!freopen (argv[1], "r", stdin)) return 3; return yyparse (); } int yylex (LEX_PARAMETERS) { char buffer[256]; int c; unsigned int i; static int lineNum = 1; static int colNum = 0; #if YYPURE # undef yylloc # define yylloc (*llocp) # undef yylval # define yylval (*lvalp) #endif while (1) { c = getchar (); switch (c) { case EOF: return 0; case '\t': colNum = (colNum + 7) & ~7; break; case ' ': case '\f': colNum += 1; break; case '\n': lineNum += 1; colNum = 0; break; default: { int tok; #if YYLSP_NEEDED yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_column = colNum; #endif if (isalpha (c)) { i = 0; do { buffer[i++] = c; colNum += 1; if (i == sizeof buffer - 1) abort (); c = getchar (); } while (isalnum (c) || c == '_'); ungetc (c, stdin); buffer[i++] = 0; tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = new_term (strcpy ((char *) malloc (i), buffer)); } else { colNum += 1; tok = c; yylval = 0; } #if YYLSP_NEEDED yylloc.last_column = colNum-1; #endif return tok; } } } } void yyerror (ERROR_PARAMETERS) { #if YYPURE && YYLSP_NEEDED /* Pacify GCC by using llocp. */ if (! llocp) abort (); #endif fprintf (stderr, "%s\n", s); } static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { Node *node = (Node *) malloc (sizeof (Node)); node->nterm.isNterm = 1; node->nterm.parents = 0; node->nterm.form = form; node->nterm.children[0] = child0; if (child0) child0->nodeInfo.parents += 1; node->nterm.children[1] = child1; if (child1) child1->nodeInfo.parents += 1; node->nterm.children[2] = child2; if (child2) child2->nodeInfo.parents += 1; return node; } static Node * new_term (char *text) { Node *node = (Node *) malloc (sizeof (Node)); node->term.isNterm = 0; node->term.parents = 0; node->term.text = text; return node; } static void free_node (Node *node) { if (!node) return; node->nodeInfo.parents -= 1; /* Free only if 0 (last parent) or -1 (no parents). */ if (node->nodeInfo.parents > 0) return; if (node->nodeInfo.isNterm == 1) { free_node (node->nterm.children[0]); free_node (node->nterm.children[1]); free_node (node->nterm.children[2]); } else free (node->term.text); free (node); } static char * node_to_string (Node *node) { char *child0; char *child1; char *child2; char *buffer; if (!node) { buffer = (char *) malloc (1); buffer[0] = 0; } else if (node->nodeInfo.isNterm == 1) { child0 = node_to_string (node->nterm.children[0]); child1 = node_to_string (node->nterm.children[1]); child2 = node_to_string (node->nterm.children[2]); buffer = (char *) malloc (strlen (node->nterm.form) + strlen (child0) + strlen (child1) + strlen (child2) + 1); sprintf (buffer, node->nterm.form, child0, child1, child2); free (child0); free (child1); free (child2); } else buffer = strdup (node->term.text); return buffer; } static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1) { return new_nterm ("(%s,%s)", x0, x1, 0); } _ATEOF cat >test-input <<'_ATEOF' z + q; T x; T x = y; x = y; T (x) + y; T (x); T (y) = z + q; T (y y) = z + q; z + q; @ This is total garbage, but it should be ignored. _ATEOF $at_traceoff echo "cxx-type.at:461: bison -o types.c types.y" echo cxx-type.at:461 >$at_check_line_file ( $at_traceon; bison -o types.c types.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:461: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:461: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o types types.c \$LIBS" echo cxx-type.at:461 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o types types.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:461: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:463: \$PREPARSER ./types test-input" echo cxx-type.at:463 >$at_check_line_file ( $at_traceon; $PREPARSER ./types test-input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "3.0-3.5: +(z,q) 5.0-5.3: (T,x) 7.0-7.7: (T,x,y) 9.0-9.5: =(x,y) 11.0-11.9: +((x,T),y) 13.0-13.5: ((T,x),(x,T)) 15.0-15.13: ((T,y,+(z,q)),=((y,T),+(z,q))) 17.0-17.15: 19.0-19.5: +(z,q) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:463: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 141 ) # 141. cxx-type.at:466: GLR: Verbose messages, resolve ambiguity, impure, no locations at_setup_line='cxx-type.at:466' at_desc='GLR: Verbose messages, resolve ambiguity, impure, no locations' $at_quiet $ECHO_N "141: GLR: Verbose messages, resolve ambiguity, impure, no locations$ECHO_C" at_xfail=no ( echo "141. cxx-type.at:466: testing ..." $at_traceon # Using yacc.c? # yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror always sees the locations (when activated), except if # yacc & pure & !param. # The interface is pure: either because %pure-parser, or because we # are using the C++ parsers. cat >types.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Simplified C++ Type and Expression Grammar. */ %error-verbose %{ #include union Node { struct { int isNterm; int parents; } nodeInfo; struct { int isNterm; /* 1 */ int parents; char const *form; union Node *children[3]; } nterm; struct { int isNterm; /* 0 */ int parents; char *text; } term; }; typedef union Node Node; static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); #define YYSTYPE Node * static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1); #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 struct YYLTYPE; #if YYPURE # if YYLSP_NEEDED # define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp # define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s # else # define LEX_PARAMETERS YYSTYPE *lvalp # endif #endif #ifndef LEX_PARAMETERS # define LEX_PARAMETERS void #endif #ifndef ERROR_PARAMETERS # define ERROR_PARAMETERS char const *s #endif int yylex (LEX_PARAMETERS); void yyerror (ERROR_PARAMETERS); %} %token TYPENAME ID %right '=' %left '+' %glr-parser %destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %% prog : | prog stmt { char *output; output = node_to_string ($2); printf ("%s\n", output); free (output); free_node ($2); } ; stmt : expr ';' %merge { $$ = $1; } | decl %merge | error ';' { $$ = new_nterm ("", 0, 0, 0); } | '@' { YYACCEPT; } ; expr : ID | TYPENAME '(' expr ')' { $$ = new_nterm ("(%s,%s)", $3, $1, 0); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", $1, $3, 0); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", $1, $3, 0); } ; decl : TYPENAME declarator ';' { $$ = new_nterm ("(%s,%s)", $1, $2, 0); } | TYPENAME declarator '=' expr ';' { $$ = new_nterm ("(%s,%s,%s)", $1, $2, $4); } ; declarator : ID | '(' declarator ')' { $$ = $2; } ; %% #include #include #include #include int main (int argc, char **argv) { if (argc != 2) abort (); if (!freopen (argv[1], "r", stdin)) return 3; return yyparse (); } int yylex (LEX_PARAMETERS) { char buffer[256]; int c; unsigned int i; static int lineNum = 1; static int colNum = 0; #if YYPURE # undef yylloc # define yylloc (*llocp) # undef yylval # define yylval (*lvalp) #endif while (1) { c = getchar (); switch (c) { case EOF: return 0; case '\t': colNum = (colNum + 7) & ~7; break; case ' ': case '\f': colNum += 1; break; case '\n': lineNum += 1; colNum = 0; break; default: { int tok; #if YYLSP_NEEDED yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_column = colNum; #endif if (isalpha (c)) { i = 0; do { buffer[i++] = c; colNum += 1; if (i == sizeof buffer - 1) abort (); c = getchar (); } while (isalnum (c) || c == '_'); ungetc (c, stdin); buffer[i++] = 0; tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = new_term (strcpy ((char *) malloc (i), buffer)); } else { colNum += 1; tok = c; yylval = 0; } #if YYLSP_NEEDED yylloc.last_column = colNum-1; #endif return tok; } } } } void yyerror (ERROR_PARAMETERS) { #if YYPURE && YYLSP_NEEDED /* Pacify GCC by using llocp. */ if (! llocp) abort (); #endif fprintf (stderr, "%s\n", s); } static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { Node *node = (Node *) malloc (sizeof (Node)); node->nterm.isNterm = 1; node->nterm.parents = 0; node->nterm.form = form; node->nterm.children[0] = child0; if (child0) child0->nodeInfo.parents += 1; node->nterm.children[1] = child1; if (child1) child1->nodeInfo.parents += 1; node->nterm.children[2] = child2; if (child2) child2->nodeInfo.parents += 1; return node; } static Node * new_term (char *text) { Node *node = (Node *) malloc (sizeof (Node)); node->term.isNterm = 0; node->term.parents = 0; node->term.text = text; return node; } static void free_node (Node *node) { if (!node) return; node->nodeInfo.parents -= 1; /* Free only if 0 (last parent) or -1 (no parents). */ if (node->nodeInfo.parents > 0) return; if (node->nodeInfo.isNterm == 1) { free_node (node->nterm.children[0]); free_node (node->nterm.children[1]); free_node (node->nterm.children[2]); } else free (node->term.text); free (node); } static char * node_to_string (Node *node) { char *child0; char *child1; char *child2; char *buffer; if (!node) { buffer = (char *) malloc (1); buffer[0] = 0; } else if (node->nodeInfo.isNterm == 1) { child0 = node_to_string (node->nterm.children[0]); child1 = node_to_string (node->nterm.children[1]); child2 = node_to_string (node->nterm.children[2]); buffer = (char *) malloc (strlen (node->nterm.form) + strlen (child0) + strlen (child1) + strlen (child2) + 1); sprintf (buffer, node->nterm.form, child0, child1, child2); free (child0); free (child1); free (child2); } else buffer = strdup (node->term.text); return buffer; } static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1) { return new_nterm ("(%s,%s)", x0, x1, 0); } _ATEOF cat >test-input <<'_ATEOF' z + q; T x; T x = y; x = y; T (x) + y; T (x); T (y) = z + q; T (y y) = z + q; z + q; @ This is total garbage, but it should be ignored. _ATEOF $at_traceoff echo "cxx-type.at:468: bison -o types.c types.y" echo cxx-type.at:468 >$at_check_line_file ( $at_traceon; bison -o types.c types.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:468: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:468: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o types types.c \$LIBS" echo cxx-type.at:468 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o types types.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:468: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "cxx-type.at:470: \$PREPARSER ./types test-input" echo cxx-type.at:470 >$at_check_line_file ( $at_traceon; $PREPARSER ./types test-input ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error, unexpected ID, expecting '=' or '+' or ')' " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "+(z,q) (T,x) (T,x,y) =(x,y) +((x,T),y) ((T,x),(x,T)) ((T,y,+(z,q)),=((y,T),+(z,q))) +(z,q) " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "cxx-type.at:470: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; banner-18 ) # Banner 18. glr-regression.at:19 cat <<\_ATEOF GLR Regression Tests _ATEOF ;; 142 ) # 142. glr-regression.at:25: Badly Collapsed GLR States at_setup_line='glr-regression.at:25' at_desc='Badly Collapsed GLR States' $at_quiet $ECHO_N "142: Badly Collapsed GLR States $ECHO_C" at_xfail=no ( echo "142. glr-regression.at:25: testing ..." $at_traceon cat >glr-regr1.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Regression Test: Improper state compression */ /* Reported by Scott McPeak */ %{ #include #define YYSTYPE int static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1); int yylex (void); void yyerror (char const *msg); %} %glr-parser /* -------- productions ------ */ %% StartSymbol: E { $$=0; } %merge ; E: E 'P' E { $$=1; printf("E -> E 'P' E\n"); } %merge | 'B' { $$=2; printf("E -> 'B'\n"); } %merge ; /* ---------- C code ----------- */ %% static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1) { (void) x0; (void) x1; printf ("\n"); return 0; } int main (void) { return yyparse (); } void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } int yylex (void) { for (;;) { int ch = getchar (); if (ch == EOF) return 0; else if (ch == 'B' || ch == 'P') return ch; } } _ATEOF $at_traceoff echo "glr-regression.at:96: bison -o glr-regr1.c glr-regr1.y" echo glr-regression.at:96 >$at_check_line_file ( $at_traceon; bison -o glr-regr1.c glr-regr1.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr1.y: conflicts: 1 shift/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:96: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:97: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr1 glr-regr1.c \$LIBS" echo glr-regression.at:97 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr1 glr-regr1.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:97: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:108: echo BPBPB | ./glr-regr1" echo glr-regression.at:108 >$at_check_line_file ( $at_traceon; echo BPBPB | ./glr-regr1 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "E -> 'B' E -> 'B' E -> E 'P' E E -> 'B' E -> E 'P' E E -> 'B' E -> E 'P' E E -> E 'P' E " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:108: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 143 ) # 143. glr-regression.at:116: Improper handling of embedded actions and dollar(-N) in GLR parsers at_setup_line='glr-regression.at:116' at_desc='Improper handling of embedded actions and dollar(-N) in GLR parsers' $at_quiet $ECHO_N "143: Improper handling of embedded actions and dollar(-N) in GLR parsers$ECHO_C" at_xfail=no ( echo "143. glr-regression.at:116: testing ..." $at_traceon cat >glr-regr2a.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Regression Test: Improper handling of embedded actions and $-N */ /* Reported by S. Eken */ %{ #define YYSTYPE char * #include #include #include #include int yylex (void); void yyerror (char const *); %} %glr-parser %% command: 's' var 't' { printf ("Variable: '%s'\n", $2); } 'v' 'x' 'q' { free ($2); } | 's' var_list 't' 'e' { printf ("Varlist: '%s'\n", $2); free ($2); } | 's' var 't' var_printer 'x' { free ($2); } ; var: 'V' { $$ = $1; } ; var_list: var { $$ = $1; } | var ',' var_list { char *s = (char *) realloc ($1, strlen ($1) + 1 + strlen ($3) + 1); strcat (s, ","); strcat (s, $3); free ($3); $$ = s; } ; var_printer: 'v' { printf ("Variable: '%s'\n", $-1); } %% FILE *input = NULL; int yylex (void) { char buf[50]; char *s; switch (fscanf (input, " %1[a-z,]", buf)) { case 1: return buf[0]; case EOF: return 0; default: break; } if (fscanf (input, "%49s", buf) != 1) return 0; if (sizeof buf - 1 <= strlen (buf)) abort (); s = (char *) malloc (strlen (buf) + 1); strcpy (s, buf); yylval = s; return 'V'; } void yyerror (char const *s) { printf ("%s\n", s); } int main (int argc, char **argv) { input = stdin; if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3; return yyparse (); } _ATEOF $at_traceoff echo "glr-regression.at:212: bison -o glr-regr2a.c glr-regr2a.y" echo glr-regression.at:212 >$at_check_line_file ( $at_traceon; bison -o glr-regr2a.c glr-regr2a.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr2a.y: conflicts: 2 shift/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:212: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:213: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr2a glr-regr2a.c \$LIBS" echo glr-regression.at:213 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr2a glr-regr2a.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:213: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:217: echo s VARIABLE_1 t v x q | ./glr-regr2a" echo glr-regression.at:217 >$at_check_line_file ( $at_traceon; echo s VARIABLE_1 t v x q | ./glr-regr2a ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Variable: 'VARIABLE_1' " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:217: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:220: echo s VARIABLE_1 , ANOTHER_VARIABLE_2 t e | ./glr-regr2a" echo glr-regression.at:220 >$at_check_line_file ( $at_traceon; echo s VARIABLE_1 , ANOTHER_VARIABLE_2 t e | ./glr-regr2a ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Varlist: 'VARIABLE_1,ANOTHER_VARIABLE_2' " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:220: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:223: echo s VARIABLE_3 t v x | ./glr-regr2a" echo glr-regression.at:223 >$at_check_line_file ( $at_traceon; echo s VARIABLE_3 t v x | ./glr-regr2a ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Variable: 'VARIABLE_3' " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:223: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 144 ) # 144. glr-regression.at:232: Improper merging of GLR delayed action sets at_setup_line='glr-regression.at:232' at_desc='Improper merging of GLR delayed action sets' $at_quiet $ECHO_N "144: Improper merging of GLR delayed action sets $ECHO_C" at_xfail=no ( echo "144. glr-regression.at:232: testing ..." $at_traceon cat >glr-regr3.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Regression Test: Improper merging of GLR delayed action sets. */ /* Reported by M. Rosien */ %{ #include #include static int MergeRule (int x0, int x1); static void yyerror (char const * s); int yylex (void); #define RULE(x) (1 << (x)) %} %glr-parser %token BAD_CHAR %token P1 P2 T1 T2 T3 T4 O1 O2 %% S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); } ; NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge ; NT2 : NT1 { $$ = RULE(3); } %merge | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge ; NT3 : T3 { $$ = RULE(5); } %merge | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge ; NT4 : NT3 { $$ = RULE(7); } %merge | NT2 { $$ = RULE(8); } %merge | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge ; NT5 : NT4 { $$ = RULE(10); } %merge ; NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge | NT5 { $$ = RULE(12) | $1; } %merge ; %% static int MergeRule (int x0, int x1) { return x0 | x1; } static void yyerror(char const * s) { fprintf(stderr,"error: %s\n",s); } FILE *input = NULL; int P[] = { P1, P2 }; int O[] = { O1, O2 }; int T[] = { T1, T2, T3, T4 }; int yylex (void) { char inp[3]; if (fscanf (input, "%2s", inp) == EOF) return 0; switch (inp[0]) { case 'p': return P[inp[1] - '1']; case 't': return T[inp[1] - '1']; case 'o': return O[inp[1] - '1']; } return BAD_CHAR; } int main(int argc, char* argv[]) { input = stdin; if (argc == 2 && !(input = fopen (argv[1], "r"))) return 3; return yyparse (); } _ATEOF $at_traceoff echo "glr-regression.at:322: bison -o glr-regr3.c glr-regr3.y" echo glr-regression.at:322 >$at_check_line_file ( $at_traceon; bison -o glr-regr3.c glr-regr3.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:322: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:323: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr3 glr-regr3.c \$LIBS" echo glr-regression.at:323 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr3 glr-regr3.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:323: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:327: echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3" echo glr-regression.at:327 >$at_check_line_file ( $at_traceon; echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "Result: 1c04 " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:327: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 145 ) # 145. glr-regression.at:337: Duplicate representation of merged trees at_setup_line='glr-regression.at:337' at_desc='Duplicate representation of merged trees' $at_quiet $ECHO_N "145: Duplicate representation of merged trees $ECHO_C" at_xfail=no ( echo "145. glr-regression.at:337: testing ..." $at_traceon cat >glr-regr4.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %union { char *ptr; } %type S A A1 A2 B %glr-parser %{ #include #include #include static char *merge (YYSTYPE, YYSTYPE); static char *make_value (char const *, char const *); static void yyerror (char const *); static int yylex (void); %} %% tree: S { printf ("%s\n", $1); } ; S: A %merge { $$ = make_value ("S", $1); } | B %merge { $$ = make_value ("S", $1); } ; A: A1 %merge { $$ = make_value ("A", $1); } | A2 %merge { $$ = make_value ("A", $1); } ; A1: 'a' { $$ = make_value ("A1", "'a'"); } ; A2: 'a' { $$ = make_value ("A2", "'a'"); } ; B: 'a' { $$ = make_value ("B", "'a'"); } ; %% static int yylex (void) { static char const *input = "a"; return *input++; } int main (void) { return yyparse (); } static char * make_value (char const *parent, char const *child) { char const format[] = "%s <- %s"; char *value = (char *) malloc (strlen (parent) + strlen (child) + sizeof format); sprintf (value, format, parent, child); return value; } static char * merge (YYSTYPE s1, YYSTYPE s2) { char const format[] = "merge{ %s and %s }"; char *value = (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format); sprintf (value, format, s1.ptr, s2.ptr); return value; } static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } _ATEOF $at_traceoff echo "glr-regression.at:417: bison -o glr-regr4.c glr-regr4.y" echo glr-regression.at:417 >$at_check_line_file ( $at_traceon; bison -o glr-regr4.c glr-regr4.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr4.y: conflicts: 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:417: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:418: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr4 glr-regr4.c \$LIBS" echo glr-regression.at:418 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr4 glr-regr4.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:418: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:422: ./glr-regr4" echo glr-regression.at:422 >$at_check_line_file ( $at_traceon; ./glr-regr4 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' } " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:422: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 146 ) # 146. glr-regression.at:432: User destructor for unresolved GLR semantic value at_setup_line='glr-regression.at:432' at_desc='User destructor for unresolved GLR semantic value' $at_quiet $ECHO_N "146: User destructor for unresolved GLR semantic value$ECHO_C" at_xfail=no ( echo "146. glr-regression.at:432: testing ..." $at_traceon cat >glr-regr5.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include static void yyerror (char const *); static int yylex (void); enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */ %} %glr-parser %union { int value; } %type start %destructor { if ($$ != MAGIC_VALUE) { fprintf (stderr, "Bad destructor call.\n"); exit (EXIT_FAILURE); } } start %% start: 'a' { $$ = MAGIC_VALUE; } | 'a' { $$ = MAGIC_VALUE; } ; %% static int yylex (void) { static char const *input = "a"; return *input++; } static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } int main (void) { return yyparse () != 1; } _ATEOF $at_traceoff echo "glr-regression.at:487: bison -o glr-regr5.c glr-regr5.y" echo glr-regression.at:487 >$at_check_line_file ( $at_traceon; bison -o glr-regr5.c glr-regr5.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr5.y: conflicts: 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:487: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:488: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr5 glr-regr5.c \$LIBS" echo glr-regression.at:488 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr5 glr-regr5.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:488: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:492: ./glr-regr5" echo glr-regression.at:492 >$at_check_line_file ( $at_traceon; ./glr-regr5 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax is ambiguous " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:492: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 147 ) # 147. glr-regression.at:502: User destructor after an error during a split parse at_setup_line='glr-regression.at:502' at_desc='User destructor after an error during a split parse' $at_quiet $ECHO_N "147: User destructor after an error during a split parse$ECHO_C" at_xfail=no ( echo "147. glr-regression.at:502: testing ..." $at_traceon cat >glr-regr6.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include static void yyerror (char const *); static int yylex (void); %} %glr-parser %union { int value; } %type 'a' %destructor { printf ("Destructor called.\n"); } 'a' %% start: 'a' | 'a' ; %% static int yylex (void) { static char const *input = "a"; return *input++; } static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } int main (void) { return yyparse () != 1; } _ATEOF $at_traceoff echo "glr-regression.at:549: bison -o glr-regr6.c glr-regr6.y" echo glr-regression.at:549 >$at_check_line_file ( $at_traceon; bison -o glr-regr6.c glr-regr6.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr6.y: conflicts: 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:549: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:550: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr6 glr-regr6.c \$LIBS" echo glr-regression.at:550 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr6 glr-regr6.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:550: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:556: ./glr-regr6" echo glr-regression.at:556 >$at_check_line_file ( $at_traceon; ./glr-regr6 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax is ambiguous " | $at_diff - $at_stderr || at_failed=: echo >>$at_stdout; echo "Destructor called. " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:556: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 148 ) # 148. glr-regression.at:566: Duplicated user destructor for lookahead at_setup_line='glr-regression.at:566' at_desc='Duplicated user destructor for lookahead' $at_quiet $ECHO_N "148: Duplicated user destructor for lookahead $ECHO_C" at_xfail=no ( echo "148. glr-regression.at:566: testing ..." $at_traceon cat >glr-regr7.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include static void yyerror (char const *); static int yylex (void); #define YYSTACKEXPANDABLE 0 %} %glr-parser %union { int *count; } %type 'a' %destructor { if ((*$$)++) fprintf (stderr, "Destructor called on same value twice.\n"); } 'a' %% start: stack1 start | stack2 start | /* empty */ ; stack1: 'a' ; stack2: 'a' ; %% static int yylex (void) { yylval.count = (int *) malloc (sizeof (int)); if (!yylval.count) { fprintf (stderr, "Test inconclusive.\n"); exit (EXIT_FAILURE); } *yylval.count = 0; return 'a'; } static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } int main (void) { return yyparse (); } _ATEOF $at_traceoff echo "glr-regression.at:627: bison -o glr-regr7.c glr-regr7.y" echo glr-regression.at:627 >$at_check_line_file ( $at_traceon; bison -o glr-regr7.c glr-regr7.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr7.y: conflicts: 2 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:627: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:628: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr7 glr-regr7.c \$LIBS" echo glr-regression.at:628 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr7 glr-regr7.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:628: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:632: ./glr-regr7" echo glr-regression.at:632 >$at_check_line_file ( $at_traceon; ./glr-regr7 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "memory exhausted " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 2) ;; *) echo "glr-regression.at:632: exit code was $at_status, expected 2" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 149 ) # 149. glr-regression.at:644: Incorrectly initialized location for empty right-hand side in GLR at_setup_line='glr-regression.at:644' at_desc='Incorrectly initialized location for empty right-hand side in GLR' $at_quiet $ECHO_N "149: Incorrectly initialized location for empty right-hand side in GLR$ECHO_C" at_xfail=no ( echo "149. glr-regression.at:644: testing ..." $at_traceon cat >glr-regr8.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ #include #include static void yyerror (char const *); static int yylex (void); static void yyerror (char const *msg); %} %token T_CONSTANT %token T_PORT %token T_SIGNAL %glr-parser %% PortClause : T_PORT InterfaceDeclaration T_PORT { printf("%d/%d - %d/%d - %d/%d\n", @1.first_column, @1.last_column, @2.first_column, @2.last_column, @3.first_column, @3.last_column); } ; InterfaceDeclaration : OptConstantWord %dprec 1 | OptSignalWord %dprec 2 ; OptConstantWord : /* empty */ | T_CONSTANT ; OptSignalWord : /* empty */ { printf("empty: %d/%d\n", @$.first_column, @$.last_column); } | T_SIGNAL ; %% void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } static int lexIndex; int yylex (void) { lexIndex += 1; switch (lexIndex) { case 1: yylloc.first_column = 1; yylloc.last_column = 9; return T_PORT; case 2: yylloc.first_column = 13; yylloc.last_column = 17; return T_PORT; default: return 0; } } int main (void) { yyparse(); return 0; } _ATEOF $at_traceoff echo "glr-regression.at:723: bison -o glr-regr8.c glr-regr8.y" echo glr-regression.at:723 >$at_check_line_file ( $at_traceon; bison -o glr-regr8.c glr-regr8.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr8.y: conflicts: 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:723: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:724: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr8 glr-regr8.c \$LIBS" echo glr-regression.at:724 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr8 glr-regr8.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:724: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:730: ./glr-regr8" echo glr-regression.at:730 >$at_check_line_file ( $at_traceon; ./glr-regr8 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "empty: 9/9 1/9 - 9/9 - 13/17 " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:730: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 150 ) # 150. glr-regression.at:740: No users destructors if stack 0 deleted at_setup_line='glr-regression.at:740' at_desc='No users destructors if stack 0 deleted' $at_quiet $ECHO_N "150: No users destructors if stack 0 deleted $ECHO_C" at_xfail=no ( echo "150. glr-regression.at:740: testing ..." $at_traceon cat >glr-regr9.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ # include # include static void yyerror (char const *); static int yylex (void); # define YYSTACKEXPANDABLE 0 static int tokens = 0; static int destructors = 0; # define USE(Var) %} %glr-parser %union { int dummy; } %type 'a' %destructor { destructors += 1; } 'a' %% start: ambig0 'a' { destructors += 2; USE ($2); } | ambig1 start { destructors += 1; } | ambig2 start { destructors += 1; } ; ambig0: 'a' ; ambig1: 'a' ; ambig2: 'a' ; %% static int yylex (void) { tokens += 1; return 'a'; } static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } int main (void) { int exit_status; exit_status = yyparse (); if (tokens != destructors) { fprintf (stderr, "Tokens = %d, Destructors = %d\n", tokens, destructors); return 1; } return !exit_status; } _ATEOF $at_traceoff echo "glr-regression.at:806: bison -o glr-regr9.c glr-regr9.y" echo glr-regression.at:806 >$at_check_line_file ( $at_traceon; bison -o glr-regr9.c glr-regr9.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr9.y: conflicts: 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:806: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:807: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr9 glr-regr9.c \$LIBS" echo glr-regression.at:807 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr9 glr-regr9.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:807: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:811: ./glr-regr9" echo glr-regression.at:811 >$at_check_line_file ( $at_traceon; ./glr-regr9 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "memory exhausted " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:811: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 151 ) # 151. glr-regression.at:820: Corrupted semantic options if user action cuts parse at_setup_line='glr-regression.at:820' at_desc='Corrupted semantic options if user action cuts parse' $at_quiet $ECHO_N "151: Corrupted semantic options if user action cuts parse$ECHO_C" at_xfail=no ( echo "151. glr-regression.at:820: testing ..." $at_traceon cat >glr-regr10.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ # include static void yyerror (char const *); static int yylex (void); #define GARBAGE_SIZE 50 static char garbage[GARBAGE_SIZE]; %} %glr-parser %union { char *ptr; } %type start %% start: %dprec 2 { $$ = garbage; YYACCEPT; } | %dprec 1 { $$ = garbage; YYACCEPT; } ; %% static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } static int yylex (void) { return 0; } int main (void) { int i; for (i = 0; i < GARBAGE_SIZE; i+=1) garbage[i] = 108; return yyparse (); } _ATEOF $at_traceoff echo "glr-regression.at:869: bison -o glr-regr10.c glr-regr10.y" echo glr-regression.at:869 >$at_check_line_file ( $at_traceon; bison -o glr-regr10.c glr-regr10.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr10.y: conflicts: 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:869: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:870: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr10 glr-regr10.c \$LIBS" echo glr-regression.at:870 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr10 glr-regr10.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:870: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:872: ./glr-regr10" echo glr-regression.at:872 >$at_check_line_file ( $at_traceon; ./glr-regr10 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:872: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 152 ) # 152. glr-regression.at:881: Undesirable destructors if user action cuts parse at_setup_line='glr-regression.at:881' at_desc='Undesirable destructors if user action cuts parse' $at_quiet $ECHO_N "152: Undesirable destructors if user action cuts parse$ECHO_C" at_xfail=no ( echo "152. glr-regression.at:881: testing ..." $at_traceon cat >glr-regr11.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %{ # include static void yyerror (char const *); static int yylex (void); static int destructors = 0; # define USE(val) %} %glr-parser %union { int dummy; } %type 'a' %destructor { destructors += 1; } 'a' %% start: 'a' %dprec 2 { USE ($1); destructors += 1; YYACCEPT; } | 'a' %dprec 1 { USE ($1); destructors += 1; YYACCEPT; } ; %% static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } static int yylex (void) { static char const *input = "a"; return *input++; } int main (void) { int exit_status = yyparse (); if (destructors != 1) { fprintf (stderr, "Destructor calls: %d\n", destructors); return 1; } return exit_status; } _ATEOF $at_traceoff echo "glr-regression.at:935: bison -o glr-regr11.c glr-regr11.y" echo glr-regression.at:935 >$at_check_line_file ( $at_traceon; bison -o glr-regr11.c glr-regr11.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr11.y: conflicts: 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:935: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:936: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr11 glr-regr11.c \$LIBS" echo glr-regression.at:936 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr11 glr-regr11.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:936: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:938: ./glr-regr11" echo glr-regression.at:938 >$at_check_line_file ( $at_traceon; ./glr-regr11 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:938: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 153 ) # 153. glr-regression.at:947: Leaked semantic values if user action cuts parse at_setup_line='glr-regression.at:947' at_desc='Leaked semantic values if user action cuts parse' $at_quiet $ECHO_N "153: Leaked semantic values if user action cuts parse$ECHO_C" at_xfail=no ( echo "153. glr-regression.at:947: testing ..." $at_traceon cat >glr-regr12.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %glr-parser %union { int dummy; } %token PARENT_RHS_AFTER %type parent_rhs_before merged PARENT_RHS_AFTER %destructor { parent_rhs_before_value = 0; } parent_rhs_before %destructor { merged_value = 0; } merged %destructor { parent_rhs_after_value = 0; } PARENT_RHS_AFTER %{ # include static int merge (YYSTYPE, YYSTYPE); static void yyerror (char const *); static int yylex (void); static int parent_rhs_before_value = 0; static int merged_value = 0; static int parent_rhs_after_value = 0; # define USE(val) %} %% start: alt1 %dprec 1 | alt2 %dprec 2 ; alt1: PARENT_RHS_AFTER { USE ($1); parent_rhs_after_value = 0; } ; alt2: parent_rhs_before merged PARENT_RHS_AFTER { USE (($1, $2, $3)); parent_rhs_before_value = 0; merged_value = 0; parent_rhs_after_value = 0; } ; parent_rhs_before: { USE ($$); parent_rhs_before_value = 1; } ; merged: %merge { USE ($$); merged_value = 1; } | cut %merge { USE ($$); merged_value = 1; } ; cut: { YYACCEPT; } ; %% static int merge (YYSTYPE s1, YYSTYPE s2) { /* Not invoked. */ char dummy = s1.dummy + s2.dummy; return dummy; } static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } static int yylex (void) { static int const input[] = { PARENT_RHS_AFTER, 0 }; static const int *inputp = input; if (*inputp == PARENT_RHS_AFTER) parent_rhs_after_value = 1; return *inputp++; } int main (void) { int exit_status = yyparse (); if (parent_rhs_before_value) { fprintf (stderr, "`parent_rhs_before' destructor not called.\n"); exit_status = 1; } if (merged_value) { fprintf (stderr, "`merged' destructor not called.\n"); exit_status = 1; } if (parent_rhs_after_value) { fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n"); exit_status = 1; } return exit_status; } _ATEOF $at_traceoff echo "glr-regression.at:1064: bison -o glr-regr12.c glr-regr12.y" echo glr-regression.at:1064 >$at_check_line_file ( $at_traceon; bison -o glr-regr12.c glr-regr12.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1064: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1065: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr12 glr-regr12.c \$LIBS" echo glr-regression.at:1065 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr12 glr-regr12.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1065: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1067: ./glr-regr12" echo glr-regression.at:1067 >$at_check_line_file ( $at_traceon; ./glr-regr12 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1067: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 154 ) # 154. glr-regression.at:1078: Incorrect lookahead during deterministic GLR at_setup_line='glr-regression.at:1078' at_desc='Incorrect lookahead during deterministic GLR' $at_quiet $ECHO_N "154: Incorrect lookahead during deterministic GLR $ECHO_C" at_xfail=no ( echo "154. glr-regression.at:1078: testing ..." $at_traceon cat >glr-regr13.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Tests: - Defaulted state with initial yychar: yychar == YYEMPTY. - Nondefaulted state: yychar != YYEMPTY. - Defaulted state after lookahead: yychar != YYEMPTY. - Defaulted state after shift: yychar == YYEMPTY. - User action changing the lookahead. */ %{ #include static void yyerror (char const *); static int yylex (void); static void print_look_ahead (char const *); #define USE(value) %} %union { char value; } %type 'a' 'b' %glr-parser %locations %% start: defstate_init defstate_shift 'b' change_lookahead 'a' { USE ($3); print_look_ahead ("start <- defstate_init defstate_shift 'b'"); } ; defstate_init: { print_look_ahead ("defstate_init <- empty string"); } ; defstate_shift: nondefstate defstate_look 'a' { USE ($3); print_look_ahead ("defstate_shift <- nondefstate defstate_look 'a'"); } ; defstate_look: { print_look_ahead ("defstate_look <- empty string"); } ; nondefstate: { print_look_ahead ("nondefstate <- empty string"); } | 'b' { USE ($1); print_look_ahead ("nondefstate <- 'b'"); } ; change_lookahead: { yychar = 'a'; } ; %% static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } static int yylex (void) { static char const *input = "ab"; static int i = 0; yylloc.first_line = yylloc.last_line = 1; yylloc.first_column = yylloc.last_column = i + 1; yylval.value = input[i] + 'A' - 'a'; return input[i++]; } static void print_look_ahead (char const *reduction) { printf ("%s:\n yychar=", reduction); if (yychar == YYEMPTY) printf ("YYEMPTY"); else if (yychar == YYEOF) printf ("YYEOF"); else { printf ("'%c', yylval='", yychar); if (yylval.value > ' ') printf ("%c", yylval.value); printf ("', yylloc=(%d,%d),(%d,%d)", yylloc.first_line, yylloc.first_column, yylloc.last_line, yylloc.last_column); } printf ("\n"); } int main (void) { yychar = '#'; /* Not a token in the grammar. */ yylval.value = '!'; return yyparse (); } _ATEOF $at_traceoff echo "glr-regression.at:1189: bison -o glr-regr13.c glr-regr13.y" echo glr-regression.at:1189 >$at_check_line_file ( $at_traceon; bison -o glr-regr13.c glr-regr13.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1189: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1190: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr13 glr-regr13.c \$LIBS" echo glr-regression.at:1190 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr13 glr-regr13.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1190: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1203: ./glr-regr13" echo glr-regression.at:1203 >$at_check_line_file ( $at_traceon; ./glr-regr13 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "defstate_init <- empty string: yychar=YYEMPTY nondefstate <- empty string: yychar='a', yylval='A', yylloc=(1,1),(1,1) defstate_look <- empty string: yychar='a', yylval='A', yylloc=(1,1),(1,1) defstate_shift <- nondefstate defstate_look 'a': yychar=YYEMPTY start <- defstate_init defstate_shift 'b': yychar=YYEMPTY " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1203: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 155 ) # 155. glr-regression.at:1212: Incorrect lookahead during nondeterministic GLR at_setup_line='glr-regression.at:1212' at_desc='Incorrect lookahead during nondeterministic GLR' $at_quiet $ECHO_N "155: Incorrect lookahead during nondeterministic GLR$ECHO_C" at_xfail=no ( echo "155. glr-regression.at:1212: testing ..." $at_traceon cat >glr-regr14.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} /* Tests: - Conflicting actions (split-off parse, which copies lookahead need, which is necessarily yytrue) and nonconflicting actions (non-split-off parse) for nondefaulted state: yychar != YYEMPTY. - Merged deferred actions (lookahead need and RHS from different stack than the target state) and nonmerged deferred actions (same stack). - Defaulted state after lookahead: yychar != YYEMPTY. - Defaulted state after shift: yychar == YYEMPTY. - yychar != YYEMPTY but lookahead need is yyfalse (a previous stack has seen the lookahead but current stack has not). - Exceeding stack capacity (stack explosion), and thus reallocating lookahead need array. Note that it does not seem possible to see the initial yychar value during nondeterministic operation since: - In order to preserve the initial yychar, only defaulted states may be entered. - If only defaulted states are entered, there are no conflicts, so nondeterministic operation does not start. */ %union { char value; } %{ #include static void yyerror (char const *); static int yylex (void); static void print_look_ahead (char const *); static char merge (union YYSTYPE, union YYSTYPE); #define USE(value) %} %type 'a' 'b' 'c' 'd' stack_explosion %glr-parser %locations %% start: merge 'c' stack_explosion { USE ($2); USE ($3); print_look_ahead ("start <- merge 'c' stack_explosion"); } ; /* When merging the 2 deferred actions, the lookahead needs are different. */ merge: nonconflict1 'a' 'b' nonconflict2 %dprec 1 { USE ($2); USE ($3); print_look_ahead ("merge <- nonconflict1 'a' 'b' nonconflict2"); } | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 { USE ($3); USE ($5); print_look_ahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'" " defstate_shift"); } ; nonconflict1: { print_look_ahead ("nonconflict1 <- empty string"); } ; nonconflict2: { print_look_ahead ("nonconflict2 <- empty string"); } | 'a' { USE ($1); print_look_ahead ("nonconflict2 <- 'a'"); } ; conflict: { print_look_ahead ("conflict <- empty string"); } ; defstate_look: { print_look_ahead ("defstate_look <- empty string"); } ; /* yychar != YYEMPTY but lookahead need is yyfalse. */ defstate_shift: { print_look_ahead ("defstate_shift <- empty string"); } ; stack_explosion: { $$ = '\0'; } | alt1 stack_explosion %merge { $$ = $2; } | alt2 stack_explosion %merge { $$ = $2; } | alt3 stack_explosion %merge { $$ = $2; } ; alt1: 'd' no_look { USE ($1); if (yychar != 'd' && yychar != YYEOF) { fprintf (stderr, "Incorrect lookahead during stack explosion.\n"); } } ; alt2: 'd' no_look { USE ($1); if (yychar != 'd' && yychar != YYEOF) { fprintf (stderr, "Incorrect lookahead during stack explosion.\n"); } } ; alt3: 'd' no_look { USE ($1); if (yychar != 'd' && yychar != YYEOF) { fprintf (stderr, "Incorrect lookahead during stack explosion.\n"); } } ; no_look: { if (yychar != YYEMPTY) { fprintf (stderr, "Found lookahead where shouldn't during stack explosion.\n"); } } ; %% static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } static int yylex (void) { static char const *input = "abcdddd"; static int i = 0; yylloc.first_line = yylloc.last_line = 1; yylloc.first_column = yylloc.last_column = i + 1; yylval.value = input[i] + 'A' - 'a'; return input[i++]; } static void print_look_ahead (char const *reduction) { printf ("%s:\n yychar=", reduction); if (yychar == YYEMPTY) printf ("YYEMPTY"); else if (yychar == YYEOF) printf ("YYEOF"); else { printf ("'%c', yylval='", yychar); if (yylval.value > ' ') printf ("%c", yylval.value); printf ("', yylloc=(%d,%d),(%d,%d)", yylloc.first_line, yylloc.first_column, yylloc.last_line, yylloc.last_column); } printf ("\n"); } static char merge (union YYSTYPE s1, union YYSTYPE s2) { char dummy = s1.value + s2.value; return dummy; } int main (void) { yychar = '#'; /* Not a token in the grammar. */ yylval.value = '!'; return yyparse (); } _ATEOF $at_traceoff echo "glr-regression.at:1404: bison -o glr-regr14.c glr-regr14.y" echo glr-regression.at:1404 >$at_check_line_file ( $at_traceon; bison -o glr-regr14.c glr-regr14.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr14.y: conflicts: 3 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1404: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1405: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr14 glr-regr14.c \$LIBS" echo glr-regression.at:1405 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr14 glr-regr14.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1405: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1420: ./glr-regr14" echo glr-regression.at:1420 >$at_check_line_file ( $at_traceon; ./glr-regr14 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false $at_diff $at_devnull $at_stderr || at_failed=: echo >>$at_stdout; echo "conflict <- empty string: yychar='a', yylval='A', yylloc=(1,1),(1,1) defstate_look <- empty string: yychar='a', yylval='A', yylloc=(1,1),(1,1) nonconflict2 <- empty string: yychar='b', yylval='B', yylloc=(1,2),(1,2) defstate_shift <- empty string: yychar=YYEMPTY merge <- conflict defstate_look 'a' nonconflict2 'b' defstate_shift: yychar=YYEMPTY start <- merge 'c' stack_explosion: yychar=YYEOF " | $at_diff - $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1420: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 156 ) # 156. glr-regression.at:1429: Leaked semantic values when reporting ambiguity at_setup_line='glr-regression.at:1429' at_desc='Leaked semantic values when reporting ambiguity' $at_quiet $ECHO_N "156: Leaked semantic values when reporting ambiguity$ECHO_C" at_xfail=no ( echo "156. glr-regression.at:1429: testing ..." $at_traceon cat >glr-regr15.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %glr-parser %destructor { parent_rhs_before_value = 0; } parent_rhs_before %{ # include static void yyerror (char const *); static int yylex (void); static int parent_rhs_before_value = 0; # define USE(val) %} %% start: alt1 %dprec 1 | alt2 %dprec 2 ; /* This stack must be merged into the other stacks *last* (added at the beginning of the semantic options list) so that yyparse will choose to clean it up rather than the tree for which some semantic actions have been performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from those other trees are not cleaned up. */ alt1: ; alt2: parent_rhs_before ambiguity { USE ($1); parent_rhs_before_value = 0; } ; parent_rhs_before: { USE ($$); parent_rhs_before_value = 1; } ; ambiguity: ambiguity1 | ambiguity2 ; ambiguity1: ; ambiguity2: ; %% static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } static int yylex (void) { return 0; } int main (void) { int exit_status = yyparse () != 1; if (parent_rhs_before_value) { fprintf (stderr, "`parent_rhs_before' destructor not called.\n"); exit_status = 1; } return exit_status; } _ATEOF $at_traceoff echo "glr-regression.at:1505: bison -o glr-regr15.c glr-regr15.y" echo glr-regression.at:1505 >$at_check_line_file ( $at_traceon; bison -o glr-regr15.c glr-regr15.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr15.y: conflicts: 2 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1505: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1506: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr15 glr-regr15.c \$LIBS" echo glr-regression.at:1506 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr15 glr-regr15.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1506: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1510: ./glr-regr15" echo glr-regression.at:1510 >$at_check_line_file ( $at_traceon; ./glr-regr15 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax is ambiguous " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1510: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 157 ) # 157. glr-regression.at:1519: Leaked lookahead after nondeterministic parse syntax error at_setup_line='glr-regression.at:1519' at_desc='Leaked lookahead after nondeterministic parse syntax error' $at_quiet $ECHO_N "157: Leaked lookahead after nondeterministic parse syntax error$ECHO_C" at_xfail=no ( echo "157. glr-regression.at:1519: testing ..." $at_traceon cat >glr-regr16.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %glr-parser %destructor { lookahead_value = 0; } 'b' %{ # include static void yyerror (char const *); static int yylex (void); static int lookahead_value = 0; # define USE(val) %} %% start: alt1 'a' | alt2 'a' ; alt1: ; alt2: ; %% static void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); } static int yylex (void) { static char const *input = "ab"; if (*input == 'b') lookahead_value = 1; return *input++; } int main (void) { int exit_status = yyparse () != 1; if (lookahead_value) { fprintf (stderr, "Lookahead destructor not called.\n"); exit_status = 1; } return exit_status; } _ATEOF $at_traceoff echo "glr-regression.at:1571: bison -o glr-regr16.c glr-regr16.y" echo glr-regression.at:1571 >$at_check_line_file ( $at_traceon; bison -o glr-regr16.c glr-regr16.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr16.y: conflicts: 1 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1571: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1572: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr16 glr-regr16.c \$LIBS" echo glr-regression.at:1572 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr16 glr-regr16.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1572: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1576: ./glr-regr16" echo glr-regression.at:1576 >$at_check_line_file ( $at_traceon; ./glr-regr16 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "syntax error " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1576: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; 158 ) # 158. glr-regression.at:1585: Uninitialized location when reporting ambiguity at_setup_line='glr-regression.at:1585' at_desc='Uninitialized location when reporting ambiguity' $at_quiet $ECHO_N "158: Uninitialized location when reporting ambiguity$ECHO_C" at_xfail=no ( echo "158. glr-regression.at:1585: testing ..." $at_traceon cat >glr-regr17.y <<'_ATEOF' %{ #ifdef HAVE_CONFIG_H # include /* We don't need perfect functions for these tests. */ # undef malloc # undef memcmp # undef realloc #endif %} %glr-parser %locations %pure-parser %error-verbose %union { int dummy; } %{ static void yyerror (YYLTYPE *, char const *); static int yylex (YYSTYPE *, YYLTYPE *); %} %initial-action { @$.first_line = 1; @$.first_column = 1; @$.last_line = 1; @$.last_column = 1; } %% /* Tests the case of an empty RHS that has inherited the location of the previous nonterminal, which is unresolved. That location is reported as the last position of the ambiguity. */ start: ambig1 empty1 | ambig2 empty2 ; /* Tests multiple levels of yyresolveLocations recursion. */ ambig1: sub_ambig1 | sub_ambig2 ; ambig2: sub_ambig1 | sub_ambig2 ; /* Tests the case of a non-empty RHS as well as the case of an empty RHS that has inherited the initial location. The empty RHS's location is reported as the first position in the ambiguity. */ sub_ambig1: empty1 'a' 'b' ; sub_ambig2: empty2 'a' 'b' ; empty1: ; empty2: ; %% static void yyerror (YYLTYPE *locp, char const *msg) { fprintf (stderr, "Error at %d.%d-%d.%d: %s.\n", locp->first_line, locp->first_column, locp->last_line, locp->last_column, msg); } static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) { static char const input[] = "ab"; static char const *inputp = input; lvalp->dummy = 0; llocp->first_line = llocp->last_line = 2; llocp->first_column = inputp - input + 1; llocp->last_column = llocp->first_column + 1; return *inputp++; } int main (void) { return yyparse () != 1; } _ATEOF $at_traceoff echo "glr-regression.at:1656: bison -o glr-regr17.c glr-regr17.y" echo glr-regression.at:1656 >$at_check_line_file ( $at_traceon; bison -o glr-regr17.c glr-regr17.y ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "glr-regr17.y: conflicts: 3 reduce/reduce " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1656: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1657: \$CC \$CFLAGS \$CPPFLAGS \$LDFLAGS -o glr-regr17 glr-regr17.c \$LIBS" echo glr-regression.at:1657 >$at_check_line_file ( $at_traceon; $CC $CFLAGS $CPPFLAGS $LDFLAGS -o glr-regr17 glr-regr17.c $LIBS ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo stderr:; cat $at_stderr echo stdout:; cat $at_stdout case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1657: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff echo "glr-regression.at:1661: ./glr-regr17" echo glr-regression.at:1661 >$at_check_line_file ( $at_traceon; ./glr-regr17 ) >$at_stdout 2>$at_stder1 at_status=$? grep '^ *+' $at_stder1 >&2 grep -v '^ *+' $at_stder1 >$at_stderr at_failed=false echo >>$at_stderr; echo "Error at 1.1-2.3: syntax is ambiguous. " | $at_diff - $at_stderr || at_failed=: $at_diff $at_devnull $at_stdout || at_failed=: case $at_status in 77) echo 77 > $at_status_file exit 77;; 0) ;; *) echo "glr-regression.at:1661: exit code was $at_status, expected 0" at_failed=:;; esac if $at_failed; then echo 1 > $at_status_file exit 1 fi $at_traceon $at_traceoff $at_times_p && times >$at_times_file ) 5>&1 2>&1 | eval $at_tee_pipe at_status=`cat $at_status_file` ;; * ) echo "$as_me: no such test group: $at_group" >&2 continue ;; esac # Be sure to come back to the suite directory, in particular # since below we might `rm' the group directory we are in currently. cd $at_suite_dir case $at_group in banner-*) ;; *) if test ! -f $at_check_line_file; then sed "s/^ */$as_me: warning: /" <<_ATEOF A failure happened in a test group before any test could be run. This means that test suite is improperly designed. Please report this failure to . _ATEOF echo "$at_setup_line" >$at_check_line_file fi at_group_count=`expr 1 + $at_group_count` $at_verbose $ECHO_N "$at_group. $at_setup_line: $ECHO_C" echo $ECHO_N "$at_group. $at_setup_line: $ECHO_C" >> $at_group_log case $at_xfail:$at_status in yes:0) at_msg="UNEXPECTED PASS" at_xpass_list="$at_xpass_list $at_group" at_errexit=$at_errexit_p ;; no:0) at_msg="ok" at_pass_list="$at_pass_list $at_group" at_errexit=false ;; *:77) at_msg="skipped (`cat $at_check_line_file`)" at_skip_list="$at_skip_list $at_group" at_errexit=false ;; yes:*) at_msg="expected failure (`cat $at_check_line_file`)" at_xfail_list="$at_xfail_list $at_group" at_errexit=false ;; no:*) at_msg="FAILED (`cat $at_check_line_file`)" at_fail_list="$at_fail_list $at_group" at_errexit=$at_errexit_p ;; esac echo $at_msg at_log_msg="$at_group. $at_desc ($at_setup_line): $at_msg" case $at_status in 0|77) # $at_times_file is only available if the group succeeded. # We're not including the group log, so the success message # is written in the global log separately. But we also # write to the group log in case they're using -d. if test -f $at_times_file; then at_log_msg="$at_log_msg (`sed 1d $at_times_file`)" rm -f $at_times_file fi echo "$at_log_msg" >> $at_group_log echo "$at_log_msg" >&5 # Cleanup the group directory, unless the user wants the files. $at_debug_p || rm -rf $at_group_dir ;; *) # Upon failure, include the log into the testsuite's global # log. The failure message is written in the group log. It # is later included in the global log. echo "$at_log_msg" >> $at_group_log # Upon failure, keep the group directory for autopsy, and # create the debugging script. { echo "#! /bin/sh" echo 'test "${ZSH_VERSION+set}" = set && alias -g '\''${1+"$@"}'\''='\''"$@"'\''' echo "cd $at_dir" echo 'exec ${CONFIG_SHELL-'"$SHELL"'}' "$0" \ '-v -d' "$at_debug_args" "$at_group" '${1+"$@"}' echo 'exit 1' } >$at_group_dir/run chmod +x $at_group_dir/run $at_errexit && break ;; esac ;; esac done # Back to the top directory. cd $at_dir # Compute the duration of the suite. at_stop_date=`date` at_stop_time=`(date +%s) 2>/dev/null` echo "$as_me: ending at: $at_stop_date" >&5 at_duration_s=`(expr $at_stop_time - $at_start_time) 2>/dev/null` at_duration_m=`(expr $at_duration_s / 60) 2>/dev/null` at_duration_h=`(expr $at_duration_m / 60) 2>/dev/null` at_duration_s=`(expr $at_duration_s % 60) 2>/dev/null` at_duration_m=`(expr $at_duration_m % 60) 2>/dev/null` at_duration="${at_duration_h}h ${at_duration_m}m ${at_duration_s}s" if test "$at_duration" != "h m s"; then echo "$as_me: test suite duration: $at_duration" >&5 fi # Wrap up the test suite with summary statistics. at_skip_count=`set dummy $at_skip_list; shift; echo $#` at_fail_count=`set dummy $at_fail_list; shift; echo $#` at_xpass_count=`set dummy $at_xpass_list; shift; echo $#` at_xfail_count=`set dummy $at_xfail_list; shift; echo $#` at_run_count=`expr $at_group_count - $at_skip_count` at_unexpected_count=`expr $at_xpass_count + $at_fail_count` at_total_fail_count=`expr $at_xfail_count + $at_fail_count` echo cat <<\_ASBOX ## ------------- ## ## Test results. ## ## ------------- ## _ASBOX echo { echo cat <<\_ASBOX ## ------------- ## ## Test results. ## ## ------------- ## _ASBOX echo } >&5 if test $at_run_count = 1; then at_result="1 test" at_were=was else at_result="$at_run_count tests" at_were=were fi if $at_errexit_p && test $at_unexpected_count != 0; then if test $at_xpass_count = 1; then at_result="$at_result $at_were run, one passed" else at_result="$at_result $at_were run, one failed" fi at_result="$at_result unexpectedly and inhibited subsequent tests." else # Don't you just love exponential explosion of the number of cases? case $at_xpass_count:$at_fail_count:$at_xfail_count in # So far, so good. 0:0:0) at_result="$at_result $at_were successful." ;; 0:0:*) at_result="$at_result behaved as expected." ;; # Some unexpected failures 0:*:0) at_result="$at_result $at_were run, $at_fail_count failed unexpectedly." ;; # Some failures, both expected and unexpected 0:*:1) at_result="$at_result $at_were run, $at_total_fail_count failed ($at_xfail_count expected failure)." ;; 0:*:*) at_result="$at_result $at_were run, $at_total_fail_count failed ($at_xfail_count expected failures)." ;; # No unexpected failures, but some xpasses *:0:*) at_result="$at_result $at_were run, $at_xpass_count passed unexpectedly." ;; # No expected failures, but failures and xpasses *:1:0) at_result="$at_result $at_were run, $at_unexpected_count did not behave as expected ($at_fail_count unexpected failure)." ;; *:*:0) at_result="$at_result $at_were run, $at_unexpected_count did not behave as expected ($at_fail_count unexpected failures)." ;; # All of them. *:*:1) at_result="$at_result $at_were run, $at_xpass_count passed unexpectedly, $at_total_fail_count failed ($at_xfail_count expected failure)." ;; *:*:*) at_result="$at_result $at_were run, $at_xpass_count passed unexpectedly, $at_total_fail_count failed ($at_xfail_count expected failures)." ;; esac if test $at_skip_count = 0 && test $at_run_count -gt 1; then at_result="All $at_result" fi fi # Now put skips in the mix. case $at_skip_count in 0) ;; 1) at_result="$at_result 1 test was skipped." ;; *) at_result="$at_result $at_skip_count tests were skipped." ;; esac if test $at_unexpected_count = 0; then echo "$at_result" echo "$at_result" >&5 else echo "ERROR: $at_result" >&2 echo "ERROR: $at_result" >&5 { echo cat <<\_ASBOX ## ------------------------ ## ## Summary of the failures. ## ## ------------------------ ## _ASBOX # Summary of failed and skipped tests. if test $at_fail_count != 0; then echo "Failed tests:" $SHELL $0 $at_fail_list --list echo fi if test $at_skip_count != 0; then echo "Skipped tests:" $SHELL $0 $at_skip_list --list echo fi if test $at_xpass_count != 0; then echo "Unexpected passes:" $SHELL $0 $at_xpass_list --list echo fi if test $at_fail_count != 0; then cat <<\_ASBOX ## ---------------------- ## ## Detailed failed tests. ## ## ---------------------- ## _ASBOX echo for at_group in $at_fail_list do # Normalize the test group number. at_group_normalized=`expr "00000$at_group" : ".*\($at_format\)"` # Create a fresh directory for the next test group, and enter. at_group_dir=$at_suite_dir/$at_group_normalized at_group_log=$at_group_dir/$as_me.log cat $at_group_log echo done echo fi if test -n "$at_top_srcdir"; then sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## $at_top_builddir/config.log ## _ASBOX sed 's/^/| /' $at_top_builddir/config.log echo fi } >&5 sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## $as_me.log was created. ## _ASBOX echo echo "Please send \`$as_me.log' and all information you think might help:" echo echo " To: " echo " Subject: [GNU Bison 2.3] $as_me:$at_fail_list${at_fail_list:+ failed${at_xpass_list:+,}}$at_xpass_list${at_xpass_list:+ passed unexpectedly}" echo if test $at_debug_p = false; then echo echo 'You may investigate any problem if you feel able to do so, in which' echo 'case the test suite provides a good starting point.' echo fi exit 1 fi exit 0