Files
bison/tests/existing.at
Joel E. Denny cff03fb2b9 * src/gram.c: Remove comments that duplicate comments in gram.h.
When reporting useless rules and nonterminals, say "useless in grammar"
instead of "useless", and say "useless in parser" instead of "never
reduced".  Discussed starting at
<http://lists.gnu.org/archive/html/bison-patches/2007-10/msg00033.html>.
* NEWS (2.3a+): Mention this change.
* data/xslt/xml2text.xsl: Update output text and expected input XML
element names to match changes below.
* data/xslt/xml2xhtml.xsl: Likewise.
(xsl:template match="bison-xml-report"): Add missing entry in Table of
Contents: "Rules useless in parser due to conflicts".
* doc/bison.texinfo (Decl Summary): Reword a little.
(Understanding): Update example output for changes below.
* src/gram.c: (rule_useful_p): Rename to...
(rule_useful_in_grammar_p): ... this.
(rule_useless_p): Rename to...
(rule_useless_in_grammar_p): ... this.
(rule_never_reduced_p): Rename to...
(rule_useless_in_parser_p): ... this.
(grammar_rules_print): Update for renames.
(grammar_rules_print_xml): Update for renames.
(grammar_rules_never_reduced_report): Rename to...
(grammar_rules_useless_report): ... this since it is used for either
kind of useless rule.
* src/gram.h: Reword comments and update function names in prototypes.
* src/main.c (main): Say "rule useless in parser due to conflicts".
* src/print-xml.c (print_rules_never_reduced): Rename to...
(print_rules_useless_in_parser): ... this, and rename output XML
element "rules-never-reduced" to "rules-useless-in-parser".
(print_xml): Update for rename.
* src/print.c (print_results): Say "Rules useless in parser due to
conflicts".
* src/reduce.c (reduce_grammar_tables): Say "rule useless in grammar".
(nonterminals_reduce): Say "nonterminal useless in grammar".
(reduce_output): Say "Nonterminals useless in grammar".
Say "Rules useless in grammar".
(reduce_xml): Rename output XML element "useless" to
"useless-in-grammar".
(reduce_print): Don't report the count of grammatically useless rules
as "rules never reduced" just because %yacc is specified.
In the correct report of this count, say nonterminal(s) and rule(s)
"useless in grammar".
* tests/conflicts.at (S/R in initial): Update expected output.
(Defaulted Conflicted Reduction): Likewise.
(Unreachable States After Conflict Resolution): Likewise.
* tests/existing.at (GNU pic Grammar): Likewise.
* tests/reduce.at (Useless Nonterminals): Likewise.
(Useless Rules): Likewise.
(Reduced Automaton): Likewise.
(Underivable Rules): Likewise.
(Empty Language): Likewise.
2007-11-10 03:42:37 +00:00

1526 lines
27 KiB
Plaintext

# Exercising Bison on actual grammars. -*- Autotest -*-
# Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004, 2005,
# 2007 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, see <http://www.gnu.org/licenses/>.
AT_BANNER([[Existing Grammars.]])
## ----------------- ##
## 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 {}
%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
;
%%
]])
# 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: conflicts: 78 shift/reduce, 10 reduce/reduce
]])
AT_CHECK([[grep '^State.*conflicts:' input.output]], 0,
[[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_CLEANUP
## ----------------- ##
## GNU pic Grammar. ##
## ----------------- ##
AT_SETUP([GNU pic Grammar])
# GNU pic, part of groff.
# Bison once reported shift/reduce conflicts that it shouldn't have.
AT_DATA([[input.y]],
[[%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
;
]])
# 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:453.11-48: warning: rule useless in parser due to conflicts: path: ORDINAL LAST object_type relative_path
]])
AT_CLEANUP