[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gnubol: Re: Magic tokens



Tim Josling TIMJOSLING@prodigy.net 

Has made a bison grammar available. It definitely reveals a lot of hard work.

Thankyou.

It will take time to study and completely understand the work you did, so 
don't be offended if the following comment is not completely informed. But I 
do want to let you know that some of the forward scans you are doing are not 
necessary. 'Though I do not fully understand how you do the forwards scan I 
am real confident that you don't need to and I think I know why that is 
happening to you.

The table driven goal oriented tools only have one state at a time but that 
state can be in the middle of a lot of possible competing rules. For example,


pr_add_statement_imperative:
   tk_add  pr_from_numeric  tk_to  pr_to_numeric
 | tk_add  pr_from_numeric  tk_to  pr_to_numeric GIVING pr_giving_numeric

Involves a situation where competing rules are concurrent up to the point 
that GIVING becomes the lookahead.  It is perfectly okay that these rules 
compete, You seem to think that it is necessary to scan ahead and temporarily 
look for GIVING, and when you find it, magically push the tk_add token back 
on the stack as tk_add_M_M_has_giving_M 
and have your rules  look something  like 

pr_add_statement_imperative:
   tk_add  pr_from_numeric  tk_to  pr_to_numeric
 | tk_add_M_M_has_giving_M  pr_from_numeric  tk_to  pr_to_numeric 
pr_giving_numeric

That is not necessary. Within the ..._imperative rule, bison will allow the 
leading portion of the
various RHSs to look alike with no problem.  You may subsequently have 
trouble merging this rule into something that can have two different path 
ways leading to the point where the rule pulls in this ..._imperative. That 
will look like an r/r conflict. The problem is not down here in this multi 
branched ..._imperative.  The problem is in the plan of attack up above. An 
r/r conflict simply means two rules are trying to reduce to two continuations.

Turns out that you can have as many concurrent running competitive rules as 
you like. So it is not harmful to have two continuations from any given 
place. But at any given juncture you can not have two rules reduce 
simultaneously and then try to continue onto multiple paths.

(Conversely, you are allowed to have jillions of things end as long as there 
is only one new continuation).

From looking at this lookahead for GIVING and the magic transformation of the 
lead ADD token, I would guess that you had a rule which included the 
..._imperative. And there were two or more ways into it from rules reducing 
at that point : and from there either an ADD continue or an alternate ADD 
continue looks like an r/r.  The problem is not in the two ADD continuations. 
 The problem is either in the collection of things coming into that point, or 
in unacceptable precedence on the r/r default.

The point in these situations is that bison is not going to have trouble 
continuing. It would put all ADD statement rules concurrently into scope, 
piece of cake until it sees contrary lookahead subsequent to that.

The problem in r/r is that bison is saying it does not know which of multiple 
preceeding rules to reduce when it sees ADD as the continuation. This 
generally means it is time to change the other rules not the ADD imperative 
collection.

Your %tokens are defined in alphabetic order. That is part of the problem. 
Some things that come before an add you want to reduce, some you want to 
shift.  If the preceding precedence is less than ADD the ADD shifts on.  So 
for example make ON, SIZE, ERROR  have lower precedence than ADD, and it will 
glue onto (shift onto) that clause.

If you define ADD and SUBTRACT as equal then to get a preceding 
(unconditional) ADD to reduce when it sees SUBTRACT, you will need an 
artificial token such as
%left GREATER_THAN_ARITH_VERB  and a %prec marker. (Unless you wish to try to 
use associativity which really will not be viable in this situation.  Also 
one of your comments seems to suggest that you do not realize that 
associtivity only kicks in when precedence is equal. So,..., I mean this in a 
real friendly manner, ... using %left or %right in a bison grammr where every 
token has a distinct precedence, as in an alphabetical ordering, is a non 
sequitur).

To use the  dummy tokens for shift/reduce explication you can code, for 
example,

your_rule_imper :
   ADD simplicity_here %prec GREATER_THAN_ARITH_VERB

will reduce when it encounters SUBTRACT or even ADD.

Trying to establish the precedence of ON might be impossible, and surely we 
will find
contradictory requirements for NOT, so rather than try to get the conditional 
clauses to 
allow shifting of verbs we could set up artificial precedence tokens for them 
as well


your_rule_conditional :
   ADD complexity_here %prec LESS_THAN_ARITH_VERB

will shift when it encounters an arithmetic verb as lookahead.

Now you can recurse with your original rule

your_original_rule :
   ADD simplicity_here %prec GREATER_THAN_ARITH_VERB
   ADD complexity_here %prec LESS_THAN_ARITH_VERB


Any two ADD statements can preceed any following ADD statement this way and 
there is
no conflict.

Your reorganized tokens now _might_ be.

%nonassoc LESS_THAN_ARITH_VERB
%nonassoc ADD SUBTRACT DIVIDE MULTIPLY COMPUTE
%nonassoc GREATER_THAN_ARITH_VERB

It is the ordinal relationship of the dummy tokens to the lookahead. When the 
dummy token is less than the lookahead token, the lookahead shifts on.  When 
the dummy token is greater than the lookahead, the token precipitates a 
reduction of the preceding rule.

You can, of course generalize this.  I use dummies that have similar 
oridinality, but the different names help me clearly describe in the rules 
what I am doing

%nonassoc LESS_THAN_CONDITIONAL
%nonassoc SIZE ERROR
%nonassoc GREATER_THAN_CONDITIONAL

%nonassoc LESS_THAN_VERB
%nonassoc ADD SUBTRACT DIVIDE MULTIPLY COMPUTE
%nonassoc PERFORM MOVE
%nonassoc GREATER_THAN_VERB

here
  %nonassoc GREATER_THAN_CONDITIONAL
and
  %nonassoc LESS_THAN_VERB

are the same as long as I do not insert any tokens inbetween, so although it 
is less readable,
I could code the dummies as

%left GREATER_THAN_CONDITIONAL  LESS_THAN_VERB

But the whole matter takes some work, and I might want to move a group around 
in the order to create different relationships, so I keep them separate.  

Into this we need to weave the END-XYZs and IF/ELSE etc.

A comment in your bison script indicates you have seen the conflict reports 
about the classic dangling ELSE clause.  Again precedence can fix that, and 
you will not have to cross your fingers to hope that it keeps working.

Blocks of code in [THEN] clauses can be tagged with a dummy which is greater 
than ELSE.

so if your token sequence was

...
%nonassoc LESS_THAN_ELSE
...
%token ELSE
....
%nonassoc LESS_THAN_ELSE

and your rule looked like this

somewhere_in_IFs :
   IF reasonable_cond opt_THEN big_complex_block %prec LESS_THAN_ELSE

an encounter with token ELSE as a lookahead will shift the ELSE token onto 
the structure.

You will nolong hear complaints from the tool when you use these to resolve 
conflicts.  A portion of the bison feedback will explain what is going on in 
rules that have these marks; it is actually still necessary to review those 
thoroughly. For COBOL we will not need many of these, but we will need to use 
them in many places.

Bison actually makes a choice in r/r situations, the first rule I think.  But 
that is at best a fifty-fifty. I think s/r situations default to shift (the 
idea is to parse as much as possible successfully as a default). That too is 
not reliable.

Think of rules as parts of movies on plastic film. In our grammar world many 
movies (rules) which have small subsections that are alike.  The movie plays 
by getting everything aligned where all simillar movies have their 
identically matching frames synchronized. Bison plays each movie one frame at 
a time. Stepping each movie forward as long as its next frame matches the 
lookahead. Thousands of movies can play simultaneously this way, the state of 
the machine is the current frame (the aligned frames are all the same, but 
they are in the middle of different movies).  

Eventually a lookahead frame arrives that forces a decision. Each rule that 
might continue either continues by shifting when its continuation matches the 
lookahead, or ends by being dropped completely. Some rules end there because 
that is their end point. New rules can start at that point too commencing 
with the lookahead token. If these are bunches of concurrent movies that have 
been synchronous up to this point, the basic idea is that the camera person 
can only do simple splicing. You can not reduce two or more rules and splice 
in as many as two or more rules at one point, because the camera person is 
real stupid and can not tell which of multiple splices glue to which of 
multiple previous movies. The camera person knows that can't be right. It's 
like being in college and the rules are once enrolled you can not drop two 
courses and add two curses at the same time or your major become unknonwn.

However while continuing any number of rules you can either reduce multiple 
and add one, or reduce one and add multiple; and also drop many obsolete 
rules simultaneously. When reviewing bison output your can get so disoriented 
it is unbelievable. When you focus on individual vexatious conflicts, you can 
really get the wrong impression that the state of the machine reflects just 
one rule. That is not at all true.  You can have many many many competing 
rules going on, even the same rule can compete with itself concurrently if 
different subsections match each outer (that happens alot on things like 
statements with alternate conditional clauses).  And also less obvious, at 
any give shift point you could have some rules shift and perhaps numerous 
rules die, and still not have a reduction at that point.

Anyway, just intended as tips, hope it's useful.

Best Wishes
Bob Rayhawk
RKRayhawk@aol.com









--
This message was sent through the gnu-cobol mailing list.  To remove yourself
from this mailing list, send a message to majordomo@lusars.net with the
words "unsubscribe gnu-cobol" in the message body.  For more information on
the GNU COBOL project, send mail to gnu-cobol-owner@lusars.net.