Listing 2 Second cut at the grammar after initial tests

{
/*
 File:   CONV.SYN - AnaGram syntax file for
                 conversion program;
        Version 2
*/
#include "string.h"
#include "convutil.h"
}
[
  parser file name = "conv.cpp"
]

grammar
 -> record?..., eof

(void) record
 -> valid record, newline                   =cleanUp();
 -> bad data, newline                       =cleanUp();

bad data
 -> error               =wrError(PCB.line, PCB.column);

(void) valid record
 -> "class", attribute list                =putClass();
 -> "instanceVariable",
      attribute list           =putInstanceVariable();
// six other record types handled similarly

attribute list
 -> tab, attribute
 -> attribute list, tab, attribute

(void) attribute
 -> "name@", id value:a                =atAdd(NAME, a);
 -> "file@", string value:a           =atAdd(FILEN, a);
 -> "line@", string value:a            =atAdd(LINE, a);
// twelve other attribute types handled similarly

// ------------ string value syntax -------------------
(Attribute *) string value
 -> value contents              =makeStringAttribute();

// ------------ id value syntax -----------------------
(Attribute *) id value
 -> scoped name:sn,
     name remainder:s          =makeIdAttribute(sn,s);

(char *) scoped name
 -> scoped name term:head                        =head;
 -> scoped name:sn, "::",
     scoped name term:t            =extendScope(sn,t);

(char *) scoped name term
 -> identifier:i                                    =i;

(char *) name remainder
 ->                 =makeHeap(""); //remainder is empty
 -> value contents         =release(); //remaining text

// =============== lexical definitions ================
eof              = -1 + 0 + ^Z
name follow char = 'a-z' + 'A-Z' + '_' + ' ~ + '0-9'
name start char  = 'a-z' + 'A-Z' + '_' + '~'
newline          = '\n'
tab              = '\t'
value char       = ~(eof + tab + '@' + newline)

[
  sticky {name string}
]
(char *) identifier
 -> name string                           =release();

(void) name string
 -> name start char:c                =collectFirst(c);
 -> name string, name follow char:c       =collect(c);

(void) value contents
 -> value char:c                     =collectFirst(c);
 -> value contents, value char:c          =collect(c);

// Supporting C++ code follows
{

StringAttribute *makeStringAttribute() {
  StringAttribute *a = new StringAttribute(release());
  return a;
}

IdAttribute *makeIdAttribute(char * sn, char *s) {
  IdAttribute * a;
  a = new IdAttribute(sn,s);
  delete sn;
  delete s;
  return a;
}

char* extendScope(char *sn, char *t) {
  char * nsn;  // string for new scoped name
  nsn = new char[strlen(sn) + strlen(t) + 3];
  strcpy(nsn, sn);
  strcat(nsn, "::");
  strcat(nsn, t);
  delete sn;
  delete t;
  return nsn;
}

int main(int argc, char * argv[]) {
  if (FALSE == setErrorFile(argv[1])) {
    fprintf(stderr, "Couldn't open error file\n");
    return 1;
  }
  conv();
  return 0;
}
}

/* End of File */