mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
The computation of nullable is broken: it doesn't handle empty
RHS's properly. * tests/torture.at (GNU AWK Grammar): New. * tests/sets.at (Nullable): New. * src/nullable.c (set_nullable): Instead of blindly looping over `ritems', loop over the rules, and then over their rhs's. Work around Autotest bugs. * src/warshall.c (bitmatrix_print): Don't use `+--+' as table frame, because Autotest understand lines starting with a `+' as traces from the shell. Then, they are not processed properly. Admittedly an Autotest bug, but we don't have time to wait for Autotest to catch up. * tests/regression.at (Broken Closure): Adjust to the new table frames. Move to... * tests/sets.at: here.
This commit is contained in:
340
tests/torture.at
340
tests/torture.at
@@ -114,3 +114,343 @@ AT_CHECK([input 900], 0, [], [ignore])
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user