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

Re: gnubol: Nested conditional statements



>>>>> "Tim" == Tim Josling <tej@melbpc.org.au>
>>>>> wrote the following on Fri, 07 Jan 2000 20:22:33 +1100

  Tim> I tried out nesting conditional search and evaluate on IBM's
  Tim> mainframe compiler (cobol for os/390). The results give some
  Tim> insight into how the compiler operates.

  Tim> I had something like

evaluate num1
   when 1
      search arr1 varying index1
          when arr1 (index1) = "a"
               display "a"
          when arr1 (index1) = "b"
               display "b"
          when arr1 (index1) = "c"
               display "c"
   when 2
         display "2"
   when other
         display "other"
#

	<snip>

  Tim> Reportedly Microfocus cobol can handle this sort of thing. I
  Tim> would love to see what it does with this.

Hi Tim,

First, thanks for bringing my attention back to SEARCH and EVALUATE.
The rules for these verbs in my grammar are nonsense.  

Now, with respect to this question that won't die, I suspect that
both MicroFocus and IBM use hand coded recursive descent parsing,
which, of course, gives them complete freedom to do whatever they
think is worth the trouble.  If you're willing to do whatever it
takes, here's a pccts grammar that does parse your program correctly
according to the indentation, but I hasten to add that it is not the
grammar that I think should be adopted.

For those of you (almost all, I would think) that don't care to spend
too much of your day poring over this example, this is essentially
what's going on.

When it's time for EVALUATE to parse WHEN, it first uses lookahead to
determine if the next phrase is a valid WHEN for EVALUATE.  If that
fails, it tries a lookahead parse for a WHEN that's appropriate for
SEARCH ALL, and then for one that's OK for SEARCH.  If none of
these succeed, it does a real parse for the EVALUATE WHEN so
diagnosis will be at the right place.  Success on the SEARCH phrases
does not consume tokens, but simply causes the EVALUATE parse to end.  

I made some attempt to have this be symmetrical, but I didn't try to
parse EVALUATE within SEARCH.

The ploy could be extended so that it wouldn't happen unless there's
a SEARCH in progress, and other niceties might be added.  

Best regards,

Mike  

search_imperative
  :  SEARCH search_common 
     (  (WHEN eval_when)? null_rule
     |  end_search
     )
  ;

search_stmt
  :  SEARCH search_common
     { end_search }
  ;

search_common
  :  ALL identifier
      { at_end }
      WHEN 
      (  (search_when_all_test)? 
          search_when_all_test ( AND WHEN search_when_all_test )*
        (  conditional_body
        |   NEXT SENTENCE
        )
      |   (  (eval_when)? null_rule
          |  search_when_all_test ( AND WHEN search_when_all_test )*
            (  conditional_body
            |   NEXT SENTENCE
            )
          ) 
      )    
  |  identifier { VARYING identifier }
     { at_end }
     (   (WHEN search_when_test)?  WHEN search_when_test
        ( conditional_body
        | NEXT SENTENCE
        )  
     )+
  ;

search_when_test
  :  condition
  ;
search_when_all_test
  :   ( ( qualified_name rel_eq )? qualified_name rel_eq
        (   NON_NUMERIC_LITERAL
        |   arith_expr
        )
      |   identifier // (condition name)
      )
  ;
end_search
  :   END_SEARCH 
  ;   

evaluate_imperative
  :   EVALUATE evaluate_common 
      end_evaluate
  ;
evaluate_stmt
  :   EVALUATE evaluate_common
      { end_evaluate }
  ;
evaluate_common
  :   eval_head ( ALSO eval_head )*
    (  WHEN
      (   OTHER conditional_body << break; >>
      |  (  (eval_when)? eval_when ( ALSO WHEN eval_when )* 
         |  (  (search_when_all_test)? null_rule
            |  (  (search_when_test)? null_rule  
	       |  eval_when ( ALSO WHEN eval_when )*
               )
            )
         )   
      )
    )*
  ;
eval_head
  :  ( NON_NUMERIC_LITERAL | arith_expr | TRUE_KW | FALSE_KW )
  ;
eval_when
  : (  ANY 
    |  TRUE_KW 
    |  FALSE_KW 
    |  ( (condition)? condition
       |   eval_range
       )
    )
    conditional_body 
  ;
eval_range
  :  { NOT } ( NON_NUMERIC_LITERAL | arith_expr )
     { THRU ( NON_NUMERIC_LITERAL | arith_expr ) }
  ;
end_evaluate
  :   END_EVALUATE
  ;   
null_rule
  :
  ;



--
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.