]> git.saurik.com Git - bison.git/blobdiff - tests/torture.at
Typo.
[bison.git] / tests / torture.at
index e0205372a9daaefc7f27d4ac33b03c5e67f218a9..8fe00f7cad657da9369bbee0860005f4ea569b72 100644 (file)
@@ -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