[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: %destructor feedback
From: |
Akim Demaille |
Subject: |
Re: %destructor feedback |
Date: |
Thu, 22 Dec 2005 12:37:03 +0100 |
User-agent: |
Gnus/5.110004 (No Gnus v0.4) Emacs/21.4 (gnu/linux) |
>>> "Paul" == Paul Eggert <address@hidden> writes:
>> - we desire a warning about typed $n not used in the actions.
> Yes, that sounds reasonable. My assumption is that a missing action
> continues to be treated as { $$ = $1; }, so for missing actions Bison
> would warn about typed $2, $3, etc., not used but would not warn about
> typed $1 not used.
I installed the following. I spent quite a lot of time debugging
these lines:
if (typed)
{
symbol_list *l = current_rule;
int n = 1;
for (l = current_rule->next; l && l->sym; ++l, ++n)
/* The default action `uses' $1. */
if (! (!current_rule->action && n == 1)
&& l->sym->type_name && !l->used)
warn_at (current_rule->location, _("unused value: $%d"), n);
}
because... in C, you ought to write l = l->next for linked lists, not
++l... I dunno whether it is C++ or C I should thank for all this
time...
Index: ChangeLog
from Akim Demaille <address@hidden>
Warn about unused values.
* src/symlist.h, src/symlist.c (symbol_list, symbol_list_new): Add
a `used' member.
(symbol_list_n_get, symbol_list_n_used_set): New.
(symbol_list_n_type_name_get): Use symbol_list_n_get.
* src/scan-gram.l (handle_action_dollar): Flag used symbols.
* src/reader.c (grammar_current_rule_check): Check that values are
used.
* src/symtab.c (symbol_print): Accept 0.
* tests/existing.at: Remove the type information.
Empty the actions.
Remove useless actions (beware of mid-rule actions: perl -000
-pi -e 's/\s*\{\}(?=[\n\s]*[|;])//g').
* tests/actions.at (Exotic Dollars): Use unused values.
* tests/calc.at: Likewise.
* tests/glr-regression.at (No users destructors if stack 0 deleted):
Likewise.
* src/gram.c (rule_useful_p, rule_never_reduced_p): Use
rule_useful_p.
Index: NEWS
===================================================================
RCS file: /cvsroot/bison/bison/NEWS,v
retrieving revision 1.134
diff -u -u -r1.134 NEWS
--- NEWS 21 Dec 2005 15:28:30 -0000 1.134
+++ NEWS 22 Dec 2005 11:35:59 -0000
@@ -3,6 +3,24 @@
Changes in version 2.1a:
+* New warning: unused values
+ Typed right-hand side symbols whose value are not used are reported.
+ For instance
+
+ exp: exp "?" exp ":" exp { $$ = $1 + $3; }
+ | exp "+" exp
+ ;
+
+ will trigger a warning about $5 of the first rule, and $3 in the
+ second ($1 is copied to $$ by the default rule). To avoid this
+ warning, let Bison believe the value is used, e.g.
+
+ exp: exp "?" exp ":" exp { $$ = $1 + $3; $5; }
+ | exp "+" exp { $$ = $1; $3; }
+
+ This helps catching lost values and memory leaks: if a value is
+ ignored, its associated memory will never be reclaimed.
+
* %destructor vs. YYACCEPT, YYERROR, and YYABORT.
When the parsing/action is cut by the user using one of these
special actions, the stack is freed except the right-hand side
Index: src/gram.c
===================================================================
RCS file: /cvsroot/bison/bison/src/gram.c,v
retrieving revision 1.58
diff -u -u -r1.58 gram.c
--- src/gram.c 9 Dec 2005 23:51:26 -0000 1.58
+++ src/gram.c 22 Dec 2005 11:35:59 -0000
@@ -65,7 +65,7 @@
bool
rule_useless_p (rule *r)
{
- return r->number >= nrules;
+ return !rule_useful_p (r);
}
@@ -77,7 +77,7 @@
bool
rule_never_reduced_p (rule *r)
{
- return !r->useful && r->number < nrules;
+ return !r->useful && rule_useful_p (r);
}
@@ -317,8 +317,7 @@
if (!rules[r].useful)
{
location_print (stderr, rules[r].location);
- fprintf (stderr, ": %s: %s: ",
- _("warning"), message);
+ fprintf (stderr, ": %s: %s: ", _("warning"), message);
rule_print (&rules[r], stderr);
}
}
Index: src/reader.c
===================================================================
RCS file: /cvsroot/bison/bison/src/reader.c,v
retrieving revision 1.240
diff -u -u -r1.240 reader.c
--- src/reader.c 9 Dec 2005 23:51:26 -0000 1.240
+++ src/reader.c 22 Dec 2005 11:35:59 -0000
@@ -40,7 +40,7 @@
static bool start_flag = false;
merger_list *merge_functions;
-/* Has %union been seen? */
+/* Was %union seen? */
bool typed = false;
/* Should rules have a default precedence? */
@@ -104,7 +104,7 @@
type = uniqstr_new ("");
head.next = merge_functions;
- for (syms = &head, n = 1; syms->next != NULL; syms = syms->next, n += 1)
+ for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
if (UNIQSTR_EQ (name, syms->next->name))
break;
if (syms->next == NULL)
@@ -128,11 +128,8 @@
void
free_merger_functions (void)
{
- merger_list *L0;
- if (! glr_parser)
- return;
- L0 = merge_functions;
- while (L0 != NULL)
+ merger_list *L0 = merge_functions;
+ while (L0)
{
merger_list *L1 = L0->next;
free (L0);
@@ -150,13 +147,6 @@
| |
| All actions are copied out, labelled by the rule number they apply |
| to. |
-| |
-| Bison used to allow some %directives in the rules sections, but |
-| this is no longer consider appropriate: (i) the documented grammar |
-| doesn't claim it, (ii), it would promote bad style, (iii), error |
-| recovery for %directives consists in skipping the junk until a `%' |
-| is seen and helrp synchronizing. This scheme is definitely wrong |
-| in the rules section. |
`-------------------------------------------------------------------*/
/* The (currently) last symbol of GRAMMAR. */
@@ -206,7 +196,6 @@
current_rule = grammar_end;
/* Mark the rule's lhs as a nonterminal if not already so. */
-
if (lhs->class == unknown_sym)
{
lhs->class = nterm_sym;
@@ -217,39 +206,55 @@
complain_at (loc, _("rule given for %s, which is a token"), lhs->tag);
}
-/* Check that the last rule (CURRENT_RULE) is properly defined. For
- instance, there should be no type clash on the default action. */
+
+/*------------------------------------------------------------------.
+| Check that the last rule (CURRENT_RULE) is properly defined. For |
+| instance, there should be no type clash on the default action. |
+`------------------------------------------------------------------*/
static void
grammar_current_rule_check (void)
{
symbol *lhs = current_rule->sym;
char const *lhs_type = lhs->type_name;
- symbol *first_rhs = current_rule->next->sym;
- /* If there is an action, then there is nothing we can do: the user
- is allowed to shoot herself in the foot. */
- if (current_rule->action)
- return;
+ /* Type check.
- /* Don't worry about the default action if $$ is untyped, since $$'s
- value can't be used. */
- if (! lhs_type)
- return;
+ If there is an action, then there is nothing we can do: the user
+ is allowed to shoot herself in the foot.
- /* If $$ is being set in default way, report if any type mismatch. */
- if (first_rhs)
+ Don't worry about the default action if $$ is untyped, since $$'s
+ value can't be used. */
+ if (!current_rule->action && lhs_type)
{
- const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : "";
- if (!UNIQSTR_EQ (lhs_type, rhs_type))
+ symbol *first_rhs = current_rule->next->sym;
+ /* If $$ is being set in default way, report if any type mismatch. */
+ if (first_rhs)
+ {
+ const char *rhs_type =
+ first_rhs->type_name ? first_rhs->type_name : "";
+ if (!UNIQSTR_EQ (lhs_type, rhs_type))
+ warn_at (current_rule->location,
+ _("type clash on default action: <%s> != <%s>"),
+ lhs_type, rhs_type);
+ }
+ /* Warn if there is no default for $$ but we need one. */
+ else
warn_at (current_rule->location,
- _("type clash on default action: <%s> != <%s>"),
- lhs_type, rhs_type);
+ _("empty rule for typed nonterminal, and no action"));
+ }
+
+ /* Check that all the symbol values are used. */
+ if (typed)
+ {
+ symbol_list *l = current_rule;
+ int n = 1;
+ for (l = current_rule->next; l && l->sym; l = l->next, ++n)
+ /* The default action `uses' $1. */
+ if (! (!current_rule->action && n == 1)
+ && l->sym->type_name && !l->used)
+ warn_at (current_rule->location, _("unused value: $%d"), n);
}
- /* Warn if there is no default for $$ but we need one. */
- else
- warn_at (current_rule->location,
- _("empty rule for typed nonterminal, and no action"));
}
Index: src/reader.h
===================================================================
RCS file: /cvsroot/bison/bison/src/reader.h,v
retrieving revision 1.45
diff -u -u -r1.45 reader.h
--- src/reader.h 25 Jul 2005 03:12:53 -0000 1.45
+++ src/reader.h 22 Dec 2005 11:35:59 -0000
@@ -77,7 +77,10 @@
extern merger_list *merge_functions;
+/* Was %union seen? */
extern bool typed;
+
+/* Should rules have a default precedence? */
extern bool default_prec;
#endif /* !READER_H_ */
Index: src/scan-gram.l
===================================================================
RCS file: /cvsroot/bison/bison/src/scan-gram.l,v
retrieving revision 1.78
diff -u -u -r1.78 scan-gram.l
--- src/scan-gram.l 13 Oct 2005 19:38:46 -0000 1.78
+++ src/scan-gram.l 22 Dec 2005 11:35:59 -0000
@@ -825,9 +825,9 @@
if (INT_MIN <= num && num <= rule_length && ! get_errno ())
{
int n = num;
- if (1-n > max_left_semantic_context)
- max_left_semantic_context = 1-n;
- if (!type_name && n > 0)
+ if (max_left_semantic_context < 1 - n)
+ max_left_semantic_context = 1 - n;
+ if (!type_name && 0 < n)
type_name = symbol_list_n_type_name_get (current_rule, loc, n);
if (!type_name && typed)
complain_at (loc, _("$%d of `%s' has no declared type"),
@@ -837,6 +837,8 @@
obstack_fgrow3 (&obstack_for_string,
"]b4_rhs_value(%d, %d, [%s])[",
rule_length, n, type_name);
+ if (typed)
+ symbol_list_n_used_set (current_rule, n, true);
}
else
complain_at (loc, _("integer out of range: %s"), quote (text));
Index: src/symlist.c
===================================================================
RCS file: /cvsroot/bison/bison/src/symlist.c,v
retrieving revision 1.13
diff -u -u -r1.13 symlist.c
--- src/symlist.c 9 Dec 2005 23:51:26 -0000 1.13
+++ src/symlist.c 22 Dec 2005 11:35:59 -0000
@@ -34,13 +34,19 @@
symbol_list_new (symbol *sym, location loc)
{
symbol_list *res = xmalloc (sizeof *res);
- res->next = NULL;
+
res->sym = sym;
res->location = loc;
+
res->action = NULL;
+ res->used = false;
+
res->ruleprec = NULL;
res->dprec = 0;
res->merger = 0;
+
+ res->next = NULL;
+
return res;
}
@@ -56,7 +62,7 @@
{
symbol_print (l->sym, f);
if (l && l->sym)
- fputc (' ', f);
+ fprintf (f, ", ");
}
}
@@ -90,43 +96,64 @@
`--------------------*/
unsigned int
-symbol_list_length (symbol_list *list)
+symbol_list_length (symbol_list *l)
{
int res = 0;
- for (/* Nothing. */; list; list = list->next)
+ for (/* Nothing. */; l; l = l->next)
++res;
return res;
}
+/*--------------------------------.
+| Get symbol N in symbol list L. |
+`--------------------------------*/
+
+symbol_list *
+symbol_list_n_get (symbol_list *l, int n)
+{
+ int i;
+
+ if (n < 0)
+ return NULL;
+
+ for (i = 0; i < n; ++i)
+ {
+ l = l->next;
+ if (l == NULL || l->sym == NULL)
+ return NULL;
+ }
+
+ return l;
+}
+
+
/*--------------------------------------------------------------.
| Get the data type (alternative in the union) of the value for |
-| symbol N in symbol list RP. |
+| symbol N in symbol list L. |
`--------------------------------------------------------------*/
uniqstr
-symbol_list_n_type_name_get (symbol_list *rp, location loc, int n)
+symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
{
- int i;
-
- if (n < 0)
+ l = symbol_list_n_get (l, n);
+ if (!l)
{
complain_at (loc, _("invalid $ value: $%d"), n);
return NULL;
}
+ return l->sym->type_name;
+}
- i = 0;
- while (i < n)
- {
- rp = rp->next;
- if (rp == NULL || rp->sym == NULL)
- {
- complain_at (loc, _("invalid $ value: $%d"), n);
- return NULL;
- }
- ++i;
- }
+/*----------------------------------------.
+| The symbol N in symbol list L is USED. |
+`----------------------------------------*/
- return rp->sym->type_name;
+void
+symbol_list_n_used_set (symbol_list *l, int n, bool used)
+{
+ l = symbol_list_n_get (l, n);
+ if (l)
+ l->used = used;
}
Index: src/symlist.h
===================================================================
RCS file: /cvsroot/bison/bison/src/symlist.h,v
retrieving revision 1.10
diff -u -u -r1.10 symlist.h
--- src/symlist.h 12 Jul 2005 15:58:49 -0000 1.10
+++ src/symlist.h 22 Dec 2005 11:35:59 -0000
@@ -25,9 +25,10 @@
# include "location.h"
# include "symtab.h"
+/* A list of symbols, used during the parsing to store the rules. */
typedef struct symbol_list
{
- struct symbol_list *next;
+ /* The symbol. */
symbol *sym;
location location;
@@ -35,9 +36,16 @@
const char *action;
location action_location;
+ /* Whether this symbol's value is used in the current action. */
+ bool used;
+
+ /* Precedence/associativity. */
symbol *ruleprec;
int dprec;
int merger;
+
+ /* The list. */
+ struct symbol_list *next;
} symbol_list;
@@ -48,18 +56,24 @@
void symbol_list_print (symbol_list *l, FILE *f);
/* Prepend SYM at LOC to the LIST. */
-symbol_list *symbol_list_prepend (symbol_list *list,
+symbol_list *symbol_list_prepend (symbol_list *l,
symbol *sym,
location loc);
/* Free the LIST, but not the symbols it contains. */
-void symbol_list_free (symbol_list *list);
+void symbol_list_free (symbol_list *l);
/* Return its length. */
-unsigned int symbol_list_length (symbol_list *list);
+unsigned int symbol_list_length (symbol_list *l);
+
+/* Get symbol N in symbol list L. */
+symbol_list *symbol_list_n_get (symbol_list *l, int n);
/* Get the data type (alternative in the union) of the value for
symbol N in rule RULE. */
-uniqstr symbol_list_n_type_name_get (symbol_list *rp, location loc, int n);
+uniqstr symbol_list_n_type_name_get (symbol_list *l, location loc, int n);
+
+/* The symbol N in symbol list L is USED. */
+void symbol_list_n_used_set (symbol_list *l, int n, bool used);
#endif /* !SYMLIST_H_ */
Index: src/symtab.c
===================================================================
RCS file: /cvsroot/bison/bison/src/symtab.c,v
retrieving revision 1.67
diff -u -u -r1.67 symtab.c
--- src/symtab.c 9 Dec 2005 23:51:26 -0000 1.67
+++ src/symtab.c 22 Dec 2005 11:35:59 -0000
@@ -85,10 +85,15 @@
void
symbol_print (symbol *s, FILE *f)
{
- fprintf (f, "\"%s\"", s->tag);
- SYMBOL_ATTR_PRINT (type_name);
- SYMBOL_ATTR_PRINT (destructor);
- SYMBOL_ATTR_PRINT (printer);
+ if (s)
+ {
+ fprintf (f, "\"%s\"", s->tag);
+ SYMBOL_ATTR_PRINT (type_name);
+ SYMBOL_ATTR_PRINT (destructor);
+ SYMBOL_ATTR_PRINT (printer);
+ }
+ else
+ fprintf (f, "<NULL>");
}
#undef SYMBOL_ATTR_PRINT
Index: tests/actions.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/actions.at,v
retrieving revision 1.54
diff -u -u -r1.54 actions.at
--- tests/actions.at 30 Sep 2005 17:57:05 -0000 1.54
+++ tests/actions.at 22 Dec 2005 11:35:59 -0000
@@ -98,6 +98,7 @@
static int yylex (void);
# define YYDEBUG 1
# define YYERROR_VERBOSE 1
+# define USE(Var)
%}
%union
@@ -112,6 +113,7 @@
exp: a_1 a_2 { $<val>$ = 3; } { $<val>$ = $<val>3 + 1; } a_5
sum_of_the_five_previous_values
{
+ USE (($1, $2, $5));
printf ("%d\n", $6);
}
;
Index: tests/calc.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/calc.at,v
retrieving revision 1.83
diff -u -u -r1.83 calc.at
--- tests/calc.at 18 Nov 2005 19:37:13 -0000 1.83
+++ tests/calc.at 22 Dec 2005 11:35:59 -0000
@@ -54,6 +54,7 @@
# define alarm(seconds) /* empty */
#endif
#include <ctype.h>
+#define USE(Var)
/* Exercise pre-prologue dependency to %union. */
typedef int semantic_value;
@@ -109,7 +110,7 @@
line:
'\n'
-| exp '\n' { ]AT_PARAM_IF([*result = global_result = $1;])[ }
+| exp '\n' { ]AT_PARAM_IF([*result = global_result = $1], [USE
($1)])[; }
;
exp:
Index: tests/existing.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/existing.at,v
retrieving revision 1.8
diff -u -u -r1.8 existing.at
--- tests/existing.at 24 Jul 2005 07:24:22 -0000 1.8
+++ tests/existing.at 22 Dec 2005 11:35:59 -0000
@@ -1,6 +1,6 @@
# Exercising Bison on actual grammars. -*- Autotest -*-
-# Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
@@ -113,7 +113,6 @@
| l_brace r_brace opt_semi opt_nls
;
-
pattern
: exp
| exp ',' exp
@@ -325,11 +324,11 @@
;
l_brace
- : '{' opt_nls
- ;
+ : '{' opt_nls
+ ;
r_brace
- : '}' opt_nls
+ : '}' opt_nls
;
r_paren
@@ -358,7 +357,6 @@
AT_CLEANUP
-
## ----------------- ##
## GNU Cim Grammar. ##
## ----------------- ##
@@ -371,15 +369,7 @@
# It reported 80 SR && 99 RR conflicts instead of 78/10!!!
AT_DATA([[input.y]],
-[[%union {
- long int token;
- long int ival;
- long int arrdim;
- double rval;
- char *ident;
- char *tval;
- char stat_decl;
- }
+[[%union {}
%token
HACTIVATE HAFTER /*HAND*/ HARRAY HAT
@@ -410,18 +400,13 @@
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
+%token HIDENTIFIER
+%token HBOOLEANKONST HINTEGERKONST HCHARACTERKONST
+%token HREALKONST
+%token HTEXTKONST
-%right <token> HASSIGN
+
+%right HASSIGN
%left HORELSE
%left HANDTHEN
%left HEQV
@@ -431,13 +416,13 @@
%left HNOT
-%left <token> HVALRELOPERATOR HREFRELOPERATOR HOBJRELOPERATOR
+%left HVALRELOPERATOR HREFRELOPERATOR HOBJRELOPERATOR
%left HCONC
-%left <token> HTERMOPERATOR
-%left <token> UNEAR
-%left <token> HFACTOROPERATOR
+%left HTERMOPERATOR
+%left UNEAR
+%left HFACTOROPERATOR
%left HPRIMARYOPERATOR
%left HQUA
@@ -447,55 +432,40 @@
%start MAIN_MODULE
%%
/* GRAMATIKK FOR PROGRAM MODULES */
-MAIN_MODULE : { categ=CLOCAL; mout(MBLOCK);
- beginBlock(KBLOKK);separat_comp=FALSE;}
- MODULS { endBlock(NULL,CCNO); mout(MENDBLOCK);}
+MAIN_MODULE : {}
+ MODULS
| 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;}
+ {}
+ HIDENTIFIER {}
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
@@ -505,8 +475,7 @@
;
EXT_KIND_ITEM : HIDENTIFIER
EXT_IDENT
- { if($2!=NULL)yerror (3);
- regDecl($1, type, kind, categ);}*/
+ {}*/
;
EMPTY_BLOCK : /*EMPT*/
| HBEGIN HEND
@@ -516,31 +485,28 @@
;
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;}
+EXT_IDENT : /* EMPTY */
+ | HVALRELOPERATOR {}
+ HTEXTKONST
;
/* GRAMATIKK FOR TYPER */
-NO_TYPE : /*EMPT*/ { type=TNOTY;}
+NO_TYPE : /*EMPT*/
;
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;}
+ | HTEXT
+ | HBOOLEAN
+ | HCHARACTER
+ | HSHORT HINTEGER
+ | HINTEGER
+ | HREAL
+ | HLONG HREAL
;
/* GRAMATIKK FOR DEL AV SETNINGER */
@@ -548,304 +514,169 @@
/* | HELSE
HIF
EXPRESSION
- HTHEN { mout(MELSE);
- mout(MIF);
- OBSBLOCK();}
- BLOCK { MBEEENDBLOCK();}
- MBEE_ELSE_PART { mout(MENDIF);}*/
- | HELSE { OBSBLOCK(); mout(MELSE);}
- BLOCK { MBEEENDBLOCK();}
+ HTHEN {}
+ BLOCK {}
+ MBEE_ELSE_PART {}*/
+ | HELSE {}
+ BLOCK
;
-FOR_LIST : FOR_LIST_ELEMENT { mout(MENDSEP);
- mout(MLISTSEP);}
+FOR_LIST : FOR_LIST_ELEMENT
| FOR_LIST_ELEMENT
HPAREXPSEPARATOR
- FOR_LIST { mout(MLISTSEP);}
+ FOR_LIST
;
FOR_LIST_ELEMENT: EXPRESSION
MBEE_F_L_EL_R_PT
;
MBEE_F_L_EL_R_PT: /*EMPT*/
| HWHILE
- EXPRESSION { mout(MFORWHILE);}
+ EXPRESSION
| HSTEP
EXPRESSION
HUNTIL
- EXPRESSION { mout(MUNTIL);
- mout(MSTEP);}
+ EXPRESSION
;
GOTO : HGO
HTO
| HGOTO
;
CONN_STATE_R_PT : WHEN_CLAUSE_LIST
- | HDO { beginBlock(KCON); mout(MDO);
- OBSBLOCK(); }
- BLOCK { endBlock(NULL,CCNO);
- MBEEENDBLOCK(); mout(MENDDO);}
+ | HDO {}
+ BLOCK
;
WHEN_CLAUSE_LIST: HWHEN
HIDENTIFIER
- HDO { beginBlock(KCON); mout(MIDENTIFIER);
- OBSBLOCK(); moutId($2);
- mout(MWHEN);}
- BLOCK { endBlock(NULL,CCNO);
- MBEEENDBLOCK(); mout(MENDWHEN);}
+ HDO {}
+ BLOCK
| WHEN_CLAUSE_LIST
HWHEN
HIDENTIFIER
- HDO { beginBlock(KCON); mout(MIDENTIFIER);
- OBSBLOCK(); moutId($3);
- mout(MWHEN);}
- BLOCK { endBlock(NULL,CCNO);
- MBEEENDBLOCK(); mout(MENDWHEN);}
+ HDO {}
+ BLOCK
;
MBEE_OTWI_CLAUS : /*EMPT*/
- | HOTHERWISE {OBSBLOCK(); mout(MOTHERWISE);}
+ | HOTHERWISE {}
- BLOCK {MBEEENDBLOCK();mout(MENDOTHERWISE);}
+ BLOCK
;
-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);}
+ACTIVATOR : HACTIVATE
+ | HREACTIVATE
+ ;
+SCHEDULE : /*EMPT*/
+ | ATDELAY EXPRESSION {}
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);}
+ | BEFOREAFTER {}
+ EXPRESSION
+ ;
+ATDELAY : HAT
+ | HDELAY
+ ;
+BEFOREAFTER : HBEFORE
+ | HAFTER
+ ;
+PRIOR : /*EMPT*/
+ | HPRIOR
;
/* GRAMATIKK FOR SETNINGER OG DEKLARASJONER */
MODULSTATEMENT : HWHILE
EXPRESSION
- HDO { STOPOBSBLOCK(); mout(MWHILE);
- OBSBLOCK();}
- BLOCK { MBEEENDBLOCK(); mout(MENDWHILE);
- $$=STATEMENT;}
+ HDO {}
+ BLOCK
| HIF
EXPRESSION
- HTHEN { STOPOBSBLOCK(); mout(MIF);
- OBSBLOCK();}
- BLOCK { MBEEENDBLOCK();}
- MBEE_ELSE_PART { mout(MENDIF);
- $$=STATEMENT;}
+ HTHEN {}
+ BLOCK {}
+ MBEE_ELSE_PART
| HFOR
HIDENTIFIER
- HASSIGN { STOPOBSBLOCK(); mout(MIDENTIFIER);
- moutId($2);}
+ HASSIGN {}
FOR_LIST
- HDO { beginBlock(KFOR);
- if($3==HASSIGNVALUE) mout(MFOR);
- else mout(MFORR);
- OBSBLOCK(); mout(MFORDO);}
- BLOCK { MBEEENDBLOCK();
- endBlock(NULL,CCNO); mout(MENDFOR);
- $$=STATEMENT;}
+ HDO {}
+ BLOCK
| GOTO
- EXPRESSION { mout(MGOTO);
- STOPOBSBLOCK(); $$=STATEMENT;}
+ EXPRESSION
| HINSPECT
- EXPRESSION { mout(MINSPECT);
- STOPOBSBLOCK();
- beginBlock(KINSP);}
+ EXPRESSION {}
CONN_STATE_R_PT
- { endBlock(NULL,CCNO);}
- MBEE_OTWI_CLAUS { mout(MENDINSPECT);
- $$=STATEMENT;}
- | HINNER { STOPOBSBLOCK(); mout(MINNER);
- regInner(); $$=STATEMENT;}
+ {}
+ MBEE_OTWI_CLAUS
+ | HINNER
| HIDENTIFIER
HLABELSEPARATOR
- { STOPOBSBLOCK();
- regDecl($1, TLABEL, KSIMPLE, categ);
mout(MLABEL);
- moutId($1);
- mout(MENDLABEL);}
- DECLSTATEMENT { if($4<=DECLARATION)
- { yerror (27);
- $$=DECLARATION;}
- else $$=$4;}
+ {}
+ DECLSTATEMENT
| EXPRESSION_SIMP
HBEGIN
- { $<ident>$=$1; }
+ {}
IMPORT_SPEC_MODULE
- { mout(MPRBLOCK);
- prefquantident=$1;
- beginBlock(KPRBLK);}
+ {}
MBEE_DECLSTMS
- HEND { endBlock(NULL,CCNO); mout(MENDPRBLOCK);
- $$=STATEMENT;}
+ HEND
| EXPRESSION_SIMP HBEGIN error HSTATEMENTSEPARATOR
- MBEE_DECLSTMS HEND { $$=STATEMENT;
- endBlock(NULL,CCNO); mout(MENDPRBLOCK);}
+ MBEE_DECLSTMS HEND
| 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;}
+ HEND
| MBEE_TYPE HPROCEDURE
HIDENTIFIER
- { MBEENEWBLOCK(); mout(MPROCEDURE);
- regDecl($3, type, KPROC, categ);
- beginBlock(KPROC);}
- HEADING BLOCK { endBlock(NULL,CCNO); $$=DECLARATION;
- mout(MENDPROCEDURE);}
+ {}
+ HEADING BLOCK
| 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);}
+ BLOCK
| 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);}
+ BLOCK
+ | EXT_DECLARATION
+ | /*EMPT*/
+ ;
+IMPORT_SPEC_MODULE:
;
DECLSTATEMENT : MODULSTATEMENT
| TYPE
HIDENTIFIER
MBEE_CONSTANT
HPAREXPSEPARATOR
- { MBEENEWBLOCK();
- kind=KSIMPLE;
- regDecl($2, type, KSIMPLE, categ);
- categ=CLOCAL;}
- IDENTIFIER_LISTC { $$=DECLARATION;}
+ {}
+ IDENTIFIER_LISTC
| TYPE
HIDENTIFIER
MBEE_CONSTANT
- { MBEENEWBLOCK();
- regDecl($2, type, KSIMPLE, categ);
- categ=CLOCAL; $$=DECLARATION;}
| MBEE_TYPE
- HARRAY { MBEENEWBLOCK();
- kind=KARRAY;}
- ARR_SEGMENT_LIST { $$=DECLARATION;}
+ HARRAY {}
+ ARR_SEGMENT_LIST
| HSWITCH
HIDENTIFIER
- HASSIGN { MBEENEWBLOCK(); mout(MIDENTIFIER);
- moutId($2);
- regDecl($2, TLABEL, KARRAY, categ);}
- SWITCH_LIST { $$=DECLARATION;
- mout(MSWITCH);
- mout(MENDSWITCH);}
+ HASSIGN {}
+ SWITCH_LIST
;
-BLOCK : DECLSTATEMENT { if($1<=DECLARATION)yerror (29);}
+BLOCK : DECLSTATEMENT
| HBEGIN MBEE_DECLSTMS HEND
| HBEGIN error HSTATEMENTSEPARATOR MBEE_DECLSTMS HEND
| HBEGIN error HEND
;
-MBEE_DECLSTMS : MBEE_DECLSTMSU { if($1<=DECLARATION)yerror (28);
- $$=$1;}
+MBEE_DECLSTMS : MBEE_DECLSTMSU
;
-MBEE_DECLSTMSU : DECLSTATEMENT { $$=$1;}
+MBEE_DECLSTMSU : DECLSTATEMENT
| MBEE_DECLSTMSU
HSTATEMENTSEPARATOR
- DECLSTATEMENT { if($1>=STATEMENT && $3<=DECLARATION)
- yerror (26);
- $$=$3;}
- ;
-MODULS : MODULSTATEMENT { if($1==DECLARATION)
- {separat_comp=TRUE;gettimestamp();}
- $$=$1;}
+ DECLSTATEMENT
+ ;
+MODULS : MODULSTATEMENT
| 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
@@ -855,47 +686,35 @@
;
ARR_SEGMENT : ARRAY_SEGMENT
HBEGPAR
- BAUND_PAIR_LIST HENDPAR { mout(MARRAY);
- mout(MENDARRAY);
- setArrayDim($3);}
+ BAUND_PAIR_LIST HENDPAR
;
-ARRAY_SEGMENT : ARRAY_SEGMENT_EL { mout(MENDSEP);
- mout(MARRAYSEP);}
+ARRAY_SEGMENT : ARRAY_SEGMENT_EL {}
| ARRAY_SEGMENT_EL
HPAREXPSEPARATOR
- ARRAY_SEGMENT { mout(MARRAYSEP);}
+ ARRAY_SEGMENT
;
-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;}
+ARRAY_SEGMENT_EL: HIDENTIFIER
+ ;
+BAUND_PAIR_LIST : BAUND_PAIR
| BAUND_PAIR
HPAREXPSEPARATOR
- BAUND_PAIR_LIST { mout(MBOUNDSEP);
- $$=$3+1;}
+ BAUND_PAIR_LIST
;
BAUND_PAIR : EXPRESSION
HLABELSEPARATOR
- EXPRESSION { mout(MBOUNDPARSEP);}
+ EXPRESSION
;
-SWITCH_LIST : EXPRESSION { mout(MENDSEP);
- mout(MSWITCHSEP);}
+SWITCH_LIST : EXPRESSION
| EXPRESSION
HPAREXPSEPARATOR
- SWITCH_LIST { mout(MSWITCHSEP);}
+ SWITCH_LIST
;
-HEADING : MBEE_FMAL_PAR_P HSTATEMENTSEPARATOR { kind=KNOKD;}
- MBEE_MODE_PART { categ=CSPEC;}
- MBEE_SPEC_PART { kind=KNOKD;}
- MBEE_PROT_PART { categ=CVIRT;}
+HEADING : MBEE_FMAL_PAR_P HSTATEMENTSEPARATOR {}
+ MBEE_MODE_PART {}
+ MBEE_SPEC_PART {}
+ MBEE_PROT_PART {}
MBEE_VIRT_PART
- { categ=CLOCAL;}
;
MBEE_FMAL_PAR_P : /*EMPT*/
| FMAL_PAR_PART
@@ -906,10 +725,10 @@
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 {}
+LISTV : HIDENTIFIER
+ | FPP_CATEG HDOTDOTDOT
+ | HIDENTIFIER {}
+ HPAREXPSEPARATOR LISTV
| FPP_SPEC
| FPP_SPEC
HPAREXPSEPARATOR LISTV
@@ -920,36 +739,28 @@
FPP_MBEE_LISTV : /*EMPT*/
| FPP_LISTV
;
-FPP_LISTV : FPP_CATEG HDOTDOTDOT { regDecl(varargsid,
TVARARGS, KNOKD, categ);}
+FPP_LISTV : FPP_CATEG HDOTDOTDOT
| 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;}
+ | /*EMPT*/
;
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 {}
+ {}
+ FPP_HEADING {} { /* Yes, two "final" actions. */ }
+ ;
+IDENTIFIER_LISTV: HIDENTIFIER
+ | HDOTDOTDOT
+ | HIDENTIFIER {}
+ HPAREXPSEPARATOR IDENTIFIER_LISTV
;
MBEE_MODE_PART : /*EMPT*/
| MODE_PART
@@ -970,15 +781,15 @@
| VALUE_PART VAR_PART NAME_PART
| VALUE_PART NAME_PART VAR_PART
;
-NAME_PART : HNAME { categ=CNAME;}
+NAME_PART : HNAME {}
IDENTIFIER_LISTV
HSTATEMENTSEPARATOR
;
-VAR_PART : HVAR { categ=CVAR;}
+VAR_PART : HVAR {}
IDENTIFIER_LISTV
HSTATEMENTSEPARATOR
;
-VALUE_PART : HVALUE { categ=CVALUE;}
+VALUE_PART : HVALUE {}
IDENTIFIER_LISTV HSTATEMENTSEPARATOR
;
MBEE_SPEC_PART : /*EMPT*/
@@ -989,32 +800,25 @@
;
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;}
+SPECIFIER : TYPE
| MBEE_TYPE
- HARRAY { kind=KARRAY;}
- | HLABEL { type=TLABEL;
- kind=KSIMPLE;}
- | HSWITCH { type=TLABEL;
- kind=KARRAY;}
+ HARRAY
+ | HLABEL
+ | HSWITCH
;
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
@@ -1027,12 +831,12 @@
| PROTECTION_PART PROT_SPECIFIER
IDENTIFIER_LIST HSTATEMENTSEPARATOR
;
-PROT_SPECIFIER : HHIDDEN { categ=CHIDEN;}
- | HPROTECTED { categ=CPROT;}
+PROT_SPECIFIER : HHIDDEN
+ | HPROTECTED
| HHIDDEN
- HPROTECTED { categ=CHIPRO;}
+ HPROTECTED
| HPROTECTED
- HHIDDEN { categ=CHIPRO;}
+ HHIDDEN
;
MBEE_VIRT_PART : /*EMPT*/
| VIRTUAL_PART
@@ -1041,150 +845,109 @@
HLABELSEPARATOR
MBEE_SPEC_PART
;
-IDENTIFIER_LIST : HIDENTIFIER { regDecl($1, type, kind, categ);}
+IDENTIFIER_LIST : HIDENTIFIER
| IDENTIFIER_LIST HPAREXPSEPARATOR
- HIDENTIFIER { regDecl($3, type, kind, categ);}
+ HIDENTIFIER
;
IDENTIFIER_LISTC: HIDENTIFIER
- MBEE_CONSTANT { regDecl($1, type, kind, categ);
- categ=CLOCAL;}
+ MBEE_CONSTANT
| IDENTIFIER_LISTC HPAREXPSEPARATOR
HIDENTIFIER
- MBEE_CONSTANT { regDecl($3, type, kind, categ);
- categ=CLOCAL;}
+ MBEE_CONSTANT
;
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);}
+ {}
+ EXPRESSION
;
/* GRAMATIKK FOR UTTRYKK */
-EXPRESSION : EXPRESSION_SIMP {}
+EXPRESSION : EXPRESSION_SIMP
| HIF
EXPRESSION
HTHEN
EXPRESSION
HELSE
- EXPRESSION { mout(MELSEE);
- mout(MIFE);}
+ EXPRESSION
;
EXPRESSION_SIMP : EXPRESSION_SIMP
HASSIGN
- EXPRESSION { if($2==HASSIGNREF)mout(MASSIGNR);
- else mout(MASSIGN);$$=NULL;}
+ EXPRESSION
|
EXPRESSION_SIMP
HCONC
- EXPRESSION_SIMP { mout(MCONC);$$=NULL;}
+ EXPRESSION_SIMP
| EXPRESSION_SIMP HOR
HELSE
EXPRESSION_SIMP
- %prec HORELSE { mout(MORELSEE);$$=NULL;}
+ %prec HORELSE
| EXPRESSION_SIMP HAND
HTHEN
EXPRESSION_SIMP
- %prec HANDTHEN { mout(MANDTHENE);$$=NULL;}
+ %prec HANDTHEN
| EXPRESSION_SIMP
- HEQV EXPRESSION_SIMP { mout(MEQV);$$=NULL;}
+ HEQV EXPRESSION_SIMP
| EXPRESSION_SIMP
- HIMP EXPRESSION_SIMP { mout(MIMP);$$=NULL;}
+ HIMP EXPRESSION_SIMP
| EXPRESSION_SIMP
- HOR EXPRESSION_SIMP { mout(MOR);$$=NULL;}
+ HOR EXPRESSION_SIMP
| EXPRESSION_SIMP
- HAND EXPRESSION_SIMP { mout(MAND);$$=NULL;}
- | HNOT EXPRESSION_SIMP { mout(MNOT);$$=NULL;}
+ HAND EXPRESSION_SIMP
+ | HNOT EXPRESSION_SIMP
| 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;}
+ EXPRESSION_SIMP
| 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;}
+ EXPRESSION HENDPAR
+ | HTEXTKONST
+ | HCHARACTERKONST
+ | HREALKONST
+ | HINTEGERKONST
+ | HBOOLEANKONST
+ | HNONE
| HIDENTIFIER
- { $<ident>$=$1;}
- MBEE_ARG_R_PT {}
- | HTHIS HIDENTIFIER { mout(MTHIS);
- moutId($2);$$=NULL;}
+ {}
+ MBEE_ARG_R_PT
+ | HTHIS HIDENTIFIER
| HNEW
HIDENTIFIER
- ARG_R_PT { mout(MNEWARG);
- moutId($2);$$=NULL;}
+ ARG_R_PT
| EXPRESSION_SIMP
HDOT
- EXPRESSION_SIMP { mout(MDOT);$$=NULL;}
+ EXPRESSION_SIMP
| EXPRESSION_SIMP
- HQUA HIDENTIFIER { mout(MQUA);
- moutId($3);$$=NULL;}
+ HQUA HIDENTIFIER
;
-ARG_R_PT : /*EMPTY*/ { mout(MENDSEP);}
+ARG_R_PT : /*EMPTY*/
| HBEGPAR
ARGUMENT_LIST HENDPAR
;
-MBEE_ARG_R_PT : /*EMPTY*/ { mout(MIDENTIFIER);
- moutId($<ident>0);
- $$=$<ident>0;}
+MBEE_ARG_R_PT : /*EMPTY*/
| HBEGPAR
- ARGUMENT_LIST HENDPAR { mout(MARGUMENT);
- moutId($<ident>0);}
+ ARGUMENT_LIST HENDPAR
;
-ARGUMENT_LIST : EXPRESSION { mout(MENDSEP);
- mout(MARGUMENTSEP);}
+ARGUMENT_LIST : EXPRESSION
| EXPRESSION
HPAREXPSEPARATOR
- ARGUMENT_LIST { mout(MARGUMENTSEP);}
+ ARGUMENT_LIST
;
%%
]])
@@ -1210,7 +973,6 @@
AT_CLEANUP
-
## ----------------- ##
## GNU pic Grammar. ##
## ----------------- ##
@@ -1222,32 +984,15 @@
# Bison once reported shift/reduce conflicts that it shouldn't have.
AT_DATA([[input.y]],
-[[%union {
- char *str;
- int n;
- double x;
- struct { double x, y; } pair;
- struct { double x; char *body; } if_data;
- struct { char *str; const char *filename; int lineno; } lstr;
- struct { double *v; int nv; int maxv; } dv;
- struct { double val; int is_multiplicative; } by;
- place pl;
- object *obj;
- corner crn;
- path *pth;
- object_spec *spec;
- saved_state *pstate;
- graphics_state state;
- object_type obtype;
-}
-
-%token <str> LABEL
-%token <str> VARIABLE
-%token <x> NUMBER
-%token <lstr> TEXT
-%token <lstr> COMMAND_LINE
-%token <str> DELIMITED
-%token <n> ORDINAL
+[[%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
@@ -1406,44 +1151,20 @@
%right '!'
%right '^'
-%type <x> expr any_expr text_expr
-%type <by> optional_by
-%type <pair> expr_pair position_not_place
-%type <if_data> simple_if
-%type <obj> nth_primitive
-%type <crn> corner
-%type <pth> path label_path relative_path
-%type <pl> place label element element_list middle_element_list
-%type <spec> object_spec
-%type <pair> position
-%type <obtype> object_type
-%type <n> optional_ordinal_last ordinal
-%type <str> until
-%type <dv> sprintf_args
-%type <lstr> text print_args print_arg
-
%%
top:
optional_separator
| element_list
- {
- if (olist.head)
- print_picture(olist.head);
- }
;
-
element_list:
optional_separator middle_element_list optional_separator
- { $$ = $2; }
;
middle_element_list:
element
- { $$ = $1; }
| middle_element_list separator element
- { $$ = $1; }
;
optional_separator:
@@ -1458,844 +1179,191 @@
placeless_element:
VARIABLE '=' any_expr
- {
- define_variable($1, $3);
- a_delete $1;
- }
| VARIABLE ':' '=' any_expr
- {
- place *p = lookup_label($1);
- if (!p) {
- lex_error("variable `%1' not defined", $1);
- YYABORT;
- }
- p->obj = 0;
- p->x = $4;
- p->y = 0.0;
- a_delete $1;
- }
| UP
- { current_direction = UP_DIRECTION; }
| DOWN
- { current_direction = DOWN_DIRECTION; }
| LEFT
- { current_direction = LEFT_DIRECTION; }
| RIGHT
- { current_direction = RIGHT_DIRECTION; }
| COMMAND_LINE
- {
- olist.append(make_command_object($1.str, $1.filename,
- $1.lineno));
- }
| COMMAND print_args
- {
- olist.append(make_command_object($2.str, $2.filename,
- $2.lineno));
- }
| PRINT print_args
- {
- fprintf(stderr, "%s\n", $2.str);
- a_delete $2.str;
- fflush(stderr);
- }
| SH
- { delim_flag = 1; }
+ {}
DELIMITED
- {
- delim_flag = 0;
- if (safer_flag)
- lex_error("unsafe to run command `%1'", $3);
- else
- system($3);
- a_delete $3;
- }
| COPY TEXT
- {
- if (yychar < 0)
- do_lookahead();
- do_copy($2.str);
- // do not delete the filename
- }
| COPY TEXT THRU
- { delim_flag = 2; }
+ {}
DELIMITED
- { delim_flag = 0; }
+ {}
until
- {
- if (yychar < 0)
- do_lookahead();
- copy_file_thru($2.str, $5, $7);
- // do not delete the filename
- a_delete $5;
- a_delete $7;
- }
| COPY THRU
- { delim_flag = 2; }
+ {}
DELIMITED
- { delim_flag = 0; }
+ {}
until
- {
- if (yychar < 0)
- do_lookahead();
- copy_rest_thru($4, $6);
- a_delete $4;
- a_delete $6;
- }
| FOR VARIABLE '=' expr TO expr optional_by DO
- { delim_flag = 1; }
+ {}
DELIMITED
- {
- delim_flag = 0;
- if (yychar < 0)
- do_lookahead();
- do_for($2, $4, $6, $7.is_multiplicative, $7.val, $10);
- }
| simple_if
- {
- if (yychar < 0)
- do_lookahead();
- if ($1.x != 0.0)
- push_body($1.body);
- a_delete $1.body;
- }
| simple_if ELSE
- { delim_flag = 1; }
+ {}
DELIMITED
- {
- delim_flag = 0;
- if (yychar < 0)
- do_lookahead();
- if ($1.x != 0.0)
- push_body($1.body);
- else
- push_body($4);
- a_delete $1.body;
- a_delete $4;
- }
| reset_variables
| RESET
- { define_variable("scale", 1.0); }
;
reset_variables:
RESET VARIABLE
- {
- reset($2);
- a_delete $2;
- }
| reset_variables VARIABLE
- {
- reset($2);
- a_delete $2;
- }
| reset_variables ',' VARIABLE
- {
- reset($3);
- a_delete $3;
- }
;
print_args:
print_arg
- { $$ = $1; }
| print_args print_arg
- {
- $$.str = new char[strlen($1.str) + strlen($2.str) + 1];
- strcpy($$.str, $1.str);
- strcat($$.str, $2.str);
- a_delete $1.str;
- a_delete $2.str;
- if ($1.filename) {
- $$.filename = $1.filename;
- $$.lineno = $1.lineno;
- }
- else if ($2.filename) {
- $$.filename = $2.filename;
- $$.lineno = $2.lineno;
- }
- }
;
print_arg:
expr %prec ','
- {
- $$.str = new char[GDIGITS + 1];
- sprintf($$.str, "%g", $1);
- $$.filename = 0;
- $$.lineno = 0;
- }
| text
- { $$ = $1; }
| position %prec ','
- {
- $$.str = new char[GDIGITS + 2 + GDIGITS + 1];
- sprintf($$.str, "%g, %g", $1.x, $1.y);
- $$.filename = 0;
- $$.lineno = 0;
- }
;
simple_if:
IF any_expr THEN
- { delim_flag = 1; }
+ {}
DELIMITED
- {
- delim_flag = 0;
- $$.x = $2;
- $$.body = $5;
- }
;
until:
/* empty */
- { $$ = 0; }
| UNTIL TEXT
- { $$ = $2.str; }
;
any_expr:
expr
- { $$ = $1; }
| text_expr
- { $$ = $1; }
;
text_expr:
text EQUALEQUAL text
- {
- $$ = strcmp($1.str, $3.str) == 0;
- a_delete $1.str;
- a_delete $3.str;
- }
| text NOTEQUAL text
- {
- $$ = strcmp($1.str, $3.str) != 0;
- a_delete $1.str;
- a_delete $3.str;
- }
| text_expr ANDAND text_expr
- { $$ = ($1 != 0.0 && $3 != 0.0); }
| text_expr ANDAND expr
- { $$ = ($1 != 0.0 && $3 != 0.0); }
| expr ANDAND text_expr
- { $$ = ($1 != 0.0 && $3 != 0.0); }
| text_expr OROR text_expr
- { $$ = ($1 != 0.0 || $3 != 0.0); }
| text_expr OROR expr
- { $$ = ($1 != 0.0 || $3 != 0.0); }
| expr OROR text_expr
- { $$ = ($1 != 0.0 || $3 != 0.0); }
| '!' text_expr
- { $$ = ($2 == 0.0); }
;
-
optional_by:
/* empty */
- {
- $$.val = 1.0;
- $$.is_multiplicative = 0;
- }
| BY expr
- {
- $$.val = $2;
- $$.is_multiplicative = 0;
- }
| BY '*' expr
- {
- $$.val = $3;
- $$.is_multiplicative = 1;
- }
;
element:
object_spec
- {
- $$.obj = $1->make_object(¤t_position,
- ¤t_direction);
- if ($$.obj == 0)
- YYABORT;
- delete $1;
- if ($$.obj)
- olist.append($$.obj);
- else {
- $$.x = current_position.x;
- $$.y = current_position.y;
- }
- }
| LABEL ':' optional_separator element
- {
- $$ = $4;
- define_label($1, & $$);
- a_delete $1;
- }
| LABEL ':' optional_separator position_not_place
- {
- $$.obj = 0;
- $$.x = $4.x;
- $$.y = $4.y;
- define_label($1, & $$);
- a_delete $1;
- }
| LABEL ':' optional_separator place
- {
- $$ = $4;
- define_label($1, & $$);
- a_delete $1;
- }
- | '{'
- {
- $<state>$.x = current_position.x;
- $<state>$.y = current_position.y;
- $<state>$.dir = current_direction;
- }
- element_list '}'
- {
- current_position.x = $<state>2.x;
- current_position.y = $<state>2.y;
- current_direction = $<state>2.dir;
- }
+ | '{}'
+ {}
optional_element
- {
- $$ = $3;
- }
| placeless_element
- {
- $$.obj = 0;
- $$.x = current_position.x;
- $$.y = current_position.y;
- }
;
optional_element:
/* empty */
- {}
| element
- {}
;
object_spec:
BOX
- { $$ = new object_spec(BOX_OBJECT); }
| CIRCLE
- { $$ = new object_spec(CIRCLE_OBJECT); }
| ELLIPSE
- { $$ = new object_spec(ELLIPSE_OBJECT); }
| ARC
- {
- $$ = new object_spec(ARC_OBJECT);
- $$->dir = current_direction;
- }
| LINE
- {
- $$ = new object_spec(LINE_OBJECT);
- lookup_variable("lineht", & $$->segment_height);
- lookup_variable("linewid", & $$->segment_width);
- $$->dir = current_direction;
- }
| ARROW
- {
- $$ = new object_spec(ARROW_OBJECT);
- lookup_variable("lineht", & $$->segment_height);
- lookup_variable("linewid", & $$->segment_width);
- $$->dir = current_direction;
- }
| MOVE
- {
- $$ = new object_spec(MOVE_OBJECT);
- lookup_variable("moveht", & $$->segment_height);
- lookup_variable("movewid", & $$->segment_width);
- $$->dir = current_direction;
- }
| SPLINE
- {
- $$ = new object_spec(SPLINE_OBJECT);
- lookup_variable("lineht", & $$->segment_height);
- lookup_variable("linewid", & $$->segment_width);
- $$->dir = current_direction;
- }
| text %prec TEXT
- {
- $$ = new object_spec(TEXT_OBJECT);
- $$->text = new text_item($1.str, $1.filename, $1.lineno);
- }
| PLOT expr
- {
- $$ = new object_spec(TEXT_OBJECT);
- $$->text = new text_item(format_number(0, $2), 0, -1);
- }
| PLOT expr text
- {
- $$ = new object_spec(TEXT_OBJECT);
- $$->text = new text_item(format_number($3.str, $2),
- $3.filename, $3.lineno);
- a_delete $3.str;
- }
| '['
- {
- saved_state *p = new saved_state;
- $<pstate>$ = p;
- p->x = current_position.x;
- p->y = current_position.y;
- p->dir = current_direction;
- p->tbl = current_table;
- p->prev = current_saved_state;
- current_position.x = 0.0;
- current_position.y = 0.0;
- current_table = new PTABLE(place);
- current_saved_state = p;
- olist.append(make_mark_object());
- }
+ {}
element_list ']'
- {
- current_position.x = $<pstate>2->x;
- current_position.y = $<pstate>2->y;
- current_direction = $<pstate>2->dir;
- $$ = new object_spec(BLOCK_OBJECT);
- olist.wrap_up_block(& $$->oblist);
- $$->tbl = current_table;
- current_table = $<pstate>2->tbl;
- current_saved_state = $<pstate>2->prev;
- delete $<pstate>2;
- }
| object_spec HEIGHT expr
- {
- $$ = $1;
- $$->height = $3;
- $$->flags |= HAS_HEIGHT;
- }
| object_spec RADIUS expr
- {
- $$ = $1;
- $$->radius = $3;
- $$->flags |= HAS_RADIUS;
- }
| object_spec WIDTH expr
- {
- $$ = $1;
- $$->width = $3;
- $$->flags |= HAS_WIDTH;
- }
| object_spec DIAMETER expr
- {
- $$ = $1;
- $$->radius = $3/2.0;
- $$->flags |= HAS_RADIUS;
- }
| object_spec expr %prec HEIGHT
- {
- $$ = $1;
- $$->flags |= HAS_SEGMENT;
- switch ($$->dir) {
- case UP_DIRECTION:
- $$->segment_pos.y += $2;
- break;
- case DOWN_DIRECTION:
- $$->segment_pos.y -= $2;
- break;
- case RIGHT_DIRECTION:
- $$->segment_pos.x += $2;
- break;
- case LEFT_DIRECTION:
- $$->segment_pos.x -= $2;
- break;
- }
- }
| object_spec UP
- {
- $$ = $1;
- $$->dir = UP_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.y += $$->segment_height;
- }
| object_spec UP expr
- {
- $$ = $1;
- $$->dir = UP_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.y += $3;
- }
| object_spec DOWN
- {
- $$ = $1;
- $$->dir = DOWN_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.y -= $$->segment_height;
- }
| object_spec DOWN expr
- {
- $$ = $1;
- $$->dir = DOWN_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.y -= $3;
- }
| object_spec RIGHT
- {
- $$ = $1;
- $$->dir = RIGHT_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x += $$->segment_width;
- }
| object_spec RIGHT expr
- {
- $$ = $1;
- $$->dir = RIGHT_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x += $3;
- }
| object_spec LEFT
- {
- $$ = $1;
- $$->dir = LEFT_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x -= $$->segment_width;
- }
| object_spec LEFT expr
- {
- $$ = $1;
- $$->dir = LEFT_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x -= $3;
- }
| object_spec FROM position
- {
- $$ = $1;
- $$->flags |= HAS_FROM;
- $$->from.x = $3.x;
- $$->from.y = $3.y;
- }
| object_spec TO position
- {
- $$ = $1;
- if ($$->flags & HAS_SEGMENT)
- $$->segment_list = new segment($$->segment_pos,
- $$->segment_is_absolute,
- $$->segment_list);
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x = $3.x;
- $$->segment_pos.y = $3.y;
- $$->segment_is_absolute = 1;
- $$->flags |= HAS_TO;
- $$->to.x = $3.x;
- $$->to.y = $3.y;
- }
| object_spec AT position
- {
- $$ = $1;
- $$->flags |= HAS_AT;
- $$->at.x = $3.x;
- $$->at.y = $3.y;
- if ($$->type != ARC_OBJECT) {
- $$->flags |= HAS_FROM;
- $$->from.x = $3.x;
- $$->from.y = $3.y;
- }
- }
| object_spec WITH path
- {
- $$ = $1;
- $$->flags |= HAS_WITH;
- $$->with = $3;
- }
| object_spec WITH position %prec ','
- {
- $$ = $1;
- $$->flags |= HAS_WITH;
- position pos;
- pos.x = $3.x;
- pos.y = $3.y;
- $$->with = new path(pos);
- }
| object_spec BY expr_pair
- {
- $$ = $1;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x += $3.x;
- $$->segment_pos.y += $3.y;
- }
| object_spec THEN
- {
- $$ = $1;
- if ($$->flags & HAS_SEGMENT) {
- $$->segment_list = new segment($$->segment_pos,
- $$->segment_is_absolute,
- $$->segment_list);
- $$->flags &= ~HAS_SEGMENT;
- $$->segment_pos.x = $$->segment_pos.y = 0.0;
- $$->segment_is_absolute = 0;
- }
- }
| object_spec SOLID
- {
- $$ = $1; // nothing
- }
| object_spec DOTTED
- {
- $$ = $1;
- $$->flags |= IS_DOTTED;
- lookup_variable("dashwid", & $$->dash_width);
- }
| object_spec DOTTED expr
- {
- $$ = $1;
- $$->flags |= IS_DOTTED;
- $$->dash_width = $3;
- }
| object_spec DASHED
- {
- $$ = $1;
- $$->flags |= IS_DASHED;
- lookup_variable("dashwid", & $$->dash_width);
- }
| object_spec DASHED expr
- {
- $$ = $1;
- $$->flags |= IS_DASHED;
- $$->dash_width = $3;
- }
| object_spec FILL
- {
- $$ = $1;
- $$->flags |= IS_DEFAULT_FILLED;
- }
| object_spec FILL expr
- {
- $$ = $1;
- $$->flags |= IS_FILLED;
- $$->fill = $3;
- }
| object_spec SHADED text
- {
- $$ = $1;
- $$->flags |= (IS_SHADED | IS_FILLED);
- $$->shaded = new char[strlen($3.str)+1];
- strcpy($$->shaded, $3.str);
- }
| object_spec COLORED text
- {
- $$ = $1;
- $$->flags |= (IS_SHADED | IS_OUTLINED | IS_FILLED);
- $$->shaded = new char[strlen($3.str)+1];
- strcpy($$->shaded, $3.str);
- $$->outlined = new char[strlen($3.str)+1];
- strcpy($$->outlined, $3.str);
- }
| object_spec OUTLINED text
- {
- $$ = $1;
- $$->flags |= IS_OUTLINED;
- $$->outlined = new char[strlen($3.str)+1];
- strcpy($$->outlined, $3.str);
- }
| object_spec CHOP
- {
- $$ = $1;
- // line chop chop means line chop 0 chop 0
- if ($$->flags & IS_DEFAULT_CHOPPED) {
- $$->flags |= IS_CHOPPED;
- $$->flags &= ~IS_DEFAULT_CHOPPED;
- $$->start_chop = $$->end_chop = 0.0;
- }
- else if ($$->flags & IS_CHOPPED) {
- $$->end_chop = 0.0;
- }
- else {
- $$->flags |= IS_DEFAULT_CHOPPED;
- }
- }
| object_spec CHOP expr
- {
- $$ = $1;
- if ($$->flags & IS_DEFAULT_CHOPPED) {
- $$->flags |= IS_CHOPPED;
- $$->flags &= ~IS_DEFAULT_CHOPPED;
- $$->start_chop = 0.0;
- $$->end_chop = $3;
- }
- else if ($$->flags & IS_CHOPPED) {
- $$->end_chop = $3;
- }
- else {
- $$->start_chop = $$->end_chop = $3;
- $$->flags |= IS_CHOPPED;
- }
- }
| object_spec SAME
- {
- $$ = $1;
- $$->flags |= IS_SAME;
- }
| object_spec INVISIBLE
- {
- $$ = $1;
- $$->flags |= IS_INVISIBLE;
- }
| object_spec LEFT_ARROW_HEAD
- {
- $$ = $1;
- $$->flags |= HAS_LEFT_ARROW_HEAD;
- }
| object_spec RIGHT_ARROW_HEAD
- {
- $$ = $1;
- $$->flags |= HAS_RIGHT_ARROW_HEAD;
- }
| object_spec DOUBLE_ARROW_HEAD
- {
- $$ = $1;
- $$->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD);
- }
| object_spec CW
- {
- $$ = $1;
- $$->flags |= IS_CLOCKWISE;
- }
| object_spec CCW
- {
- $$ = $1;
- $$->flags &= ~IS_CLOCKWISE;
- }
| object_spec text %prec TEXT
- {
- $$ = $1;
- text_item **p;
- for (p = & $$->text; *p; p = &(*p)->next)
- ;
- *p = new text_item($2.str, $2.filename, $2.lineno);
- }
| object_spec LJUST
- {
- $$ = $1;
- if ($$->text) {
- text_item *p;
- for (p = $$->text; p->next; p = p->next)
- ;
- p->adj.h = LEFT_ADJUST;
- }
- }
| object_spec RJUST
- {
- $$ = $1;
- if ($$->text) {
- text_item *p;
- for (p = $$->text; p->next; p = p->next)
- ;
- p->adj.h = RIGHT_ADJUST;
- }
- }
| object_spec ABOVE
- {
- $$ = $1;
- if ($$->text) {
- text_item *p;
- for (p = $$->text; p->next; p = p->next)
- ;
- p->adj.v = ABOVE_ADJUST;
- }
- }
| object_spec BELOW
- {
- $$ = $1;
- if ($$->text) {
- text_item *p;
- for (p = $$->text; p->next; p = p->next)
- ;
- p->adj.v = BELOW_ADJUST;
- }
- }
| object_spec THICKNESS expr
- {
- $$ = $1;
- $$->flags |= HAS_THICKNESS;
- $$->thickness = $3;
- }
| object_spec ALIGNED
- {
- $$ = $1;
- $$->flags |= IS_ALIGNED;
- }
;
text:
TEXT
- { $$ = $1; }
| SPRINTF '(' TEXT sprintf_args ')'
- {
- $$.filename = $3.filename;
- $$.lineno = $3.lineno;
- $$.str = do_sprintf($3.str, $4.v, $4.nv);
- a_delete $4.v;
- a_delete $3.str;
- }
;
sprintf_args:
/* empty */
- {
- $$.v = 0;
- $$.nv = 0;
- $$.maxv = 0;
- }
| sprintf_args ',' expr
- {
- $$ = $1;
- if ($$.nv >= $$.maxv) {
- if ($$.nv == 0) {
- $$.v = new double[4];
- $$.maxv = 4;
- }
- else {
- double *oldv = $$.v;
- $$.maxv *= 2;
- $$.v = new double[$$.maxv];
- memcpy($$.v, oldv, $$.nv*sizeof(double));
- a_delete oldv;
- }
- }
- $$.v[$$.nv] = $3;
- $$.nv += 1;
- }
;
position:
position_not_place
- { $$ = $1; }
| place
- {
- position pos = $1;
- $$.x = pos.x;
- $$.y = pos.y;
- }
;
position_not_place:
expr_pair
- { $$ = $1; }
| position '+' expr_pair
- {
- $$.x = $1.x + $3.x;
- $$.y = $1.y + $3.y;
- }
| position '-' expr_pair
- {
- $$.x = $1.x - $3.x;
- $$.y = $1.y - $3.y;
- }
| '(' position ',' position ')'
- {
- $$.x = $2.x;
- $$.y = $4.y;
- }
| expr between position AND position
- {
- $$.x = (1.0 - $1)*$3.x + $1*$5.x;
- $$.y = (1.0 - $1)*$3.y + $1*$5.y;
- }
| expr '<' position ',' position '>'
- {
- $$.x = (1.0 - $1)*$3.x + $1*$5.x;
- $$.y = (1.0 - $1)*$3.y + $1*$5.y;
- }
;
between:
@@ -2305,443 +1373,147 @@
expr_pair:
expr ',' expr
- {
- $$.x = $1;
- $$.y = $3;
- }
| '(' expr_pair ')'
- { $$ = $2; }
;
place:
/* line at A left == line (at A) left */
label %prec CHOP
- { $$ = $1; }
| label corner
- {
- path pth($2);
- if (!pth.follow($1, & $$))
- YYABORT;
- }
| corner label
- {
- path pth($1);
- if (!pth.follow($2, & $$))
- YYABORT;
- }
| corner OF label
- {
- path pth($1);
- if (!pth.follow($3, & $$))
- YYABORT;
- }
| HERE
- {
- $$.x = current_position.x;
- $$.y = current_position.y;
- $$.obj = 0;
- }
;
label:
LABEL
- {
- place *p = lookup_label($1);
- if (!p) {
- lex_error("there is no place `%1'", $1);
- YYABORT;
- }
- $$ = *p;
- a_delete $1;
- }
| nth_primitive
- { $$.obj = $1; }
| label '.' LABEL
- {
- path pth($3);
- if (!pth.follow($1, & $$))
- YYABORT;
- }
;
ordinal:
ORDINAL
- { $$ = $1; }
| '`' any_expr TH
- {
- // XXX Check for overflow (and non-integers?).
- $$ = (int)$2;
- }
;
optional_ordinal_last:
LAST
- { $$ = 1; }
| ordinal LAST
- { $$ = $1; }
;
nth_primitive:
ordinal object_type
- {
- int count = 0;
- object *p;
- for (p = olist.head; p != 0; p = p->next)
- if (p->type() == $2 && ++count == $1) {
- $$ = p;
- break;
- }
- if (p == 0) {
- lex_error("there is no %1%2 %3", $1, ordinal_postfix($1),
- object_type_name($2));
- YYABORT;
- }
- }
| optional_ordinal_last object_type
- {
- int count = 0;
- object *p;
- for (p = olist.tail; p != 0; p = p->prev)
- if (p->type() == $2 && ++count == $1) {
- $$ = p;
- break;
- }
- if (p == 0) {
- lex_error("there is no %1%2 last %3", $1,
- ordinal_postfix($1), object_type_name($2));
- YYABORT;
- }
- }
;
object_type:
BOX
- { $$ = BOX_OBJECT; }
| CIRCLE
- { $$ = CIRCLE_OBJECT; }
| ELLIPSE
- { $$ = ELLIPSE_OBJECT; }
| ARC
- { $$ = ARC_OBJECT; }
| LINE
- { $$ = LINE_OBJECT; }
| ARROW
- { $$ = ARROW_OBJECT; }
| SPLINE
- { $$ = SPLINE_OBJECT; }
| '[' ']'
- { $$ = BLOCK_OBJECT; }
| TEXT
- { $$ = TEXT_OBJECT; }
;
label_path:
'.' LABEL
- { $$ = new path($2); }
| label_path '.' LABEL
- {
- $$ = $1;
- $$->append($3);
- }
;
relative_path:
corner %prec CHOP
- { $$ = new path($1); }
/* 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
- { $$ = $1; }
| label_path corner
- {
- $$ = $1;
- $$->append($2);
- }
;
path:
relative_path
- { $$ = $1; }
| '(' relative_path ',' relative_path ')'
- {
- $$ = $2;
- $$->set_ypath($4);
- }
+ {}
/* The rest of these rules are a compatibility sop. */
| ORDINAL LAST object_type relative_path
- {
- lex_warning("`%1%2 last %3' in `with' argument ignored",
- $1, ordinal_postfix($1), object_type_name($3));
- $$ = $4;
- }
| LAST object_type relative_path
- {
- lex_warning("`last %1' in `with' argument ignored",
- object_type_name($2));
- $$ = $3;
- }
| ORDINAL object_type relative_path
- {
- lex_warning("`%1%2 %3' in `with' argument ignored",
- $1, ordinal_postfix($1), object_type_name($2));
- $$ = $3;
- }
| LABEL relative_path
- {
- lex_warning("initial `%1' in `with' argument ignored", $1);
- a_delete $1;
- $$ = $2;
- }
;
corner:
DOT_N
- { $$ = &object::north; }
| DOT_E
- { $$ = &object::east; }
| DOT_W
- { $$ = &object::west; }
| DOT_S
- { $$ = &object::south; }
| DOT_NE
- { $$ = &object::north_east; }
| DOT_SE
- { $$ = &object:: south_east; }
| DOT_NW
- { $$ = &object::north_west; }
| DOT_SW
- { $$ = &object::south_west; }
| DOT_C
- { $$ = &object::center; }
| DOT_START
- { $$ = &object::start; }
| DOT_END
- { $$ = &object::end; }
| TOP
- { $$ = &object::north; }
| BOTTOM
- { $$ = &object::south; }
| LEFT
- { $$ = &object::west; }
| RIGHT
- { $$ = &object::east; }
| UPPER LEFT
- { $$ = &object::north_west; }
| LOWER LEFT
- { $$ = &object::south_west; }
| UPPER RIGHT
- { $$ = &object::north_east; }
| LOWER RIGHT
- { $$ = &object::south_east; }
| LEFT_CORNER
- { $$ = &object::west; }
| RIGHT_CORNER
- { $$ = &object::east; }
| UPPER LEFT_CORNER
- { $$ = &object::north_west; }
| LOWER LEFT_CORNER
- { $$ = &object::south_west; }
| UPPER RIGHT_CORNER
- { $$ = &object::north_east; }
| LOWER RIGHT_CORNER
- { $$ = &object::south_east; }
| NORTH
- { $$ = &object::north; }
| SOUTH
- { $$ = &object::south; }
| EAST
- { $$ = &object::east; }
| WEST
- { $$ = &object::west; }
| CENTER
- { $$ = &object::center; }
| START
- { $$ = &object::start; }
| END
- { $$ = &object::end; }
;
expr:
VARIABLE
- {
- if (!lookup_variable($1, & $$)) {
- lex_error("there is no variable `%1'", $1);
- YYABORT;
- }
- a_delete $1;
- }
| NUMBER
- { $$ = $1; }
| place DOT_X
- {
- if ($1.obj != 0)
- $$ = $1.obj->origin().x;
- else
- $$ = $1.x;
- }
| place DOT_Y
- {
- if ($1.obj != 0)
- $$ = $1.obj->origin().y;
- else
- $$ = $1.y;
- }
| place DOT_HT
- {
- if ($1.obj != 0)
- $$ = $1.obj->height();
- else
- $$ = 0.0;
- }
| place DOT_WID
- {
- if ($1.obj != 0)
- $$ = $1.obj->width();
- else
- $$ = 0.0;
- }
| place DOT_RAD
- {
- if ($1.obj != 0)
- $$ = $1.obj->radius();
- else
- $$ = 0.0;
- }
| expr '+' expr
- { $$ = $1 + $3; }
| expr '-' expr
- { $$ = $1 - $3; }
| expr '*' expr
- { $$ = $1 * $3; }
| expr '/' expr
- {
- if ($3 == 0.0) {
- lex_error("division by zero");
- YYABORT;
- }
- $$ = $1/$3;
- }
| expr '%' expr
- {
- if ($3 == 0.0) {
- lex_error("modulus by zero");
- YYABORT;
- }
- $$ = fmod($1, $3);
- }
| expr '^' expr
- {
- errno = 0;
- $$ = pow($1, $3);
- if (errno == EDOM) {
- lex_error("arguments to `^' operator out of domain");
- YYABORT;
- }
- if (errno == ERANGE) {
- lex_error("result of `^' operator out of range");
- YYABORT;
- }
- }
| '-' expr %prec '!'
- { $$ = -$2; }
| '(' any_expr ')'
- { $$ = $2; }
| SIN '(' any_expr ')'
- {
- errno = 0;
- $$ = sin($3);
- if (errno == ERANGE) {
- lex_error("sin result out of range");
- YYABORT;
- }
- }
| COS '(' any_expr ')'
- {
- errno = 0;
- $$ = cos($3);
- if (errno == ERANGE) {
- lex_error("cos result out of range");
- YYABORT;
- }
- }
| ATAN2 '(' any_expr ',' any_expr ')'
- {
- errno = 0;
- $$ = atan2($3, $5);
- if (errno == EDOM) {
- lex_error("atan2 argument out of domain");
- YYABORT;
- }
- if (errno == ERANGE) {
- lex_error("atan2 result out of range");
- YYABORT;
- }
- }
| LOG '(' any_expr ')'
- {
- errno = 0;
- $$ = log10($3);
- if (errno == ERANGE) {
- lex_error("log result out of range");
- YYABORT;
- }
- }
| EXP '(' any_expr ')'
- {
- errno = 0;
- $$ = pow(10.0, $3);
- if (errno == ERANGE) {
- lex_error("exp result out of range");
- YYABORT;
- }
- }
| SQRT '(' any_expr ')'
- {
- errno = 0;
- $$ = sqrt($3);
- if (errno == EDOM) {
- lex_error("sqrt argument out of domain");
- YYABORT;
- }
- }
| K_MAX '(' any_expr ',' any_expr ')'
- { $$ = $3 > $5 ? $3 : $5; }
| K_MIN '(' any_expr ',' any_expr ')'
- { $$ = $3 < $5 ? $3 : $5; }
| INT '(' any_expr ')'
- { $$ = floor($3); }
| RAND '(' any_expr ')'
- { $$ = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*$3); }
| RAND '(' ')'
- {
- /* return a random number in the range >=0, <1 */
- /* portable, but not very random */
- $$ = (rand() & 0x7fff) / double(0x8000);
- }
| SRAND '(' any_expr ')'
- {
- $$ = 0;
- srand((unsigned int)$3);
- }
| expr '<' expr
- { $$ = ($1 < $3); }
| expr LESSEQUAL expr
- { $$ = ($1 <= $3); }
| expr '>' expr
- { $$ = ($1 > $3); }
| expr GREATEREQUAL expr
- { $$ = ($1 >= $3); }
| expr EQUALEQUAL expr
- { $$ = ($1 == $3); }
| expr NOTEQUAL expr
- { $$ = ($1 != $3); }
| expr ANDAND expr
- { $$ = ($1 != 0.0 && $3 != 0.0); }
| expr OROR expr
- { $$ = ($1 != 0.0 || $3 != 0.0); }
| '!' expr
- { $$ = ($2 == 0.0); }
-
;
]])
Index: tests/glr-regression.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/glr-regression.at,v
retrieving revision 1.21
diff -u -u -r1.21 glr-regression.at
--- tests/glr-regression.at 8 Dec 2005 06:52:43 -0000 1.21
+++ tests/glr-regression.at 22 Dec 2005 11:35:59 -0000
@@ -746,13 +746,14 @@
AT_DATA_GRAMMAR([glr-regr9.y],
[[
%{
- #include <stdio.h>
- #include <stdlib.h>
+# include <stdio.h>
+# include <stdlib.h>
static void yyerror (char const *);
static int yylex (void);
- #define YYSTACKEXPANDABLE 0
+# define YYSTACKEXPANDABLE 0
static int tokens = 0;
static int destructors = 0;
+# define USE(Var)
%}
%glr-parser
@@ -766,7 +767,7 @@
%%
start:
- ambig0 'a' { destructors += 2; }
+ ambig0 'a' { destructors += 2; USE ($2); }
| ambig1 start { destructors += 1; }
| ambig2 start { destructors += 1; }
;
- Re: %destructor feedback, (continued)
- Re: %destructor feedback,
Akim Demaille <=
- Re: %destructor feedback, Joel E. Denny, 2005/12/22
- Re: %destructor feedback, Paul Eggert, 2005/12/22
- Re: %destructor feedback, Akim Demaille, 2005/12/23
- Re: %destructor feedback, Akim Demaille, 2005/12/27
- Re: %destructor feedback, Akim Demaille, 2005/12/27
- Re: %destructor feedback, Paul Eggert, 2005/12/27
- Re: %destructor feedback, Paul Eggert, 2005/12/22
Re: %destructor feedback, SteveBravy, 2005/12/24