[Oberon] ORP.set

Andreas Pirklbauer andreas_pirklbauer at yahoo.com
Wed Mar 13 01:14:29 CET 2019


   > Yes - that's true - that test can be removed making it even
   > simpler. Have you got a test case this doesn't handle?

From a “typical use case" point of view, your variant (a) below
is in fact practically identical to my variant (b). The difference is
only in error reporting. For example, with this small test program:

   MODULE M;
     VAR x: SET;
   BEGIN x := {1;2}          (*typo here … typed “;” instead of “,” *)
   END M.

your solution (a) issues the following message:

  pos 40 no }

whereas my variant (b) issues the following error message

  pos 40 comma?

I suggested variant (b) for two reasons: (1) to be (more or less)
consistent with e.g. ORP.ParamList or ORP.IdentList - which both
check on ORS.comma. (2) to handle the typo of writing “;” instead
of “,” separately (I’m not hung up on this one!).

But in the end it’s a question which heuristic to use. There is
no one “right” answer.

Variant (a):     [Chris]
-------------

  PROCEDURE set(VAR x: ORG.Item);
    VAR y: ORG.Item;
  BEGIN
    IF sym >= ORS.if THEN
      IF sym # ORS.rbrace THEN ORS.Mark(" } missing") END ;
      ORG.MakeConstItem(x, ORB.setType, 0) (*empty set*)
    ELSE element(x);
      WHILE sym < ORS.rparen DO
        IF sym = ORS.comma THEN ORS.Get(sym) ELSE ORS.Mark(“missing comma") END ;
        element(y); ORG.SetOp(ORS.plus, x, y)
      END
    END
  END set;

Variant (b):    [Andreas]
-------------

  PROCEDURE set(VAR x: ORG.Item);                                                                                                           
    VAR y: ORG.Item;                                                                                                                        
  BEGIN                                                                                                                                     
    IF sym >= ORS.if THEN                                                                                                                   
      IF sym # ORS.rbrace THEN ORS.Mark(" } missing") END ;                                                                                 
      ORG.MakeConstItem(x, ORB.setType, 0) (*empty set*)                                                                                    
    ELSE element(x);                                                                                                                        
      WHILE (sym <= ORS.comma) OR (sym = ORS.semicolon) DO                                                                                  
        IF sym = ORS.comma THEN ORS.Get(sym) ELSE ORS.Mark("comma?") END ;                                                                  
        element(y); ORG.SetOp(ORS.plus, x, y)                                                                                               
      END                                                                                                                                   
    END                                                                                                                                     
  END set;       


 


More information about the Oberon mailing list