# Torturing Bison. -*- Autotest -*-
-# Copyright 2001 Free Software Foundation, Inc.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
+# Copyright (C) 2001-2002, 2004-2007, 2009-2012 Free Software
+# Foundation, Inc.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-
+#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
AT_BANNER([[Torture Tests.]])
-# AT_DATA_STACK_TORTURE(C-PROLOGUE)
-# ---------------------------------
+# AT_INCREASE_DATA_SIZE(SIZE)
+# ---------------------------
+# Try to increase the data size to SIZE KiB if possible.
+m4_define([AT_INCREASE_DATA_SIZE],
+[data_limit=`(ulimit -S -d) 2>/dev/null`
+case $data_limit in
+[[0-9]]*)
+ if test "$data_limit" -lt $1; then
+ AT_CHECK([ulimit -S -d $1 || exit 77])
+ ulimit -S -d $1
+ fi
+esac])
+
+
+## ------------------------------------- ##
+## Creating a large artificial grammar. ##
+## ------------------------------------- ##
+
+# AT_DATA_TRIANGULAR_GRAMMAR(FILE-NAME, SIZE)
+# -------------------------------------------
+# Create FILE-NAME, containing a self checking parser for a huge
+# triangular grammar.
+m4_define([AT_DATA_TRIANGULAR_GRAMMAR],
+[AT_DATA([[gengram.pl]],
+[[#! /usr/bin/perl -w
+
+use strict;
+my $max = $ARGV[0] || 10;
+
+print <<EOF;
+]AT_DATA_GRAMMAR_PROLOGUE[
+%error-verbose
+%debug
+%{
+#include <stdio.h>
+#include <stdlib.h>
+
+]AT_YYLEX_DECLARE[
+]AT_YYERROR_DECLARE[
+%}
+%union
+{
+ int val;
+};
+
+%token END "end"
+%type <val> exp input
+EOF
+
+for my $size (1 .. $max)
+ {
+ print "%token t$size $size \"$size\"\n";
+ };
+
+print <<EOF;
+%%
+input:
+ exp { if (\@S|@1 != 0) abort (); \$\$ = \@S|@1; }
+| input exp { if (\@S|@2 != \@S|@1 + 1) abort (); \$\$ = \@S|@2; }
+;
+
+exp:
+ END
+ { \$\$ = 0; }
+EOF
+
+for my $size (1 .. $max)
+ {
+ use Text::Wrap;
+ print wrap ("| ", " ",
+ (map { "\"$_\"" } (1 .. $size)),
+ " END \n"),
+ " { \$\$ = $size; }\n";
+ };
+print ";\n";
+
+print <<EOF;
+%%
+static int
+yylex (void)
+{
+ static int inner = 1;
+ static int outer = 0;
+ if (outer > $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
+]])
+
+AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
+mv stdout $1
+])
+
+
+## -------------- ##
+## Big triangle. ##
+## -------------- ##
+
+AT_SETUP([Big triangle])
+
+# 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.
+AT_DATA_TRIANGULAR_GRAMMAR([input.y], [200])
+AT_BISON_CHECK_NO_XML([-v -o input.c input.y])
+AT_COMPILE([input])
+AT_PARSER_CHECK([./input])
+
+AT_CLEANUP
+
+
+
+# AT_DATA_HORIZONTAL_GRAMMAR(FILE-NAME, SIZE)
+# -------------------------------------------
+# Create FILE-NAME, containing a self checking parser for a huge
+# horizontal grammar.
+m4_define([AT_DATA_HORIZONTAL_GRAMMAR],
+[AT_DATA([[gengram.pl]],
+[[#! /usr/bin/perl -w
+
+use strict;
+my $max = $ARGV[0] || 10;
+
+print <<EOF;
+]AT_DATA_GRAMMAR_PROLOGUE[
+%error-verbose
+%debug
+%{
+#include <stdio.h>
+#include <stdlib.h>
+
+]AT_YYLEX_DECLARE[
+]AT_YYERROR_DECLARE[
+%}
+
+%token
+EOF
+for my $size (1 .. $max)
+ {
+ print " t$size $size \"$size\"\n";
+ };
+
+print <<EOF;
+
+%%
+EOF
+
+use Text::Wrap;
+print
+ wrap ("exp: ", " ",
+ (map { "\"$_\"" } (1 .. $max)), ";"),
+ "\n";
+
+print <<EOF;
+%%
+static int
+yylex (void)
+{
+ static int counter = 1;
+ if (counter <= $max)
+ return counter++;
+ if (counter++ != $max + 1)
+ abort ();
+ return 0;
+}
+
+static void
+yyerror (const char *msg)
+{
+ fprintf (stderr, "%s\\n", msg);
+}
+
+int
+main (void)
+{
+ yydebug = !!getenv ("YYDEBUG");
+ return yyparse ();
+}
+EOF
+]])
+
+AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
+mv stdout $1
+])
+
+
+## ---------------- ##
+## Big horizontal. ##
+## ---------------- ##
+
+AT_SETUP([Big horizontal])
+
+# 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
+#
+AT_DATA_HORIZONTAL_GRAMMAR([input.y], [1000])
+
+# 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.
+AT_INCREASE_DATA_SIZE(204000)
+
+AT_BISON_CHECK_NO_XML([-v -o input.c input.y])
+AT_COMPILE([input])
+AT_PARSER_CHECK([./input])
+
+AT_CLEANUP
+
+
+
+# AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR(FILE-NAME, SIZE)
+# --------------------------------------------------
+# Create FILE-NAME, containing a self checking parser for a grammar
+# requiring SIZE lookahead tokens.
+m4_define([AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR],
+[AT_DATA([[gengram.pl]],
+[[#! /usr/bin/perl -w
+
+use strict;
+use Text::Wrap;
+my $max = $ARGV[0] || 10;
+
+print <<EOF;
+%error-verbose
+%debug
+%{
+# include <stdio.h>
+# include <stdlib.h>
+# include <assert.h>
+
+]AT_YYLEX_DECLARE[
+]AT_YYERROR_DECLARE[
+%}
+%union
+{
+ int val;
+};
+
+%type <val> input exp
+%token token
+EOF
+
+print
+ wrap ("%type <val> ",
+ " ",
+ map { "n$_" } (1 .. $max)),
+ "\n";
+
+print "%token\n";
+for my $count (1 .. $max)
+ {
+ print " t$count $count \"$count\"\n";
+ };
+
+print <<EOF;
+%%
+input:
+ exp { assert (\@S|@1 == 1); \$\$ = \@S|@1; }
+| input exp { assert (\@S|@2 == \@S|@1 + 1); \$\$ = \@S|@2; }
+;
+
+exp:
+ n1 "1" { assert (\@S|@1 == 1); \@S|@\@S|@ = \@S|@1; }
+EOF
+
+for my $count (2 .. $max)
+ {
+ print "| n$count \"$count\" { assert (\@S|@1 == $count); \@S|@\@S|@ = \@S|@1; }\n";
+ };
+print ";\n";
+
+for my $count (1 .. $max)
+ {
+ print "n$count: token { \$\$ = $count; };\n";
+ };
+
+print <<EOF;
+%%
+static int
+yylex (void)
+{
+ static int return_token = 1;
+ static int counter = 1;
+ if (counter > $max)
+ {
+ if (counter++ != $max + 1)
+ abort ();
+ 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
+]])
+
+AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
+mv stdout $1
+])
+
+
+## ------------------------ ##
+## Many lookahead tokens. ##
+## ------------------------ ##
+
+AT_SETUP([Many lookahead tokens])
+
+AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR([input.y], [1000])
+
+# 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.
+AT_INCREASE_DATA_SIZE(204000)
+
+AT_BISON_CHECK([-v -o input.c input.y])
+AT_COMPILE([input])
+AT_PARSER_CHECK([./input])
+
+AT_CLEANUP
+
+
+
+# AT_DATA_STACK_TORTURE(C-PROLOGUE, [BISON-DECLS])
+# ------------------------------------------------
# A parser specialized in torturing the stack size.
m4_define([AT_DATA_STACK_TORTURE],
-[# A grammar of parens growing the stack thanks to right recursion.
+[AT_BISON_OPTION_PUSHDEFS([$2])
+# A grammar of parens growing the stack thanks to right recursion.
# exp:
AT_DATA([input.y],
[[%{
+#include <errno.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
-#include <assert.h>
]$1[
- static int yylex (void);
- static void yyerror (const char *msg);
-#define YYPRINT(File, Type, Value) \
- fprintf (File, " (%d, stack size = %d, max = %d)", \
- Value, yyssp - yyss + 1, yystacksize);
+ ]AT_YYLEX_DECLARE[
+ ]AT_YYERROR_DECLARE[
%}
+]$2[
%error-verbose
%debug
%token WAIT_FOR_EOF
%%
exp: WAIT_FOR_EOF exp | ;
%%
-static void
-yyerror (const char *msg)
-{
- fprintf (stderr, "%s\n", msg);
- exit (1);
-}
-
-/* There are YYLVAL_MAX of WAIT_FOR_EOFs. */
-unsigned int yylval_max;
-
+]AT_YYERROR_DEFINE[
static int
yylex (void)
{
+ if (yylval < 0)
+ abort ();
if (yylval--)
return WAIT_FOR_EOF;
else
int
main (int argc, const char **argv)
{
- assert (argc == 2);
- yylval = atoi (argv[1]);
+ char *endp;
+ YYSTYPE yylval_init;
+ if (argc != 2)
+ abort ();
+ yylval_init = strtol (argv[1], &endp, 10);
+ if (! (argv[1] != endp
+ && 0 <= yylval_init && yylval_init <= INT_MAX
+ && errno != ERANGE))
+ abort ();
yydebug = 1;
- return yyparse ();
+ {
+ int count;
+ int status;
+]m4_bmatch([$2], [%push-],
+[[ yypstate *ps = yypstate_new ();
+]])[ for (count = 0; count < 2; ++count)
+ {
+ int new_status;
+ yylval = yylval_init;
+]m4_bmatch([$2], [%push-],
+[[ new_status = yypull_parse (ps);
+]],
+[[ new_status = yyparse ();
+]])[ if (count > 0 && new_status != status)
+ abort ();
+ status = new_status;
+ }
+]m4_bmatch([$2], [%push-],
+[[ yypstate_delete (ps);
+]])[ return status;
+ }
}
]])
-AT_CHECK([bison input.y -o input.c])
-AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore])
+AT_BISON_OPTION_POPDEFS([$2])
+AT_BISON_CHECK([-o input.c input.y])
+AT_COMPILE([input])
])
AT_SETUP([Exploding the Stack Size with Alloca])
-AT_DATA_STACK_TORTURE
+m4_pushdef([AT_USE_ALLOCA], [[
+#if (defined __GNUC__ || defined __BUILTIN_VA_ARG_INCR \
+ || defined _AIX || defined _MSC_VER || defined _ALLOCA_H)
+# define YYSTACK_USE_ALLOCA 1
+#endif
+]])
+
+AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
# Below the limit of 200.
-AT_CHECK([input 20], 0, [], [ignore])
+AT_PARSER_CHECK([./input 20], 0, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
# Two enlargements: 2 * 2 * 200.
-AT_CHECK([input 900], 0, [], [ignore])
+AT_PARSER_CHECK([./input 900], 0, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
# 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_CHECK([input 10000], 1, [], [ignore])
+AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
+
+# The push parser can't use alloca since the stacks can't be locals. This test
+# just helps guarantee we don't let the YYSTACK_USE_ALLOCA feature affect
+# push parsers.
+AT_DATA_STACK_TORTURE([AT_USE_ALLOCA],
+[[%define api.push-pull both
+]])
+AT_PARSER_CHECK([./input 20], 0, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
+AT_PARSER_CHECK([./input 900], 0, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
+AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
+
+m4_popdef([AT_USE_ALLOCA])
AT_CLEANUP
AT_SETUP([Exploding the Stack Size with Malloc])
-AT_DATA_STACK_TORTURE([[#define YYSTACK_USE_ALLOCA 0]])
+m4_pushdef([AT_USE_ALLOCA], [[#define YYSTACK_USE_ALLOCA 0]])
+
+AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
# Below the limit of 200.
-AT_CHECK([input 20], 0, [], [ignore])
+AT_PARSER_CHECK([./input 20], 0, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
# Two enlargements: 2 * 2 * 200.
-AT_CHECK([input 900], 0, [], [ignore])
+AT_PARSER_CHECK([./input 900], 0, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
# 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_CHECK([input 10000], 1, [], [ignore])
-
-AT_CLEANUP
-
-
-## ----------------- ##
-## GNU AWK Grammar. ##
-## ----------------- ##
-
-AT_SETUP([GNU AWK Grammar])
-
-# 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!
-
-AT_DATA([[input.y]],
-[[%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
- ;
-
-%%
-]])
-
-# 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_CHECK([[bison --verbose --defines input.y]])
-
-AT_CLEANUP
-
-
-## ----------------- ##
-## GNU Cim Grammar. ##
-## ----------------- ##
-
-AT_SETUP([GNU Cim Grammar])
-
-# 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!!!
-
-AT_DATA([[input.y]],
-[[%union {
- long token;
- long ival;
- long arrdim;
- double rval;
- char *ident;
- char *tval;
- char stat_decl;
- }
-
-%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 <ident> HIDENTIFIER
-%token <ival> HBOOLEANKONST HINTEGERKONST HCHARACTERKONST
-%token <rval> HREALKONST
-%token <tval> HTEXTKONST
-
-%type <tval> EXT_IDENT
-%type <stat_decl> DECLSTATEMENT MODULSTATEMENT MBEE_DECLSTMS MBEE_DECLSTMSU
-%type <stat_decl> MODULS
-%type <ident> EXPRESSION_SIMP MBEE_ARG_R_PT
-%type <arrdim> BAUND_PAIR_LIST
-
-%right <token> HASSIGN
-%left HORELSE
-%left HANDTHEN
-%left HEQV
-%left HIMP
-%left HOR
-%left HAND
-
-%left HNOT
-
-%left <token> HVALRELOPERATOR HREFRELOPERATOR HOBJRELOPERATOR
-
-%left HCONC
-
-%left <token> HTERMOPERATOR
-%left <token> UNEAR
-%left <token> HFACTOROPERATOR
-%left HPRIMARYOPERATOR
-
-%left HQUA
-
-%left HDOT
-
-%start MAIN_MODULE
-%%
-/* GRAMATIKK FOR PROGRAM MODULES */
-MAIN_MODULE : { categ=CLOCAL; mout(MBLOCK);
- beginBlock(KBLOKK);separat_comp=FALSE;}
- MODULS { endBlock(NULL,CCNO); mout(MENDBLOCK);}
- | error HSTATEMENTSEPARATOR MBEE_DECLSTMS
- ;
-EXT_DECLARATION : HEXTERNAL
- MBEE_TYPE
- HPROCEDURE
- { MBEENEWBLOCK();
- kind=KPROC;}
- EXT_LIST
- |
- HEXTERNAL
- HIDENTIFIER
- HPROCEDURE
- { MBEENEWBLOCK();
- type=TNOTY;
- kind=KPROC;
- if($2==Ckind)categ=CCPROC;else
- yerror (1);
- ysensitive=sensitive;
- sensitive=ON;}
- HIDENTIFIER { $<ident>$=$5;
- sensitive=ysensitive;}
- EXTERNAL_KIND_ITEM
- { categ=CLOCAL;}
- | HEXTERNAL
- HCLASS
- { MBEENEWBLOCK();
- kind=KCLASS;}
- EXT_LIST
-
- ;
-EXTERNAL_KIND_ITEM: EXT_IDENT
- HOBJRELOPERATOR
- { if($2!=HIS)yerror (2);}
- MBEE_TYPE HPROCEDURE
- HIDENTIFIER
- { regDecl($6, type, KPROC, CCPROC);
- beginBlock(kind);}
- HEADING EMPTY_BLOCK
- { categ=CLOCAL;
- endBlock($1==NULL?$<ident>0:tag($1),CCCPROC);}
-/* |
- EXT_IDENT
- { if($1!=NULL)yerror (3);
- regDecl($0, type, kind, categ);}
- MBEE_REST_EXT_LIST
- { endBlock(NULL,CCNO);}
- ;
-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
- { if($2!=NULL)yerror (3);
- regDecl($1, type, kind, categ);}*/
- ;
-EMPTY_BLOCK : /*EMPT*/
- | HBEGIN HEND
- ;
-EXT_LIST : EXT_ITEM
- | EXT_LIST HPAREXPSEPARATOR EXT_ITEM
- ;
-EXT_ITEM : HIDENTIFIER
- EXT_IDENT
- { lesinn_external_spec($1,$2, kind);}
- ;
-EXT_IDENT : /* EMPTY */ { $$=NULL;}
- | HVALRELOPERATOR { if($1!=HEQ)yerror (9);
- external=TRUE;}
- HTEXTKONST { $$=$3;external=FALSE;}
- ;
-/* GRAMATIKK FOR TYPER */
-NO_TYPE : /*EMPT*/ { type=TNOTY;}
- ;
-MBEE_TYPE : NO_TYPE
- | TYPE
- ;
-TYPE : HREF HBEGPAR
- HIDENTIFIER
- { prefquantident=$3;
- type=TREF;}
- HENDPAR
- | HTEXT { type=TTEXT;}
- | HBOOLEAN { type=TBOOL;}
- | HCHARACTER { type=TCHAR;}
- | HSHORT HINTEGER { type=TSHORT;}
- | HINTEGER { type=TINTG;}
- | HREAL { type=TREAL;}
- | HLONG HREAL { type=TLONG;}
- ;
-
-/* GRAMATIKK FOR DEL AV SETNINGER */
-MBEE_ELSE_PART : /*EMPT*/
-/* | HELSE
- HIF
- EXPRESSION
- HTHEN { mout(MELSE);
- mout(MIF);
- OBSBLOCK();}
- BLOCK { MBEEENDBLOCK();}
- MBEE_ELSE_PART { mout(MENDIF);}*/
- | HELSE { OBSBLOCK(); mout(MELSE);}
- BLOCK { MBEEENDBLOCK();}
- ;
-FOR_LIST : FOR_LIST_ELEMENT { mout(MENDSEP);
- mout(MLISTSEP);}
- | FOR_LIST_ELEMENT
- HPAREXPSEPARATOR
- FOR_LIST { mout(MLISTSEP);}
- ;
-FOR_LIST_ELEMENT: EXPRESSION
- MBEE_F_L_EL_R_PT
- ;
-MBEE_F_L_EL_R_PT: /*EMPT*/
- | HWHILE
- EXPRESSION { mout(MFORWHILE);}
- | HSTEP
- EXPRESSION
- HUNTIL
- EXPRESSION { mout(MUNTIL);
- mout(MSTEP);}
- ;
-GOTO : HGO
- HTO
- | HGOTO
- ;
-CONN_STATE_R_PT : WHEN_CLAUSE_LIST
- | HDO { beginBlock(KCON); mout(MDO);
- OBSBLOCK(); }
- BLOCK { endBlock(NULL,CCNO);
- MBEEENDBLOCK(); mout(MENDDO);}
- ;
-WHEN_CLAUSE_LIST: HWHEN
- HIDENTIFIER
- HDO { beginBlock(KCON); mout(MIDENTIFIER);
- OBSBLOCK(); moutId($2);
- mout(MWHEN);}
- BLOCK { endBlock(NULL,CCNO);
- MBEEENDBLOCK(); mout(MENDWHEN);}
- | WHEN_CLAUSE_LIST
- HWHEN
- HIDENTIFIER
- HDO { beginBlock(KCON); mout(MIDENTIFIER);
- OBSBLOCK(); moutId($3);
- mout(MWHEN);}
- BLOCK { endBlock(NULL,CCNO);
- MBEEENDBLOCK(); mout(MENDWHEN);}
- ;
-MBEE_OTWI_CLAUS : /*EMPT*/
- | HOTHERWISE {OBSBLOCK(); mout(MOTHERWISE);}
-
- BLOCK {MBEEENDBLOCK();mout(MENDOTHERWISE);}
- ;
-ACTIVATOR : HACTIVATE { mout(MBOOLEANKONST);
- moutIval(FALSE);}
- | HREACTIVATE { mout(MBOOLEANKONST);
- moutIval(TRUE);}
- ;
-SCHEDULE : /*EMPT*/ { mout(MCHARACTERKONST);
- moutIval(DIRECT);
- mout(MINTEGERKONST);
- moutIval(0);
- mout(MNONE);
- mout(MBOOLEANKONST);
- moutIval(FALSE);}
- | ATDELAY EXPRESSION { mout(MNONE);}
- PRIOR
- | BEFOREAFTER { mout(MINTEGERKONST);
- moutIval(0);}
- EXPRESSION { mout(MBOOLEANKONST);
- moutIval(FALSE);}
- ;
-ATDELAY : HAT { mout(MCHARACTERKONST);
- moutIval(AT);}
- | HDELAY { mout(MCHARACTERKONST);
- moutIval(DELAYS);}
- ;
-BEFOREAFTER : HBEFORE { mout(MCHARACTERKONST);
- moutIval(BEFORE);}
- | HAFTER { mout(MCHARACTERKONST);
- moutIval(AFTER);}
- ;
-PRIOR : /*EMPT*/ { mout(MBOOLEANKONST);
- moutIval(FALSE);}
- | HPRIOR { mout(MBOOLEANKONST);
- moutIval(TRUE);}
- ;
-/* GRAMATIKK FOR SETNINGER OG DEKLARASJONER */
-MODULSTATEMENT : HWHILE
- EXPRESSION
- HDO { STOPOBSBLOCK(); mout(MWHILE);
- OBSBLOCK();}
- BLOCK { MBEEENDBLOCK(); mout(MENDWHILE);
- $$=STATEMENT;}
- | HIF
- EXPRESSION
- HTHEN { STOPOBSBLOCK(); mout(MIF);
- OBSBLOCK();}
- BLOCK { MBEEENDBLOCK();}
- MBEE_ELSE_PART { mout(MENDIF);
- $$=STATEMENT;}
- | HFOR
- HIDENTIFIER
- HASSIGN { STOPOBSBLOCK(); mout(MIDENTIFIER);
- moutId($2);}
- FOR_LIST
- HDO { beginBlock(KFOR);
- if($3==HASSIGNVALUE) mout(MFOR);
- else mout(MFORR);
- OBSBLOCK(); mout(MFORDO);}
- BLOCK { MBEEENDBLOCK();
- endBlock(NULL,CCNO); mout(MENDFOR);
- $$=STATEMENT;}
- | GOTO
- EXPRESSION { mout(MGOTO);
- STOPOBSBLOCK(); $$=STATEMENT;}
- | HINSPECT
- EXPRESSION { mout(MINSPECT);
- STOPOBSBLOCK();
- beginBlock(KINSP);}
- CONN_STATE_R_PT
- { endBlock(NULL,CCNO);}
- MBEE_OTWI_CLAUS { mout(MENDINSPECT);
- $$=STATEMENT;}
- | HINNER { STOPOBSBLOCK(); mout(MINNER);
- regInner(); $$=STATEMENT;}
- | HIDENTIFIER
- HLABELSEPARATOR
- { STOPOBSBLOCK();
- regDecl($1, TLABEL, KSIMPLE, categ); mout(MLABEL);
- moutId($1);
- mout(MENDLABEL);}
- DECLSTATEMENT { if($4<=DECLARATION)
- { yerror (27);
- $$=DECLARATION;}
- else $$=$4;}
- | EXPRESSION_SIMP
- HBEGIN
- { $<ident>$=$1; }
- IMPORT_SPEC_MODULE
- { mout(MPRBLOCK);
- prefquantident=$1;
- beginBlock(KPRBLK);}
- MBEE_DECLSTMS
- HEND { endBlock(NULL,CCNO); mout(MENDPRBLOCK);
- $$=STATEMENT;}
- | EXPRESSION_SIMP HBEGIN error HSTATEMENTSEPARATOR
- MBEE_DECLSTMS HEND { $$=STATEMENT;
- endBlock(NULL,CCNO); mout(MENDPRBLOCK);}
- | EXPRESSION_SIMP HBEGIN error HEND
- { $$=STATEMENT;
- endBlock(NULL,CCNO); mout(MENDPRBLOCK);}
-
- | EXPRESSION_SIMP
- { STOPOBSBLOCK(); $$=STATEMENT;
- mout(MENDASSIGN);}
- | ACTIVATOR EXPRESSION SCHEDULE
- { $$=STATEMENT;
- mout(MENDSEP);
- mout(MARGUMENTSEP);
- mout(MARGUMENTSEP);
- mout(MARGUMENTSEP);
- mout(MARGUMENTSEP);
- mout(MARGUMENTSEP);
- mout(MARGUMENTSEP);
- mout(MARGUMENT);
- moutId(activateid);
- mout(MENDASSIGN);}
- | HBEGIN
- { STOPOBSBLOCK();
- OBSBLOCK();}
- MBEE_DECLSTMS
- HEND { MBEEENDBLOCK(); $$=STATEMENT;}
- | MBEE_TYPE HPROCEDURE
- HIDENTIFIER
- { MBEENEWBLOCK(); mout(MPROCEDURE);
- regDecl($3, type, KPROC, categ);
- beginBlock(KPROC);}
- HEADING BLOCK { endBlock(NULL,CCNO); $$=DECLARATION;
- mout(MENDPROCEDURE);}
- | HIDENTIFIER
- HCLASS
- NO_TYPE
- { $<ident>$=$1; }
- IMPORT_SPEC_MODULE
- HIDENTIFIER
- { prefquantident=$1;
- mout(MCLASS);
- regDecl($6, TNOTY, KCLASS, categ);
- beginBlock(KCLASS);}
- HEADING
- BLOCK { endBlock(NULL,CCNO); $$=DECLARATION;
- mout(MENDCLASS);}
- | HCLASS
- NO_TYPE
- HIDENTIFIER
- { prefquantident=0;
- MBEENEWBLOCK(); mout(MCLASS);
- regDecl($3, TNOTY, KCLASS, categ);
- beginBlock(KCLASS);}
- HEADING
- BLOCK { endBlock(NULL,CCNO); $$=DECLARATION;
- mout(MENDCLASS);}
- | EXT_DECLARATION { $$=EXTDECLARATION;}
- | /*EMPT*/{ STOPOBSBLOCK(); $$=EMPTYSTATEMENT;}
- ;
-IMPORT_SPEC_MODULE: { MBEENEWBLOCK();
- kind=KCLASS;
- if($<ident>0==simsetident &&
- findDecl(simsetident,cblock,FALSE)==NULL)
- lesinn_external_spec(simsetident,
- SIMSETATRFILE, kind);
- if($<ident>0==simulationident && findDecl(
- simulationident,cblock,FALSE)==NULL)
- lesinn_external_spec(simulationident,
- SIMULATIONATRFILE, kind);
- if(($<ident>0==fileident && findDecl(
- fileident,cblock,FALSE)==NULL) ||
- ($<ident>0==outfileident && findDecl(
- outfileident,cblock,FALSE)==NULL) ||
- ($<ident>0==infileident && findDecl(
- infileident,cblock,FALSE)==NULL) ||
- ($<ident>0==directfileident && findDecl(
- directfileident,cblock,FALSE)==NULL) ||
- ($<ident>0==printfileident && findDecl(
- printfileident,cblock,FALSE)==NULL) ||
- ($<ident>0==bytefileident && findDecl(
- bytefileident,cblock,FALSE)==NULL) ||
- ($<ident>0==inbytefileident && findDecl(
- inbytefileident,cblock,FALSE)==NULL) ||
- ($<ident>0==outbytefileident && findDecl(
- outbytefileident,cblock,FALSE)==NULL) ||
- ($<ident>0==directbytefileident && findDecl(
- directbytefileident,cblock,FALSE)==NULL))
- lesinn_external_spec(fileident,
- FILEATRFILE, kind);}
- ;
-DECLSTATEMENT : MODULSTATEMENT
- | TYPE
- HIDENTIFIER
- MBEE_CONSTANT
- HPAREXPSEPARATOR
- { MBEENEWBLOCK();
- kind=KSIMPLE;
- regDecl($2, type, KSIMPLE, categ);
- categ=CLOCAL;}
- IDENTIFIER_LISTC { $$=DECLARATION;}
- | TYPE
- HIDENTIFIER
- MBEE_CONSTANT
- { MBEENEWBLOCK();
- regDecl($2, type, KSIMPLE, categ);
- categ=CLOCAL; $$=DECLARATION;}
- | MBEE_TYPE
- HARRAY { MBEENEWBLOCK();
- kind=KARRAY;}
- ARR_SEGMENT_LIST { $$=DECLARATION;}
- | HSWITCH
- HIDENTIFIER
- HASSIGN { MBEENEWBLOCK(); mout(MIDENTIFIER);
- moutId($2);
- regDecl($2, TLABEL, KARRAY, categ);}
- SWITCH_LIST { $$=DECLARATION;
- mout(MSWITCH);
- mout(MENDSWITCH);}
- ;
-BLOCK : DECLSTATEMENT { if($1<=DECLARATION)yerror (29);}
- | HBEGIN MBEE_DECLSTMS HEND
- | HBEGIN error HSTATEMENTSEPARATOR MBEE_DECLSTMS HEND
- | HBEGIN error HEND
- ;
-MBEE_DECLSTMS : MBEE_DECLSTMSU { if($1<=DECLARATION)yerror (28);
- $$=$1;}
- ;
-MBEE_DECLSTMSU : DECLSTATEMENT { $$=$1;}
- | MBEE_DECLSTMSU
- HSTATEMENTSEPARATOR
- DECLSTATEMENT { if($1>=STATEMENT && $3<=DECLARATION)
- yerror (26);
- $$=$3;}
- ;
-MODULS : MODULSTATEMENT { if($1==DECLARATION)
- {separat_comp=TRUE;gettimestamp();}
- $$=$1;}
- | MODULS HSTATEMENTSEPARATOR MODULSTATEMENT
- { if($1>=STATEMENT && $3<=DECLARATION)
- yerror (26);else
- if($1>=STATEMENT
- && $3!=EMPTYSTATEMENT)yerror (25);
- if(separat_comp && $3==STATEMENT)
- yerror (25);
- if($3==DECLARATION && !separat_comp)
- {separat_comp=TRUE;gettimestamp();}
- $$=$3;}
- ;
-/* 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 { mout(MARRAY);
- mout(MENDARRAY);
- setArrayDim($3);}
- ;
-ARRAY_SEGMENT : ARRAY_SEGMENT_EL { mout(MENDSEP);
- mout(MARRAYSEP);}
-
- | ARRAY_SEGMENT_EL
- HPAREXPSEPARATOR
- ARRAY_SEGMENT { mout(MARRAYSEP);}
- ;
-ARRAY_SEGMENT_EL: HIDENTIFIER { mout(MIDENTIFIER);
- moutId($1);
- regDecl($1, type, kind, categ);
- if(lastArray==NULL)
- lastArray=cblock->lastparloc;}
- ;
-BAUND_PAIR_LIST : BAUND_PAIR { mout(MENDSEP);
- mout(MBOUNDSEP);
- $$=1;}
- | BAUND_PAIR
- HPAREXPSEPARATOR
- BAUND_PAIR_LIST { mout(MBOUNDSEP);
- $$=$3+1;}
- ;
-BAUND_PAIR : EXPRESSION
- HLABELSEPARATOR
- EXPRESSION { mout(MBOUNDPARSEP);}
- ;
-SWITCH_LIST : EXPRESSION { mout(MENDSEP);
- mout(MSWITCHSEP);}
- | EXPRESSION
- HPAREXPSEPARATOR
- SWITCH_LIST { mout(MSWITCHSEP);}
- ;
-HEADING : MBEE_FMAL_PAR_P HSTATEMENTSEPARATOR { kind=KNOKD;}
- MBEE_MODE_PART { categ=CSPEC;}
- MBEE_SPEC_PART { kind=KNOKD;}
- MBEE_PROT_PART { categ=CVIRT;}
- MBEE_VIRT_PART
- { categ=CLOCAL;}
- ;
-MBEE_FMAL_PAR_P : /*EMPT*/
- | FMAL_PAR_PART
- ;
-FMAL_PAR_PART : HBEGPAR NO_TYPE
- MBEE_LISTV HENDPAR
- ;
-MBEE_LISTV : /*EMPT*/
- | LISTV
- ;
-LISTV : HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);}
- | FPP_CATEG HDOTDOTDOT { regDecl(varargsid, TVARARGS, KNOKD, categ);}
- | HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);}
- 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 { regDecl(varargsid, TVARARGS, KNOKD, categ);}
- | FPP_SPEC
- | FPP_SPEC
- HPAREXPSEPARATOR LISTV
- ;
-FPP_SPEC : FPP_CATEG SPECIFIER HIDENTIFIER
- { regDecl($3, type, kind, categ);}
- | FPP_CATEG FPP_PROC_DECL_IN_SPEC
- ;
-FPP_CATEG : HNAME HLABELSEPARATOR
- { categ=CNAME;}
- | HVALUE HLABELSEPARATOR
- { categ=CVALUE;}
- | HVAR HLABELSEPARATOR
- { categ=CVAR;}
- | /*EMPT*/ { categ=CDEFLT;}
- ;
-FPP_PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE
- HIDENTIFIER
- { $<ival>$=categ;
- regDecl($3, type, KPROC, categ);
- beginBlock(KPROC);}
- FPP_HEADING
- { categ=$<ival>4; /* M} settes tilbake*/}
- { endBlock(NULL,CCNO);}
- ;
-IDENTIFIER_LISTV: HIDENTIFIER { regDecl($1, type, kind, categ);}
- | HDOTDOTDOT { regDecl(varargsid, TVARARGS, kind, categ);}
- | HIDENTIFIER { regDecl($1, type, kind, categ);}
- 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 { categ=CNAME;}
- IDENTIFIER_LISTV
- HSTATEMENTSEPARATOR
- ;
-VAR_PART : HVAR { categ=CVAR;}
- IDENTIFIER_LISTV
- HSTATEMENTSEPARATOR
- ;
-VALUE_PART : HVALUE { categ=CVALUE;}
- 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
- { if($4!=HIS) yerror (8);}
- PROC_DECL_IN_SPEC HSTATEMENTSEPARATOR
- | FPP_PROC_DECL_IN_SPEC HSTATEMENTSEPARATOR
- | MBEE_TYPE HPROCEDURE HIDENTIFIER HSTATEMENTSEPARATOR
- { yerror (45);}
- | MBEE_TYPE HPROCEDURE HIDENTIFIER HPAREXPSEPARATOR
- IDENTIFIER_LIST HSTATEMENTSEPARATOR
- { yerror (45);}
- ;
-SPECIFIER : TYPE { kind=KSIMPLE;}
- | MBEE_TYPE
- HARRAY { kind=KARRAY;}
- | HLABEL { type=TLABEL;
- kind=KSIMPLE;}
- | HSWITCH { type=TLABEL;
- kind=KARRAY;}
- ;
-PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE
- HIDENTIFIER
- { $<ival>$=categ;
- regDecl($3, type, KPROC, categ);
- beginBlock(KPROC);}
- HEADING
- { categ=$<ival>4; /* M} settes tilbake*/}
- MBEE_BEGIN_END
- { endBlock(NULL,CCNO);}
- ;
-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 { categ=CHIDEN;}
- | HPROTECTED { categ=CPROT;}
- | HHIDDEN
- HPROTECTED { categ=CHIPRO;}
- | HPROTECTED
- HHIDDEN { categ=CHIPRO;}
- ;
-MBEE_VIRT_PART : /*EMPT*/
- | VIRTUAL_PART
- ;
-VIRTUAL_PART : HVIRTUAL
- HLABELSEPARATOR
- MBEE_SPEC_PART
- ;
-IDENTIFIER_LIST : HIDENTIFIER { regDecl($1, type, kind, categ);}
- | IDENTIFIER_LIST HPAREXPSEPARATOR
- HIDENTIFIER { regDecl($3, type, kind, categ);}
- ;
-IDENTIFIER_LISTC: HIDENTIFIER
- MBEE_CONSTANT { regDecl($1, type, kind, categ);
- categ=CLOCAL;}
- | IDENTIFIER_LISTC HPAREXPSEPARATOR
- HIDENTIFIER
- MBEE_CONSTANT { regDecl($3, type, kind, categ);
- categ=CLOCAL;}
- ;
-MBEE_CONSTANT : /* EMPTY */
- | HVALRELOPERATOR
- { MBEENEWBLOCK();
- if($1!=HEQ) yerror (8);
- if(type==TREF)yerror (7);
- categ=CCONSTU;
- mout(MIDENTIFIER);
- moutId($<token>0);}
- EXPRESSION { mout(MASSIGN);
- mout(MCONST);}
- ;
-
-/* GRAMATIKK FOR UTTRYKK */
-EXPRESSION : EXPRESSION_SIMP {}
- | HIF
- EXPRESSION
- HTHEN
- EXPRESSION
- HELSE
- EXPRESSION { mout(MELSEE);
- mout(MIFE);}
- ;
-EXPRESSION_SIMP : EXPRESSION_SIMP
- HASSIGN
- EXPRESSION { if($2==HASSIGNREF)mout(MASSIGNR);
- else mout(MASSIGN);$$=NULL;}
- |
-
- EXPRESSION_SIMP
- HCONC
- EXPRESSION_SIMP { mout(MCONC);$$=NULL;}
- | EXPRESSION_SIMP HOR
- HELSE
- EXPRESSION_SIMP
- %prec HORELSE { mout(MORELSEE);$$=NULL;}
- | EXPRESSION_SIMP HAND
- HTHEN
- EXPRESSION_SIMP
- %prec HANDTHEN { mout(MANDTHENE);$$=NULL;}
- | EXPRESSION_SIMP
- HEQV EXPRESSION_SIMP { mout(MEQV);$$=NULL;}
- | EXPRESSION_SIMP
- HIMP EXPRESSION_SIMP { mout(MIMP);$$=NULL;}
- | EXPRESSION_SIMP
- HOR EXPRESSION_SIMP { mout(MOR);$$=NULL;}
- | EXPRESSION_SIMP
- HAND EXPRESSION_SIMP { mout(MAND);$$=NULL;}
- | HNOT EXPRESSION_SIMP { mout(MNOT);$$=NULL;}
- | EXPRESSION_SIMP
- HVALRELOPERATOR
- EXPRESSION_SIMP
- { switch($2)
- { case HEQ: mout(MEQ);break;
- case HNE: mout(MNE);break;
- case HLT: mout(MLT);break;
- case HLE: mout(MLE);break;
- case HGT: mout(MGT);break;
- case HGE: mout(MGE);break;
- }$$=NULL;}
- | EXPRESSION_SIMP
- HREFRELOPERATOR
- EXPRESSION_SIMP
- { if($2==HNER) mout(MNER);
- else mout(MEQR);$$=NULL;}
- | EXPRESSION_SIMP
- HOBJRELOPERATOR
- EXPRESSION_SIMP
- { if($2==HIS) mout(MIS);
- else mout(MINS);$$=NULL;}
- | HTERMOPERATOR
- EXPRESSION_SIMP %prec UNEAR
- { if($1==HADD) mout(MUADD);
- else mout(MUSUB);$$=NULL;}
- | EXPRESSION_SIMP
- HTERMOPERATOR
- EXPRESSION_SIMP
- { if($2==HADD) mout(MADD);
- else mout(MSUB);$$=NULL;}
- | EXPRESSION_SIMP
- HFACTOROPERATOR
- EXPRESSION_SIMP
- { if($2==HMUL) mout(MMUL); else
- if($2==HDIV) mout(MDIV);
- else mout(MINTDIV);$$=NULL;}
- | EXPRESSION_SIMP
- HPRIMARYOPERATOR
- EXPRESSION_SIMP { mout(MPRIMARY);$$=NULL;}
- | HBEGPAR
- EXPRESSION HENDPAR { mout(MNOOP);$$=NULL;}
- | HTEXTKONST { mout(MTEXTKONST);
- moutTval($1);$$=NULL;}
- | HCHARACTERKONST { mout(MCHARACTERKONST);
- moutIval($1);$$=NULL;}
- | HREALKONST { mout(MREALKONST);
- moutRval($1);$$=NULL;}
- | HINTEGERKONST { mout(MINTEGERKONST);
- moutIval($1);$$=NULL;}
- | HBOOLEANKONST { mout(MBOOLEANKONST);
- moutIval($1);$$=NULL;}
- | HNONE { mout(MNONE);$$=NULL;}
- | HIDENTIFIER
- { $<ident>$=$1;}
- MBEE_ARG_R_PT
- | HTHIS HIDENTIFIER { mout(MTHIS);
- moutId($2);$$=NULL;}
- | HNEW
- HIDENTIFIER
- ARG_R_PT { mout(MNEWARG);
- moutId($2);$$=NULL;}
- | EXPRESSION_SIMP
- HDOT
- EXPRESSION_SIMP { mout(MDOT);$$=NULL;}
- | EXPRESSION_SIMP
- HQUA HIDENTIFIER { mout(MQUA);
- moutId($3);$$=NULL;}
- ;
-ARG_R_PT : /*EMPTY*/ { mout(MENDSEP);}
- | HBEGPAR
- ARGUMENT_LIST HENDPAR
- ;
-MBEE_ARG_R_PT : /*EMPTY*/ { mout(MIDENTIFIER);
- moutId($<ident>0);
- $$=$<ident>0;}
- | HBEGPAR
- ARGUMENT_LIST HENDPAR { mout(MARGUMENT);
- moutId($<ident>0);}
- ;
-ARGUMENT_LIST : EXPRESSION { mout(MENDSEP);
- mout(MARGUMENTSEP);}
- | EXPRESSION
- HPAREXPSEPARATOR
- ARGUMENT_LIST { mout(MARGUMENTSEP);}
- ;
-%%
-]])
-
-# 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_CHECK([[bison --verbose --defines input.y]], 0, [],
-[[input.y contains 78 shift/reduce conflicts and 10 reduce/reduce conflicts.
-]])
+AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
-AT_CHECK([[grep '^State.*contains' input.output]], 0,
-[[State 64 contains 14 shift/reduce conflicts.
-State 164 contains 1 shift/reduce conflict.
-State 201 contains 33 shift/reduce conflicts and 4 reduce/reduce conflicts.
-State 206 contains 1 shift/reduce conflict.
-State 240 contains 1 shift/reduce conflict.
-State 335 contains 9 shift/reduce conflicts and 2 reduce/reduce conflicts.
-State 356 contains 1 shift/reduce conflict.
-State 360 contains 9 shift/reduce conflicts and 2 reduce/reduce conflicts.
-State 427 contains 9 shift/reduce conflicts and 2 reduce/reduce conflicts.
+AT_DATA_STACK_TORTURE([AT_USE_ALLOCA],
+[[%define api.push-pull both
]])
+AT_PARSER_CHECK([./input 20], 0, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
+AT_PARSER_CHECK([./input 900], 0, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
+AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
+ [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
+
+m4_popdef([AT_USE_ALLOCA])
AT_CLEANUP