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

gnubol: Problem 10



In a message dated 12/22/99 6:19:34 PM EST, tej@melbpc.org.au writes:

<< 
 /* problem 10.  
    - it is hard to distinguish the two forms of perform (inline
 and outline) syntactically
 
    solution 10. 
    - check if the token after perform is the start of an
 identifier in the data division; if so, it must be the outline
 perform
    otherwise, it needs an end-perform
 */
 
 %token tk_perform_M_M_that_requires_end_verb_M
  >>

Can I talk you into believing that the data division will be parsed before 
the procedure division
parse commences?

If the data division is parsed completely first, then
the lexer (or a filter) can manifest a generic name as a data_name
or procedure_name (or atleast not_data_name), so where is
the ambiguity?  In the two perform format groups?

I have studied your perform rule structure and the sequence

pr_procedure_name:
pr_procedure_name_base
|pr_procedure_name_base pr_of_or_in pr_procedure_name_base 
;

through

pr_procedure_name_base:
tk_generic_number_integer
|tk_generic_name
;

leads to 
 tk_generic_name

that is the culprit (which I think you realize). As the data element in the
PERFORM n TIMES
phrasing can lead thusly to a like target

pr_from_numeric:
pr_identifier_no_refmod
|tk_generic_number_non_integer
|tk_generic_number_integer
;

pr_identifier_no_refmod:
pr_identifier_basic
|pr_identifier_basic_can_have_array pr_array_reference
;


pr_identifier_basic:
tk_generic_name
|pr_identifier_basic pr_of_or_in tk_generic_name
;


That is, 
 tk_generic_name

can end up just past PERFORM in several ways. 


If you draft your parser with the assumption that we can manifest atleast the 
distinction
data-element / not data-element.  I think the PERFORMS do not have any 
ambiguity at all. Your rules are rather good actually.

( I would be quibbling if I complained that the optional WITH TEST BEFORE | 
AFTER should not be buried down inside of the optional UNTIL clause. I don't 
know if you had a reason to
do that or if it just evolved that way for you. You have done so much work, 
one can't complain really.  But the PERFORM rules would be a little more 
clear if that sub rule was perked back 
up to the top as self documentation. )

Tell me if there is some other ambiguity you see if the rules are normalized 
to a single
tk_PERFORM, rather than your custom lookahead switchereeno.

----------
In a different sense completely, I would encourage you to not write the 
END-PERFORM rules so optimistically.  I would have two basic rules (really to 
sets of competing END-PERFORM rules).  One would have the END-PERFORM, and 
the other set would not have the END-PERFORM, but would have a %prec 
PREC_LOWER_THAN_END_PERFORM (actually we may want to name these things %prec 
PREC_YIELD_TO_END_PERFORM) which would be a dummy token with a precedence 
lower than END-PERFORM. Thus when source code had the 'required' END-PERFORM 
it would in fact shift on (all is well, the lesser rule yields and 
atrophies). And when the source code did not have the 'required' END-PERFORM 
if would either continue to grow by adding more verbs, or eventually be 
implicitly terminated, say by 
an ELSE clause that was not glueing internally to the PERFORM block contained 
statements. 

That is really the essence of implied scope termination. It is EASIEST to see 
in the inline perform! Two competing rules: both are inline perform rules, 
one has the explicit scope terminator (END-PERFORM) as a shiftable last 
symbol, the other has no such position, but is tagged with a lower precedence 
so that it yields to that specific token.  If we do not have a verb that can 
permit the block recurse to spin again the block recurse ends, we are back 
out 
at the competition point, we do not have END-PERFORM, the simpler rule 
reduces.

In such competitive pairs it is the one with the %prec 
PREC_YIELD_TO_something that carries the warning message about scope 
termination.  This is easiest in the inline perform.

You need that much sophistication to deal with coding errors where 
END-PERFORM is left out.  Implicit scope termination of inline perform is 
simple. It is the illuminating case.

--------
Now on the other-hand trapping erroneous END-PERFORM where they do _not_ 
belong is not so easy. We do not want to code up some rules for the basic 
perform procedure name formats with error detecting END-PERFORM alternate 
rules. That will break the parser, because these will scoop up END-PERFORMs 
that could belong to an enclosing inline perform.  So we would have to resort 
to manual means to trap the totally random END-PERFORMs and END-PERFORMs that 
look to be intended for perform procedure name format statements (as wrong 
code).  It is not worth worrying about just yet.  But if I am not mistaken, I 
saw atleast one post that claimed a current product actually allows 
END-PERFORM on perform procedure name format statements: which raises a 
miniature codebase issue. And I just wanted to put a little sticky note here 
to clarify that this is the inverse of the missing END-PERFORM on inline 
performs.

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.