Initial revision
authorJosh Yelon <jyelon@uiuc.edu>
Sun, 4 Aug 1996 23:13:31 +0000 (23:13 +0000)
committerJosh Yelon <jyelon@uiuc.edu>
Sun, 4 Aug 1996 23:13:31 +0000 (23:13 +0000)
src/xlat++/xp-lexer.flex [new file with mode: 0755]
src/xlat++/xp-sfilter.flex [new file with mode: 0755]
src/xlat++/xp-t.bison [new file with mode: 0755]
src/xlat-i/xi-parse.bison [new file with mode: 0644]
src/xlat-i/xi-scan.flex [new file with mode: 0644]
src/xlat/xl-lexsp.flex [new file with mode: 0755]
src/xlat/xl-sfspec.flex [new file with mode: 0755]
src/xlat/xl-yacc.bison [new file with mode: 0755]
src/xlatcpm/conv-cpm.flex [new file with mode: 0644]

diff --git a/src/xlat++/xp-lexer.flex b/src/xlat++/xp-lexer.flex
new file mode 100755 (executable)
index 0000000..0fc8294
--- /dev/null
@@ -0,0 +1,558 @@
+%{
+
+/*  Copyright (C) 1989-1991 James A. Roskind, All rights reserved.
+    This lexer description was written by James A.  Roskind.  Copying
+    of  this  file, as a whole, is permitted providing this notice is
+    intact  and  applicable   in   all   complete   copies.    Direct
+    translations  as a whole to other lexer generator input languages
+    (or lexical description languages)  is  permitted  provided  that
+    this  notice  is  intact and applicable in all such copies, along
+    with a disclaimer that  the  contents  are  a  translation.   The
+    reproduction  of derived files or text, such as modified versions
+    of this file, or the output of scanner generators, is  permitted,
+    provided   the  resulting  work  includes  the  copyright  notice
+    "Portions Copyright (c) 1989, 1990 James  A.   Roskind".  Derived
+    products  must  also  provide  the notice "Portions Copyright (c)
+    1989, 1990 James A.  Roskind" in  a  manner  appropriate  to  the
+    utility,   and  in  keeping  with  copyright  law  (e.g.:  EITHER
+    displayed when first invoked/executed; OR displayed  continuously
+    on  display terminal; OR via placement in the object code in form
+    readable in a printout, with or near the title of the work, or at
+    the end of the file).  No royalties, licenses or  commissions  of
+    any  kind  are  required  to copy this file, its translations, or
+    derivative products, when the copies are made in compliance  with
+    this  notice.  Persons  or  corporations  that  do make copies in
+    compliance  with  this  notice  may  charge  whatever  price   is
+    agreeable  to  a buyer, for such copies or derivative works. THIS
+    FILE IS PROVIDED ``AS IS'' AND WITHOUT  ANY  EXPRESS  OR  IMPLIED
+    WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
+    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+    James A. Roskind
+    Independent Consultant
+    516 Latania Palm Drive
+    Indialantic FL, 32903
+    (407)729-4348
+    jar@hq.ileaf.com
+    or ...!uunet!leafusa!jar
+
+    ---end of copyright notice---
+
+*/
+
+/*
+
+Comment  removal  must  be done during the lexing, as context (such as
+enclosure in string literals) must be  observed.   For  this  cut-down
+lexer,  we  will  assume that comments have been removed (don't assume
+this if you are writing a compiler or browser!).
+
+
+For each IDENTIFIER like string that is found,  there  are  several
+distinct interpretations that can be applied:
+
+1)  The  preprocessor  may  interpret  the  string as a "keyword" in a
+directive (eg: "pragma" or "include", "defined").
+
+2) The parser may interpret the string as a keyword. (eg: "int").
+
+3) Both parser and preprocessor may interpret the string as a  keyword
+(eg: "if").
+
+Since  this  file  is based on source that actually lexically analyses
+text for both preprocessing and parsing, macro definitions  were  used
+throughout.   The macro definitions supplied here have been customized
+to a C++ parse only, and  all  preprocessor  keywords  are  passed  as
+IDENTIFIER  or  TYPEDEFname.   Also, since there is no symbol table to
+interrogate to decide whether a string  is  a  TYPEDEFname,  I  simply
+assume  that  any  identifier beginning with an upper case letter is a
+TYPEDEFname.  This hack  should  allow  you  to  check  out  how  code
+segments  are  parsed  using my grammar.  Unfortunately, if you really
+want to parse major league code, you have to write a symbol table, and
+maintain appropriate scoping information.
+
+*/
+
+
+/* Included code before lex code */
+/*************** Includes and Defines *****************************/
+
+
+char *CurrentIdent, *CurrentConst ;
+int FoundLBrace=0, FoundRBrace=0 ;
+
+#define YYSTYPE char *
+#include "xp-t.tab.h" /* YACC generated definitions based on C++ grammar */
+#include "xp-lexer.h"
+#include "xp-extn.h"
+
+
+#define WHITE_RETURN(x) if ( shouldprint ) strcat(OutBuf,prevtoken) ; \
+                       strcpy(prevtoken,x);
+
+/*
+#define NEW_LINE_RETURN() CurrentLine++; \
+                         if ( shouldprint ) strcat(OutBuf,prevtoken); \
+                         strcpy(prevtoken,yytext);
+*/
+                         
+
+#define PA_KEYWORD_RETURN(x)   RETURN_VAL(x)  /* standard C PArser Keyword */
+#define CPP_KEYWORD_RETURN(x)  PA_KEYWORD_RETURN(x)  /* C++ keyword */
+#define PPPA_KEYWORD_RETURN(x) RETURN_VAL(x)  /* both PreProcessor and PArser keyword */
+#define PP_KEYWORD_RETURN(x)   IDENTIFIER_RETURN()
+
+/*
+#define IDENTIFIER_RETURN() RETURN_VAL(isaTYPE(yytext)?TYPEDEFname:IDENTIFIER)
+*/
+
+#define IDENTIFIER_RETURN() CurrentIdent = (char *)malloc((strlen(yytext)+1)*sizeof(char)); \
+                           strcpy(CurrentIdent,yytext);  \
+                           yylval = CurrentIdent ; \
+                           if (shouldprint) strcat(OutBuf,prevtoken); \
+                           strcpy(prevtoken,yytext) ; \
+                           if ( FoundLBrace ) {PushStack() ;FoundLBrace=0;}\
+                           else if ( FoundRBrace ){PopStack();FoundRBrace=0;}\
+                           return(isaTYPE(yytext)?TYPEDEFname:IDENTIFIER);
+
+#define PPOP_RETURN(x)       RETURN_VAL((int)*yytext) /* PreProcess and Parser operator */
+#define NAMED_PPOP_RETURN(x) /* error: PreProcessor ONLY operator;  Do nothing */
+#define ASCIIOP_RETURN(x)    RETURN_VAL((int)*yytext) /* a single character operator */
+#define LBRACE_RETURN(x)     CurrentScope++ ; \
+                            RETURN_VAL((int)*yytext) ;
+#define RBRACE_RETURN(x)     CurrentScope-- ; \
+                            RETURN_VAL((int)*yytext) ;
+
+#define NAMEDOP_RETURN(x)    RETURN_VAL(x)            /* a multichar operator, with a name */
+
+/* #define NUMERICAL_RETURN(x) RETURN_VAL(x)         * some sort of constant */
+
+#define NUMERICAL_RETURN(x) CurrentConst = (char *)malloc((strlen(yytext)+1)*sizeof(char)); \
+                           strcpy(CurrentConst,yytext);  \
+                           yylval = CurrentConst ; \
+                           if (shouldprint) strcat(OutBuf,prevtoken); \
+                           strcpy(prevtoken,yytext) ; \
+                           if ( FoundLBrace ) {PushStack() ;FoundLBrace=0;}\
+                           else if ( FoundRBrace ){PopStack();FoundRBrace=0;}\
+                           return(x);
+                           
+
+#define LITERAL_RETURN(x)   RETURN_VAL(x)            /* a string literal */
+
+#define RETURN_VAL(x)  yylval = yytext; \
+                       if ( shouldprint ) strcat(OutBuf,prevtoken); \
+                       strcpy(prevtoken,yytext) ; \
+                       if ( FoundLBrace ) {PushStack() ;FoundLBrace=0;}\
+                       else if ( FoundRBrace ){PopStack();FoundRBrace=0;}\
+                       if ( prevtoken[0] == '{' ) FoundLBrace=1; \
+                       else if ( prevtoken[0] == '}' ) FoundRBrace=1; \
+                       return(x);
+
+#define RETURN_VAL_NOPRINT(x)  yylval = yytext; return(x);
+
+#define CHARM_KEYWORD_RETURN(x)        RETURN_VAL_NOPRINT(x)
+
+#ifdef yywrap
+#undef yywrap
+#endif
+
+%}
+
+%p 4000
+%e 1500
+
+comment "//".*
+TabSpace [ \t]*
+ASTRNG ([^"\\\n]|\\(['"?\\abfnrtv\n]|[0-7]{1,3}|[xX][0-9a-fA-F]{1,3}))*
+
+identifier [a-zA-Z_][0-9a-zA-Z_]*
+
+exponent_part [eE][-+]?[0-9]+
+fractional_constant ([0-9]*"."[0-9]+)|([0-9]+".")
+floating_constant (({fractional_constant}{exponent_part}?)|([0-9]+{exponent_part}))[FfLl]?
+
+integer_suffix_opt ([uU]?[lL]?)|([lL][uU])
+decimal_constant [1-9][0-9]*{integer_suffix_opt}
+octal_constant "0"[0-7]*{integer_suffix_opt}
+hex_constant "0"[xX][0-9a-fA-F]+{integer_suffix_opt}
+
+simple_escape [abfnrtv'"?\\]
+octal_escape  [0-7]{1,3}
+hex_escape "x"[0-9a-fA-F]+
+
+escape_sequence [\\]({simple_escape}|{octal_escape}|{hex_escape})
+c_char [^'\\\n]|{escape_sequence}
+s_char [^"\\\n]|{escape_sequence}
+
+
+h_tab [\011]
+form_feed [\014]
+v_tab [\013]
+c_return [\015]
+
+horizontal_white [ ]|{h_tab}
+
+
+
+%%
+
+{comment}              { }
+
+{horizontal_white}+     {
+                       WHITE_RETURN(" ");
+                       }
+
+({v_tab}|{c_return}|{form_feed})+   {
+                       WHITE_RETURN(" ");
+                       }
+
+
+({horizontal_white}|{v_tab}|{c_return}|{form_feed})*"\n"   {
+                       NEW_LINE_RETURN();
+                       }
+
+chare              {CHARM_KEYWORD_RETURN(CHARE);}
+accumulator        {CHARM_KEYWORD_RETURN(ACCUMULATOR);}
+monotonic          {CHARM_KEYWORD_RETURN(MONOTONIC);}
+readonly           {CHARM_KEYWORD_RETURN(READONLY);}
+writeonce          {CHARM_KEYWORD_RETURN(WRITEONCE);}
+
+message                    {CHARM_KEYWORD_RETURN(MESSAGE);}
+handle             {   if ( CheckCharmName() ) {
+                               CHARM_KEYWORD_RETURN(HANDLE);
+                       }
+                       else {
+                               IDENTIFIER_RETURN() ;
+                       }
+                   }
+group              {   if ( CheckCharmName() ) {
+                               CHARM_KEYWORD_RETURN(GROUP);
+                               /* handle and group are processed same way */
+                       }
+                       else {
+                               IDENTIFIER_RETURN() ;
+                       }
+                   }
+entry              {if ( shouldprint ) strcat(OutBuf,prevtoken); 
+                    strcpy(prevtoken,"public") ;       
+                    CHARM_KEYWORD_RETURN(ENTRY);}
+"=>"               {CHARM_KEYWORD_RETURN(DOUBLEARROW);}
+"="{TabSpace}">"    {CHARM_KEYWORD_RETURN(DOUBLEARROW);}
+"ALL"              {CHARM_KEYWORD_RETURN(ALL_NODES);}
+"LOCAL"                    {CHARM_KEYWORD_RETURN(LOCAL);}
+VARSIZE                    { FoundVarSize = TRUE ; }
+newchare           {CPP_KEYWORD_RETURN(NEWCHARE);}
+newgroup           {CPP_KEYWORD_RETURN(NEWGROUP);}
+newaccumulator     {CPP_KEYWORD_RETURN(NEW);}
+newmonotonic       {CPP_KEYWORD_RETURN(NEW);}
+
+
+auto                {PA_KEYWORD_RETURN(AUTO);}
+break               {PA_KEYWORD_RETURN(BREAK);}
+case                {PA_KEYWORD_RETURN(CASE);}
+char                {PA_KEYWORD_RETURN(CHAR);}
+const               {PA_KEYWORD_RETURN(CONST);}
+continue            {PA_KEYWORD_RETURN(CONTINUE);}
+default             {PA_KEYWORD_RETURN(DEFAULT);}
+define              {PP_KEYWORD_RETURN(DEFINE);}
+defined             {PP_KEYWORD_RETURN(OPDEFINED);}
+do                  {PA_KEYWORD_RETURN(DO);}
+double              {PA_KEYWORD_RETURN(DOUBLE);}
+elif                {PP_KEYWORD_RETURN(ELIF);}
+else                {PPPA_KEYWORD_RETURN(ELSE);}
+endif               {PP_KEYWORD_RETURN(ENDIF);}
+enum                {PA_KEYWORD_RETURN(ENUM);}
+error               {PP_KEYWORD_RETURN(ERROR);}
+extern              {PA_KEYWORD_RETURN(EXTERN);}
+float               {PA_KEYWORD_RETURN(FLOAT);}
+for                 {PA_KEYWORD_RETURN(FOR);}
+goto                {PA_KEYWORD_RETURN(GOTO);}
+if                  {PPPA_KEYWORD_RETURN(IF);}
+ifdef               {PP_KEYWORD_RETURN(IFDEF);}
+ifndef              {PP_KEYWORD_RETURN(IFNDEF);}
+include             {PP_KEYWORD_RETURN(INCLUDE); }
+int                 {PA_KEYWORD_RETURN(INT);}
+line                {PP_KEYWORD_RETURN(LINE);}
+long                {PA_KEYWORD_RETURN(LONG);}
+pragma              {PP_KEYWORD_RETURN(PRAGMA);}
+ptrdiff_t           {if (ptrdiff_is_predefined)
+                       { PA_KEYWORD_RETURN(PTRDIFF_TOKEN); }
+                     else { IDENTIFIER_RETURN(); } }
+register            {PA_KEYWORD_RETURN(REGISTER);}
+return              {PA_KEYWORD_RETURN(RETURN);}
+short               {PA_KEYWORD_RETURN(SHORT);}
+signed              {PA_KEYWORD_RETURN(SIGNED);}
+sizeof              {PA_KEYWORD_RETURN(SIZEOF);}
+static              {PA_KEYWORD_RETURN(STATIC);}
+struct              {PA_KEYWORD_RETURN(STRUCT);}
+switch              {PA_KEYWORD_RETURN(SWITCH);}
+typedef             {PA_KEYWORD_RETURN(TYPEDEF);}
+undef               {PP_KEYWORD_RETURN(UNDEF);}
+union               {PA_KEYWORD_RETURN(UNION);}
+unsigned            {PA_KEYWORD_RETURN(UNSIGNED);}
+void                {PA_KEYWORD_RETURN(VOID);}
+volatile            {PA_KEYWORD_RETURN(VOLATILE);}
+while               {PA_KEYWORD_RETURN(WHILE);}
+wchar_t             { if (wchar_is_predefined) {
+                         PA_KEYWORD_RETURN(WCHAR_TOKEN);
+                      } else {
+                         IDENTIFIER_RETURN();
+                    }}
+__wchar_t           { PA_KEYWORD_RETURN(__WCHAR_TOKEN); }
+
+class               {CPP_KEYWORD_RETURN(CLASS);}
+delete              {CPP_KEYWORD_RETURN(DELETE);}
+friend              {CPP_KEYWORD_RETURN(FRIEND);}
+inline              {CPP_KEYWORD_RETURN(INLINE);}
+__inline__          {CPP_KEYWORD_RETURN(UNDERSCORE_INLINE);}
+new                 {CPP_KEYWORD_RETURN(NEW);}
+operator            {CPP_KEYWORD_RETURN(OPERATOR);}
+overload            {CPP_KEYWORD_RETURN(OVERLOAD);}
+protected           {CPP_KEYWORD_RETURN(PROTECTED);}
+private             {CPP_KEYWORD_RETURN(PRIVATE);}
+public              {CPP_KEYWORD_RETURN(PUBLIC);}
+this                {CPP_KEYWORD_RETURN(THIS);}
+virtual             {CPP_KEYWORD_RETURN(VIRTUAL);}
+
+
+
+"CFunctionNameToRef"{TabSpace}?"("{TabSpace}?{identifier}{TabSpace}?")"  {
+                       /* Find the identifier */
+                       char str[128] ;
+                       char *ident = str ;
+                       char *ptr1 = strchr(yytext,'(') ;
+                       ptr1++ ;
+                       while ( *ptr1==' ' || *ptr1=='\t' )
+                               ptr1++ ;                        
+                       while ( *ptr1!=' ' && *ptr1!='\t' && *ptr1!=')' )
+                               *(ident++) = *(ptr1++) ;
+                       *ident = '\0' ;
+
+                       strcpy(yytext,"_CK_func_") ;
+                       strcat(yytext,str) ;
+
+                       IDENTIFIER_RETURN();
+                       }
+
+
+
+{identifier}        { IDENTIFIER_RETURN(); }
+
+{decimal_constant}  {NUMERICAL_RETURN(INTEGERconstant);}
+{octal_constant}    {NUMERICAL_RETURN(OCTALconstant);}
+{hex_constant}      {NUMERICAL_RETURN(HEXconstant);}
+{floating_constant} {NUMERICAL_RETURN(FLOATINGconstant);}
+
+
+"L"?[']{c_char}+[']     {
+                       NUMERICAL_RETURN(CHARACTERconstant);
+                       }
+
+
+"L"?["]{s_char}*["]     {
+                       LITERAL_RETURN(STRINGliteral);}
+
+
+
+
+"("                  {PPOP_RETURN(LP);}
+")"                  {PPOP_RETURN(RP);}
+","                  {PPOP_RETURN(COMMA);}
+"#"                  {NAMED_PPOP_RETURN('#') ;}
+"##"                 {NAMED_PPOP_RETURN(POUNDPOUND);}
+
+"{"                  { LBRACE_RETURN(LC); }
+"}"                  { RBRACE_RETURN(RC); }
+
+"["                  {ASCIIOP_RETURN(LB);}
+"]"                  {ASCIIOP_RETURN(RB);}
+"."                  {ASCIIOP_RETURN(DOT);}
+"&"                  {ASCIIOP_RETURN(AND);}
+"*"                  {ASCIIOP_RETURN(STAR);}
+"+"                  {ASCIIOP_RETURN(PLUS);}
+"-"                  {ASCIIOP_RETURN(MINUS);}
+"~"                  {ASCIIOP_RETURN(NEGATE);}
+"!"                  {ASCIIOP_RETURN(NOT);}
+"/"                  {ASCIIOP_RETURN(DIV);}
+"%"                  {ASCIIOP_RETURN(MOD);}
+"<"                  {ASCIIOP_RETURN(LT);}
+">"                  {ASCIIOP_RETURN(GT);}
+"^"                  {ASCIIOP_RETURN(XOR);}
+"|"                  {ASCIIOP_RETURN(PIPE);}
+"?"                  {ASCIIOP_RETURN(QUESTION);}
+":"                  {ASCIIOP_RETURN(COLON);}
+";"                  {ASCIIOP_RETURN(SEMICOLON);}
+"="                  {ASCIIOP_RETURN(ASSIGN);}
+
+".*"                 {NAMEDOP_RETURN(DOTstar);}
+"::"                 {NAMEDOP_RETURN(CLCL);}
+"->"                 {NAMEDOP_RETURN(ARROW);}
+"->*"                {NAMEDOP_RETURN(ARROWstar);}
+"++"                 {NAMEDOP_RETURN(ICR);}
+"--"                 {NAMEDOP_RETURN(DECR);}
+"<<"                 {NAMEDOP_RETURN(LS);}
+">>"                 {NAMEDOP_RETURN(RS);}
+"<="                 {NAMEDOP_RETURN(LE);}
+">="                 {NAMEDOP_RETURN(GE);}
+"=="                 {NAMEDOP_RETURN(EQ);}
+"!="                 {NAMEDOP_RETURN(NE);}
+"&&"                 {NAMEDOP_RETURN(ANDAND);}
+"||"                 {NAMEDOP_RETURN(OROR);}
+"*="                 {NAMEDOP_RETURN(MULTassign);}
+"/="                 {NAMEDOP_RETURN(DIVassign);}
+"%="                 {NAMEDOP_RETURN(MODassign);}
+"+="                 {NAMEDOP_RETURN(PLUSassign);}
+"-="                 {NAMEDOP_RETURN(MINUSassign);}
+"<<="                {NAMEDOP_RETURN(LSassign);}
+">>="                {NAMEDOP_RETURN(RSassign);}
+"&="                 {NAMEDOP_RETURN(ANDassign);}
+"^="                 {NAMEDOP_RETURN(ERassign);}
+"|="                 {NAMEDOP_RETURN(ORassign);}
+"..."                {NAMEDOP_RETURN(ELLIPSIS);}
+
+"#"{TabSpace}("line")?{TabSpace}[0-9]+{TabSpace}\"{ASTRNG}\"({TabSpace}[0-9]+)*                                                { int i=0,j=0;
+                                                  char temp[MAX_NAME_LENGTH];
+
+                                                 strcat(OutBuf,prevtoken) ;
+                                                 strcpy(prevtoken,"") ;
+                                                 strcat(OutBuf,yytext) ;
+                                                 FLUSHBUF() ;
+
+                                                  while ((yytext[i]<'0')||
+                                                         (yytext[i]>'9'))
+                                                        i++;
+                                                  while ((yytext[i]>='0') &&
+                                                         (yytext[i]<='9'))
+                                                        temp[j++]=yytext[i++];
+                                                  temp[j]='\0';
+                                                  CurrentLine = atoi(temp)-1;
+                                                  while (yytext[i]!='\"')
+                                                        i++;
+
+                                                 /* remove double quote */
+                                                 j = yyleng-1 ;
+                                                 while ( yytext[j] != '"' )
+                                                       j-- ;
+                                                  yytext[j]='\0';
+                                                  strcpy(CurrentFileName,
+                                                                yytext+i+1);
+                                                }
+
+"#"{TabSpace}?("line")?{TabSpace}[0-9]+         { /* #line used by SP */
+                                               
+                                               int i=0,j=0;     
+                                                char temp[MAX_NAME_LENGTH];
+                                               
+                                               strcat(OutBuf,prevtoken) ;
+                                               strcpy(prevtoken,"") ;
+                                               strcat(OutBuf,yytext) ;
+                                               FLUSHBUF() ;
+
+                                               /* Skip to the line number */
+                                               while ((yytext[i]<'0')||
+                                                      (yytext[i]>'9'))
+                                                    i++;
+                                               
+                                               /* Copy the line number */
+                                               while ((yytext[i]>='0') &&
+                                                      (yytext[i]<='9'))
+                                                    temp[j++]=yytext[i++];
+                                               temp[j]='\0';
+                                               
+                                               /* Now place it in 
+                                                  'CurrentLine */
+                                               CurrentLine = atoi(temp)-1;
+                                          }
+
+
+"#"{TabSpace}?("pragma"){TabSpace}("when").*   { /* #pragma when ... */
+
+               /* This pragma is used to specify dependences between EPs */
+                   char * rest ;
+                   if ( MakeGraph ) {
+                       rest = strchr(yytext,'n') ;
+                       rest++ ;
+                       fprintf(graphfile,"WHEN %s %s : %s\n",CurrentChare,
+                                               CurrentEP, rest) ;
+                   }
+               }
+
+
+"#"{TabSpace}?("pragma").*     { /* #pragma used by G++: copy to output */
+                                       strcat(OutBuf,prevtoken) ;
+                                       strcpy(prevtoken,"") ;
+                                       strcat(OutBuf,yytext) ;
+                                       FLUSHBUF() ;
+                               }
+
+"#"{TabSpace}?("file").*       { /* #file stuff used in nCUBE CC */
+                                       strcat(OutBuf,prevtoken) ;
+                                       strcpy(prevtoken,"") ;
+                                       strcat(OutBuf,yytext) ;
+                                       FLUSHBUF() ;
+                               }
+
+%%
+
+yywrap() { return(1); }
+
+/* I won't bother to provide any error recovery. I won't  even  handle
+unknown characters */
+
+/*******************************************************************
+int isaTYPE(string)
+char * string;
+{
+    *  We  should  really  be  maintaining  a  symbol  table,  and be
+    carefully keeping track of what the current scope is  (or  in  the
+    case  of  "rescoped"  stuff,  what  scope  to  look in). Since the
+    grammar is not annotated with  actions  to  track  transitions  to
+    various  scopes,  and  there  is no symbol table, we will supply a
+    hack to allow folks to test  the  grammar  out.   THIS  IS  NOT  A
+    COMPLETE IMPLEMENTATION!!!! *
+
+    if ( strncmp(string,"NULL",4) == 0 )
+       return 0 ;
+
+    return ('A' <= string[0] && 'Z' >= string[0]);
+}
+********************************************************************/
+
+int isaTYPE(string)
+char *string ;
+{
+       int i ;
+
+       if ( StructScope )
+               return FALSE ;
+
+       if ( !FoundGlobalScope || GlobalStack == NULL ) {
+               for ( i=TotalSyms-1; i>=0; i-- ) {  /* from inner to outer */
+                       if ( strcmp(string,SymTable[i].name) == 0 ) {
+                               strcpy(CurrentTypedef,string) ;
+                               return TRUE ;
+                       }
+               }
+       }
+       else {
+               for ( i=0; i<GlobalStack->TotalSyms; i++ ) {  
+                       /* search global state */
+                       if ( strcmp(string,SymTable[i].name) == 0 ) {
+                               strcpy(CurrentTypedef,string) ;
+                               return TRUE ;
+                       }
+               }
+                FoundGlobalScope = 0 ;
+       }
+       strcpy(CurrentTypedef,"") ;
+       return FALSE ;
+}
+
+NEW_LINE_RETURN() 
+{
+       CurrentLine++; 
+       if ( shouldprint ) strcat(OutBuf,prevtoken); 
+       strcpy(prevtoken,yytext);
+}
+
+
diff --git a/src/xlat++/xp-sfilter.flex b/src/xlat++/xp-sfilter.flex
new file mode 100755 (executable)
index 0000000..6bc3dc6
--- /dev/null
@@ -0,0 +1,206 @@
+%{
+#include <string.h>
+
+char CoreName[256] ;
+int currentline=1;
+#ifdef yywrap
+#undef yywrap
+#endif
+%}
+
+WS [ \t\n]*
+WSN [ \t]*
+
+MODULE module
+STR [ \t\n]*
+NAME [a-z0-9A-Z_]+
+NA [^a-zA-Z0-9_]
+
+%%
+
+FunctionNameToRef{WS}"("  { CheckReturns(yytext); fprintf(yyout,"FunctionNameToRef("); }
+FunctionRefToName{WS}"("  { CheckReturns(yytext); fprintf(yyout,"FunctionRefToName("); }
+new_message{WS}"("       { CheckReturns(yytext); fprintf(yyout,"new_message("); }
+new_packbuffer{WS}"("    { CheckReturns(yytext); fprintf(yyout,"new_packbuffer("); }
+delete_message{WS}"("    { CheckReturns(yytext); fprintf(yyout,"delete_message("); }
+new_prio_message{WS}"("          { CheckReturns(yytext); fprintf(yyout,"new_prio_message("); }
+SendMsg{WS}"("           { CheckReturns(yytext); fprintf(yyout,"SendMsg("); }
+Insert{WS}"("            { CheckReturns(yytext); fprintf(yyout,"Insert("); }
+Find{WS}"("              { CheckReturns(yytext); fprintf(yyout,"Find("); }
+Delete{WS}"("            { CheckReturns(yytext); fprintf(yyout,"Delete("); }
+  
+new_chare{WS}"("         { CheckReturns(yytext); fprintf(yyout,"new_chare("); }
+new_branched_chare{WS}"(" { CheckReturns(yytext); fprintf(yyout,"new_branched_chare("); }
+new_accumulator{WS}"("   { CheckReturns(yytext); fprintf(yyout,"new_accumulator("); }
+CollectValue{WS}"("      { CheckReturns(yytext); fprintf(yyout,"CollectValue(");}
+new_monotonic{WS}"("     { CheckReturns(yytext); fprintf(yyout,"new_monotonic("); }
+CharmExit{WS}"("         { CheckReturns(yytext); fprintf(yyout,"CharmExit("); }
+CPriorityPtr{WS}"("      { CheckReturns(yytext); fprintf(yyout,"CPriorityPtr("); }
+CTimer{WS}"("                    { CheckReturns(yytext); fprintf(yyout,"CTimer("); }
+CUTimer{WS}"("           { CheckReturns(yytext); fprintf(yyout,"CUTimer("); }
+CHTimer{WS}"("           { CheckReturns(yytext); fprintf(yyout,"CHTimer("); }
+
+"#"{WSN}[line]{WSN}[0-9]+                               { currentline=GetLine(yytext); fprintf(yyout,"%s",yytext); }
+"#"{WSN}[line]?{WSN}[0-9]+{WSN}\"[^\n]*\"{WSN}[0-9]+    { currentline=GetLine(yytext); fprintf(yyout,"%s",yytext); }
+"#"{WSN}[line]?{WSN}[0-9]+{WSN}\"[^\n]*\"{WSN}[0-9]+{WSN}[0-9]+ { currentline = GetLine(yytext); fprintf(yyout,"%s",yytext);}
+"#"{WSN}[line]?{WSN}[0-9]+{WSN}\"[^\n]*\"{WSN}[0-9]+{WSN}[0-9]+{WSN}[0-9]+ { currentline = GetLine(yytext); fprintf(yyout,"%s",yytext);}
+
+"#"{WSN}[0-9]+{WSN}\n     { CountReturns(yytext); fprintf(yyout,"\n") ; }
+.                        { CountReturns(yytext); fprintf(yyout,"%s",yytext); }
+
+%%
+
+yywrap(){ return(1); }
+
+
+main(argc,argv) 
+int argc ;
+char *argv[] ;
+{ 
+       char pgm[256] ;
+        int len; char *bgn, *end;
+
+       if ( argc != 2 ) {
+               printf("Spacefilter invoked improperly ! Aborting.\n") ;
+               exit(1) ;       
+       }
+/* Find the file name */
+       strcpy(pgm,argv[1]);
+
+        bgn = strrchr(argv[1], '/');
+        if (bgn==0) bgn=argv[1];
+        end = bgn;
+        while (1)
+            {
+            char c = *end;
+            if (!(((c>='a')&&(c<='z'))||
+                  ((c>='A')&&(c<='Z'))||
+                  ((c>='0')&&(c<='9'))||
+                  (c=='_'))) break;
+            end++;
+            }
+       strncpy(CoreName, bgn, end-bgn);
+       CoreName[(end-bgn)] = '\0' ;
+
+       yyin = fopen(argv[1],"r") ;
+
+/* Do the rest of the stuff.. */
+       writem4(); 
+       writeundef(); 
+       yylex(); 
+}
+
+GetLine(string)
+char string[];
+{ int i=0,j;
+  char dummy[10];
+
+  while ((string[i]<'0')||(string[i]>'9')) i++;
+  j=0;
+  while ((string[i]>='0')&&(string[i]<='9')) dummy[j++] = string[i++];
+  dummy[j]='\0';
+  return(atoi(dummy));
+}
+
+output_proper_line(string)
+char string[];
+{
+   int length;
+
+   length=strlen(string)-1;
+   while (string[length-1]!='"') length--;
+   string[length]='\0';
+   fprintf(yyout,"%s",string);
+}
+
+CountReturns(string)
+char *string;
+{
+  while (*string) {
+    if (*string=='\n') currentline++;
+    string++;
+  }
+}
+
+CheckReturns(string)
+char *string;
+{
+  int anyret=0;
+  while (*string) {
+    if (*string=='\n') { currentline++; anyret=1; }
+    string++;
+  }
+  if (anyret)
+    fprintf(yyout,"# line %d\n",currentline);
+}
+
+
+
+
+/* SANJEEV */
+char *ckfreemsg="define(delete_message,`CkFreeMsg((void *)$1)')";
+
+char *charmexit="define(CharmExit,`CkExit()')";
+char *cpriorityptr="define(CPriorityPtr,`CkPriorityPtr($1)')";
+char *ctimer="define(CTimer,`CkTimer()')";
+char *cutimer="define(CUTimer,`CkUTimer()')";
+char *chtimer="define(CHTimer,`CkHTimer()')";
+
+
+char * createchare="define(new_chare,`_CK_CreateChare(_CK_chare_$1,$2,$3,ifelse($4,,NULL_VID,$4),ifelse($5,,CK_PE_ANY,$5))')" ;
+
+char * createboc="define(new_branched_chare,`_CK_CreateBoc(_CK_chare_$1,$2,$3,ifelse($4,,-1`,'NULL,$4`,'$5))')" ;
+
+char * createacc="define(new_accumulator,`_CK_CreateAcc(_CK_acc_$1,$2,ifelse($3,,-1`,'NULL,$3`,'$4))')" ;
+char * createmono="define(new_monotonic,`_CK_CreateMono(_CK_mono_$1,$2,ifelse($3,,-1`,'NULL,$3`,'$4))')" ;
+
+char * functionreftoname="define(FunctionRefToName,`CsvAccess(_CK_9_GlobalFunctionTable)[$1]')" ;
+char * functionnametoref="define(FunctionNameToRef,`_CK_func_$1')" ;
+
+char * ckallocpackbuffer="define(new_packbuffer,`CkAllocPackBuffer($1,$2)')" ;
+
+
+
+writem4()
+{ 
+  char ckallocmsg[256] ;
+  char ckallocpriomsg[256] ;
+
+/* SANJEEV */
+  printf("%s\n",ckfreemsg) ;
+  printf("%s\n%s\n%s\n%s\n%s\n",
+        charmexit,cpriorityptr,ctimer,cutimer,chtimer) ;
+  printf("%s\n%s\n%s\n%s\n",createacc,createmono,createchare, createboc);
+
+sprintf(ckallocmsg,"define(new_message,`ifelse($2,,GenericCkAlloc(_CK_%s._CK_msg_$1`,'sizeof($1)`,'0),((ALLOCFNPTR)(CsvAccess(MsgToStructTable)[_CK_%s._CK_msg_$1].alloc))(_CK_%s._CK_msg_$1`,'sizeof($1)`,'$2`,'0))')", CoreName, CoreName, CoreName );
+
+sprintf(ckallocpriomsg,"define(new_prio_message,`ifelse($3,,GenericCkAlloc(_CK_%s._CK_msg_$1`,'sizeof($1)`,'$2),((ALLOCFNPTR)(CsvAccess(MsgToStructTable)[_CK_%s._CK_msg_$1].alloc))(_CK_%s._CK_msg_$1`,'sizeof($1)`,'$3`,'$2))')", CoreName, CoreName, CoreName ) ;
+
+  printf("%s\n%s\n%s\n%s\n%s\n\n",ckallocmsg, ckallocpriomsg, 
+               functionreftoname, functionnametoref, ckallocpackbuffer );
+}
+
+
+writeundef()
+{ printf("undefine(`changequote')\n");
+  printf("undefine(`divert')\n");
+  printf("undefine(`divnum')\n");
+  printf("undefine(`dnl')\n");
+  printf("undefine(`dumpdef')\n");
+  printf("undefine(`errprint')\n");
+  printf("undefine(`eval')\n");
+  printf("undefine(`ifdef')\n");
+  printf("undefine(`include')\n");
+  printf("undefine(`incr')\n");
+  printf("undefine(`index')\n");
+  printf("undefine(`len')\n");
+  printf("undefine(`maketemp')\n");
+  printf("undefine(`sinclude')\n");
+  printf("undefine(`substr')\n");
+  printf("undefine(`syscmd')\n");
+  printf("undefine(`translit')\n");
+  printf("undefine(`undivert')\n");
+  printf("undefine(`define')\n");
+  printf("undefine(`undefine')\n");
+}
+
diff --git a/src/xlat++/xp-t.bison b/src/xlat++/xp-t.bison
new file mode 100755 (executable)
index 0000000..bda2395
--- /dev/null
@@ -0,0 +1,3397 @@
+%{
+
+/*  Copyright (C) 1989-1991 James A. Roskind, All rights reserved. 
+    This grammar was developed  and  written  by  James  A.  Roskind. 
+    Copying  of  this  grammar  description, as a whole, is permitted 
+    providing this notice is intact and applicable  in  all  complete 
+    copies.   Translations as a whole to other parser generator input 
+    languages  (or  grammar  description  languages)   is   permitted 
+    provided  that  this  notice is intact and applicable in all such 
+    copies,  along  with  a  disclaimer  that  the  contents  are   a 
+    translation.   The reproduction of derived text, such as modified 
+    versions of this grammar, or the output of parser generators,  is 
+    permitted,  provided  the  resulting  work includes the copyright 
+    notice "Portions Copyright (c)  1989,  1990  James  A.  Roskind". 
+    Derived products, such as compilers, translators, browsers, etc., 
+    that  use  this  grammar,  must also provide the notice "Portions 
+    Copyright  (c)  1989,  1990  James  A.  Roskind"  in   a   manner 
+    appropriate  to  the  utility,  and in keeping with copyright law 
+    (e.g.: EITHER displayed when first invoked/executed; OR displayed 
+    continuously on display terminal; OR via placement in the  object 
+    code  in  form  readable in a printout, with or near the title of 
+    the work, or at the end of the file).  No royalties, licenses  or 
+    commissions  of  any  kind are required to copy this grammar, its 
+    translations, or derivative products, when the copies are made in 
+    compliance with this notice. Persons or corporations that do make 
+    copies in compliance with this notice may charge  whatever  price 
+    is  agreeable  to  a  buyer, for such copies or derivative works. 
+    THIS GRAMMAR IS PROVIDED ``AS IS'' AND  WITHOUT  ANY  EXPRESS  OR 
+    IMPLIED  WARRANTIES,  INCLUDING,  WITHOUT LIMITATION, THE IMPLIED 
+    WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR 
+    PURPOSE.
+
+    James A. Roskind
+    Independent Consultant
+    516 Latania Palm Drive
+    Indialantic FL, 32903
+    (407)729-4348
+    jar@hq.ileaf.com
+
+
+    ---end of copyright notice---
+*/
+
+/*
+
+1) template support: Not  done:  pending  syntax  specification  from 
+ANSI.  (This looks like a major effort, as ANSI has decided to extend 
+the  "TYPEDEFname"-feedback-to-the-lexer-hack  to  support   template 
+names as a new kind of terminal token.)
+
+2)  exception  handling:  Not done: pending syntax specification from 
+ANSI (but it doesn't look hard)
+
+done: 3) Support nested types, including identifier::name,  where  we 
+realize  that  identifier was a hidden type.  Force the lexer to keep 
+pace in this situation.   This  will  require  an  extension  of  the 
+yacc-lex feedback loop.
+
+done: 4) Support nested types even when derivations are used in class 
+definitions.
+
+done: 6) Allow declaration specifiers to be left out of  declarations 
+at file and structure scope so that operator conversion functions can 
+be  declared and/or defined.  Note that checking to see that it was a 
+function type that does not require declaration_specifiers is  now  a 
+constraint  check,  and  not  a  syntax  issue.  Within function body 
+scopes, declaration specifiers are required, and this is critical  to 
+distinguishing expressions.
+
+*/
+
+%}
+
+/*
+
+Interesting ambiguity:
+Usually
+        typename ( typename2 ) ...
+or
+        typename ( typename2 [4] ) ...
+etc.
+is a redeclaration of typename2.
+
+Inside  a structure elaboration, it is sometimes the declaration of a 
+constructor!  Note, this only  counts  if  typename  IS  the  current 
+containing  class name. (Note this can't conflict with ANSI C because 
+ANSI C would call it a redefinition, but  claim  it  is  semantically 
+illegal because you can't have a member declared the same type as the 
+containing struct!) Since the ambiguity is only reached when a ';' is 
+found,   there  is  no  problem  with  the  fact  that  the  semantic 
+interpretation  is  providing  the  true  resolution.   As  currently 
+implemented, the constructor semantic actions must be able to process 
+an  ordinary  declaration.  I may reverse this in the future, to ease 
+semantic implementation.
+
+*/
+
+
+
+/*
+
+INTRO TO ANSI C GRAMMAR (provided in a separate file):
+
+The refined grammar resolves several typedef ambiguities in the draft 
+proposed ANSI C standard syntax down to 1 shift/reduce  conflict,  as 
+reported by a YACC process.  Note that the one shift reduce conflicts 
+is  the  traditional  if-if-else conflict that is not resolved by the 
+grammar.  This ambiguity can be removed using the method described in 
+the Dragon Book (2nd edition), but this does  not  appear  worth  the 
+effort.
+
+There  was quite a bit of effort made to reduce the conflicts to this 
+level, and an additional effort was made to make  the  grammar  quite 
+similar  to  the  C++ grammar being developed in parallel.  Note that 
+this grammar resolves the following ANSI C ambiguities:
+
+ANSI C section 3.5.6, "If the [typedef  name]  is  redeclared  at  an 
+inner  scope,  the  type specifiers shall not be omitted in the inner 
+declaration".  Supplying type specifiers prevents consideration of  T 
+as a typedef name in this grammar.  Failure to supply type specifiers 
+forced the use of the TYPEDEFname as a type specifier.  This is taken 
+to an (unnecessary) extreme by this implementation.  The ambiguity is 
+only  a  problem  with  the first declarator in a declaration, but we 
+restrict  ALL  declarators  whenever  the  users  fails  to   use   a 
+type_specifier.
+
+ANSI C section 3.5.4.3, "In a parameter declaration, a single typedef 
+name  in  parentheses  is  taken  to  be  an abstract declarator that 
+specifies a function  with  a  single  parameter,  not  as  redundant 
+parentheses  around  the  identifier".  This is extended to cover the 
+following cases:
+
+typedef float T;
+int noo(const (T[5]));
+int moo(const (T(int)));
+...
+
+Where again the '(' immediately to the left of 'T' is interpreted  as 
+being  the  start  of  a  parameter type list, and not as a redundant 
+paren around a redeclaration of T.  Hence an equivalent code fragment 
+is:
+
+typedef float T;
+int noo(const int identifier1 (T identifier2 [5]));
+int moo(const int identifier1 (T identifier2 (int identifier3)));
+...
+
+*/
+
+
+%{
+/*************** Includes and Defines *****************************/
+#define YYDEBUG_LEXER_TEXT (yylval) /* our lexer loads this up each time.
+                                    We are telling the graphical debugger
+                                    where to find the spelling of the 
+                                    tokens.*/
+#define YYDEBUG 1        /* get the pretty debugging code to compile*/
+#define YYSTYPE  char *  /* interface with flex: should be in header file */
+
+
+
+#include "xp-lexer.h" 
+
+StackStruct *StackTop=NULL ;
+StackStruct *GlobalStack=NULL ;
+
+AggState *PermanentAggTable[MAXAGGS] ;  
+int PermanentAggTableSize = 0 ;
+/* this table is only added to, never deleted from. It stores the objects
+   defined in an aggregate type.                                         */
+                                       
+
+/* These tables just hold lists of Chares,BOCs,Accs ... */
+ChareInfo * ChareTable[MAXCHARES] ;
+ChareInfo * BOCTable[MAXCHARES] ;
+MsgStruct MessageTable[MAXMSGS] ;
+AccStruct * AccTable[MAXACCS] ;
+AccStruct * MonoTable[MAXACCS] ;
+char * DTableTable[MAXDTABLES] ;
+char * ReadTable[MAXREADS] ;
+char * ReadMsgTable[MAXREADS] ;
+FunctionStruct FunctionTable[MAX_FUNCTIONS] ;
+int charecount = -1 ;
+int boccount = -1 ;
+int TotalEntries = 0 ;
+int TotalMsgs = 0 ;
+int TotalAccs = 0 ;
+int TotalMonos = 0 ;
+int TotalDTables = 0 ;
+int TotalReadMsgs = 0 ;
+int TotalReads = 0 ;
+int TotalFns = 0 ;
+
+/* This table is used to distinguish between typedefs and idents */
+SymEntry SymTable[MAXSYMBOLS] ;
+int TotalSyms = 0 ;
+
+/* the following three tables store all handle identifiers and their types */
+HandleEntry ChareHandleTable[MAXIDENTS] ;
+HandleEntry BOCHandleTable[MAXIDENTS] ;
+HandleEntry AccHandleTable[MAXIDENTS] ;
+HandleEntry MonoHandleTable[MAXIDENTS] ;
+HandleEntry WrOnHandleTable[MAXIDENTS] ;
+int ChareHandleTableSize = 0 ;
+int BOCHandleTableSize = 0 ;
+int AccHandleTableSize = 0 ;
+int MonoHandleTableSize = 0 ;
+int WrOnHandleTableSize = 0 ;
+
+/* char modname[MAX_NAME_LENGTH] ;  */
+
+char OutBuf[MAX_OUTBUF_SIZE] ;
+
+int CurrentLine=1 ;
+int CurrentScope = 0 ;         /* 1 means file scope, > 1 means inside a block */
+char CurrentFileName[MAX_NAME_LENGTH] = {'\0'} ;
+int CurrentAccess = -1, CurrentAggType = -1, CurrentStorage = -1 ;
+int CurrentCharmType = -1 ;
+int CurrentCharmNameIndex = -1 ;
+char CurrentTypedef[MAX_NAME_LENGTH] = {'\0'} ;
+char CurrentDeclType[MAX_NAME_LENGTH] = {'\0'} ;
+char CurrentAggName[MAX_NAME_LENGTH] = {'\0'} ;
+char CurrentChare[MAX_NAME_LENGTH] = {'\0'} ; 
+char CurrentEP[MAX_NAME_LENGTH] = {'\0'} ;
+char CurrentFn[MAX_NAME_LENGTH] = {'\0'} ;
+char CurrentMsgParm[MAX_NAME_LENGTH] = {'\0'} ;
+char CurrentSharedHandle[MAX_NAME_LENGTH] = {'_','C','K','_','N','O','T','A','C','C','H','A','N','D','L','E'} ;
+AccStruct *CurrentAcc ;
+ChareInfo *CurrentCharePtr ;
+char CurrentAssOp[5] ;
+char CurrentAsterisk[MAX_NAME_LENGTH] ;
+char *EpMsg=NULL ;
+char SendEP[MAX_NAME_LENGTH] ;
+char SendChare[MAX_NAME_LENGTH] ;
+char SendPe[MAX_NAME_LENGTH] ;
+char LastChare[MAX_NAME_LENGTH] ;
+char LastEP[MAX_NAME_LENGTH] ;
+char LastArg[MAX_NAME_LENGTH] ;
+char *ParentArray[MAX_PARENTS] ;
+int SendType = -1 ;
+int main_argc_argv = FALSE ;
+int foundargs = FALSE ;
+int numparents = 0 ;
+int SendMsgBranchPoss = FALSE ;
+int FoundHandle = -1 ;
+int FilledAccMsg = FALSE ;
+int FoundConstructorBody = FALSE ;
+int IsMonoCall = FALSE ;
+int IsAccCall = FALSE ;
+int FoundParms = FALSE ;
+int FoundLocalBranch = FALSE ;
+int AddedScope = 0 ;
+int FoundGlobalScope = 0 ;
+int FoundTable = FALSE ;
+int FoundVarSize = FALSE ;
+int FoundReadOnly = FALSE ;
+int StructScope = FALSE ;
+int AccFnScope = -1 ;
+int FoundAccFnDef = FALSE ;
+int MakeGraph = FALSE ;
+int InsideChareCode = FALSE ;
+int NewOpType = -1 ;
+char *NewType ;
+int FoundDeclarator=FALSE ; 
+int CurrentFnIsInline=FALSE ;
+int FoundChareEPPair=0 ;
+
+int ErrVal = FALSE ;
+
+char CoreName[MAX_NAME_LENGTH] ;
+int shouldprint=1 ;
+char prevtoken[MAX_TOKEN_SIZE] ;
+FILE *outfile, *headerfile, *graphfile ;
+
+extern int FoundLBrace, FoundRBrace ;
+
+extern char *CheckSendError() ;
+extern char *Mystrstr() ;
+extern EP *SearchEPList() ;
+extern char *Concat2() ;
+extern char *Concat3() ;
+
+%}
+
+/******************************************************************/
+
+/* These are the CHARM++ tokens */
+%token CHARE          BRANCHED        MESSAGE
+/* Note: BRANCHED is no longer a token returned by lex, it is used just
+   as a #defined constant so that a lot of older code doesnt break */
+
+%token HANDLE          GROUP          ENTRY
+/* %token MODULE          INTERFACE  */
+%token DOUBLEARROW     ALL_NODES       LOCAL
+%token ACCUMULATOR     MONOTONIC       READONLY        WRITEONCE
+%token NEWCHARE        NEWGROUP
+
+
+/* This group is used by the C/C++ language parser */
+%token AUTO            DOUBLE          INT             STRUCT
+%token BREAK           ELSE            LONG            SWITCH
+%token CASE            ENUM            REGISTER        TYPEDEF
+%token CHAR            EXTERN          RETURN          UNION
+%token CONST           FLOAT           SHORT           UNSIGNED
+%token WCHAR_TOKEN     __WCHAR_TOKEN   PTRDIFF_TOKEN
+%token CONTINUE        FOR             SIGNED          VOID
+%token DEFAULT         GOTO            SIZEOF          VOLATILE
+%token DO              IF              STATIC          WHILE
+
+/* The following are used in C++ only.  ANSI C would call these IDENTIFIERs */
+%token NEW             DELETE
+%token THIS
+%token OPERATOR
+%token CLASS
+%token PUBLIC          PROTECTED       PRIVATE
+%token VIRTUAL         FRIEND
+%token INLINE          UNDERSCORE_INLINE         OVERLOAD
+/* the underscore_inline above is __inline__ used in byteorder.h in 
+   G++'s include files for Solaris */
+
+/* ANSI C Grammar suggestions */
+%token IDENTIFIER              STRINGliteral
+%token FLOATINGconstant        INTEGERconstant        CHARACTERconstant
+%token OCTALconstant           HEXconstant
+
+/* New Lexical element, whereas ANSI C suggested non-terminal */
+%token TYPEDEFname
+
+/* Multi-Character operators */
+%token  ARROW            /*    ->                              */
+%token  ICR DECR         /*    ++      --                      */
+%token  LS RS            /*    <<      >>                      */
+%token  LE GE EQ NE      /*    <=      >=      ==      !=      */
+%token  ANDAND OROR      /*    &&      ||                      */
+%token  ELLIPSIS         /*    ...                             */
+                 /* Following are used in C++, not ANSI C        */
+%token  CLCL             /*    ::                              */
+%token  DOTstar ARROWstar/*    .*       ->*                    */
+
+/* modifying assignment operators */
+%token MULTassign  DIVassign    MODassign   /*   *=      /=      %=      */
+%token PLUSassign  MINUSassign              /*   +=      -=              */
+%token LSassign    RSassign                 /*   <<=     >>=             */
+%token ANDassign   ERassign     ORassign    /*   &=      ^=      |=      */
+
+/*************************************************************************/
+
+%start translation_unit
+
+/*************************************************************************/
+
+%%
+
+/*********************** CONSTANTS *********************************/
+constant:
+        INTEGERconstant        { $$ = $1 ; }
+        | FLOATINGconstant     { $$ = $1 ; }
+        /*  We  are not including ENUMERATIONconstant here because we 
+          are treating it like a variable with a type of "enumeration 
+          constant".  */
+        | OCTALconstant        { $$ = $1 ; }
+        | HEXconstant          { $$ = $1 ; }
+        | CHARACTERconstant    { $$ = $1 ; }
+        ;
+
+string_literal_list:
+                STRINGliteral
+                | string_literal_list STRINGliteral
+                ;
+
+
+/************************* EXPRESSIONS ********************************/
+
+
+/* Note that I provide  a  "scope_opt_identifier"  that  *cannot* 
+    begin  with ::.  This guarantees we have a viable declarator, and 
+    helps to disambiguate :: based uses in the grammar.  For example:
+
+            ...
+            {
+            int (* ::b()); // must be an expression
+            int (T::b); // officially a declaration, which fails on constraint grounds
+
+    This *syntax* restriction reflects the current syntax in the ANSI 
+    C++ Working Papers.   This  means  that  it  is  *incorrect*  for 
+    parsers to misparse the example:
+
+            int (* ::b()); // must be an expression
+
+    as a declaration, and then report a constraint error.
+
+    In contrast, declarations such as:
+
+        class T;
+        class A;
+        class B;
+        main(){
+              T( F());  // constraint error: cannot declare local function
+              T (A::B::a); // constraint error: cannot declare member as a local value
+
+    are  *parsed*  as  declarations,  and *then* given semantic error 
+    reports.  It is incorrect for a parser to "change its mind" based 
+    on constraints.  If your C++ compiler claims  that  the  above  2 
+    lines are expressions, then *I* claim that they are wrong. 
+*/
+
+paren_identifier_declarator:
+        scope_opt_identifier     {  $$ = $1 ; }
+        | scope_opt_complex_name   { $$ = $1 ; }
+        | '(' paren_identifier_declarator ')'
+        ;
+
+
+/* Note that CLCL IDENTIFIER is NOT part of scope_opt_identifier, 
+    but  it  is  part of global_opt_scope_opt_identifier.  It is ONLY 
+    valid for referring to an identifier, and NOT valid for declaring 
+    (or importing an external declaration of)  an  identifier.   This 
+    disambiguates  the  following  code,  which  would  otherwise  be 
+    syntactically and semantically ambiguous:
+
+            class base {
+                static int i; // element i;
+                float member_function(void);
+                };
+            base i; // global i
+            float base::member_function(void) {
+                i; // refers to static int element "i" of base
+                ::i; // refers to global "i", with type "base"
+                    {
+                    base :: i; // import of global "i", like "base (::i);"?
+                                // OR reference to global??
+                    }
+                }
+*/
+
+primary_expression:
+        global_opt_scope_opt_identifier { $$ = $1 ; }
+        | global_opt_scope_opt_complex_name
+        | THIS   /* C++, not ANSI C */ { $$ = (char *)malloc(sizeof(char)*5);
+                                         strcpy($$,"this") ;
+                                       }
+        | constant                     { $$ = $1 ; }
+        | string_literal_list
+        | '(' comma_expression ')'     { $$ = Concat3("(",$2,")") ; }
+        ;
+
+
+    /* I had to disallow struct, union, or enum  elaborations  during 
+    operator_function_name.   The  ANSI  C++  Working  paper is vague 
+    about whether this should be part of the syntax, or a constraint.  
+    The ambiguities that resulted were more than LALR  could  handle, 
+    so  the  easiest  fix was to be more specific.  This means that I 
+    had to in-line expand type_specifier_or_name far  enough  that  I 
+    would  be  able to exclude elaborations.  This need is what drove 
+    me to distinguish a whole series of tokens based on whether  they 
+    include elaborations:
+
+         struct A { ... }
+
+    or simply a reference to an aggregate or enumeration:
+
+         enum A
+
+    The  latter,  as  well  an  non-aggregate  types are what make up 
+    non_elaborating_type_specifier */
+
+    /* Note that the following does not include  type_qualifier_list. 
+    Hence,   whenever   non_elaborating_type_specifier  is  used,  an 
+    adjacent rule is supplied containing type_qualifier_list.  It  is 
+    not  generally  possible  to  know  immediately  (i_e., reduce) a 
+    type_qualifier_list, as a TYPEDEFname that follows might  not  be 
+    part of a type specifier, but might instead be "TYPEDEFname ::*".  
+    */
+
+non_elaborating_type_specifier:
+        sue_type_specifier
+        | basic_type_specifier
+        | typedef_type_specifier
+
+        | basic_type_name
+        | TYPEDEFname  
+        | global_or_scoped_typedefname
+        ;
+
+
+    /*  The  following  introduces  MANY  conflicts.   Requiring  and 
+    allowing '(' ')' around the `type' when the type is complex would 
+    help a lot. */
+
+operator_function_name:
+        OPERATOR any_operator  
+       {       $$ = (char *)malloc(sizeof(char)*(9+strlen($2))) ;
+               sprintf($$,"operator %s",$2) ;  
+       }
+        | OPERATOR type_qualifier_list            operator_function_ptr_opt
+        | OPERATOR non_elaborating_type_specifier operator_function_ptr_opt
+        ;
+
+
+    /* The following causes several ambiguities on *  and  &.   These 
+    conflicts  would also be removed if parens around the `type' were 
+    required in the derivations for operator_function_name */
+
+    /*  Interesting  aside:  The  use  of  right  recursion  in   the 
+    production  for  operator_function_ptr_opt gives both the correct 
+    parsing, AND removes a conflict!   Right  recursion  permits  the 
+    parser  to  defer  reductions  (a.k.a.:  delay  resolution),  and 
+    effectively make a second pass! */
+
+operator_function_ptr_opt:
+        /* nothing */
+        | unary_modifier        operator_function_ptr_opt
+        | asterisk_or_ampersand operator_function_ptr_opt
+        ;
+
+
+    /* List of operators we can overload */
+any_operator:
+        '+'
+        | '-'
+        | '*'
+        | '/'
+        | '%'
+        | '^'
+        | '&'
+        | '|'
+        | '~'
+        | '!'
+        | '<'
+        | '>'
+        | LS
+        | RS
+        | ANDAND
+        | OROR
+        | ARROW
+        | ARROWstar
+        | '.'
+        | DOTstar
+        | ICR
+        | DECR
+        | LE
+        | GE
+        | EQ
+        | NE
+        | assignment_operator
+        | '(' ')'
+        | '[' ']'
+        | NEW
+        | DELETE
+        | ','
+        ;
+
+
+    /* The following production for type_qualifier_list was specially 
+    placed BEFORE the definition of postfix_expression to  resolve  a 
+    reduce-reduce    conflict    set    correctly.    Note   that   a 
+    type_qualifier_list is only used  in  a  declaration,  whereas  a 
+    postfix_expression is clearly an example of an expression.  Hence 
+    we  are helping with the "if it can be a declaration, then it is" 
+    rule.  The reduce conflicts are on ')', ',' and '='.  Do not move 
+    the following productions */
+
+type_qualifier_list_opt:
+        /* Nothing */
+        | type_qualifier_list
+        ;
+
+
+    /*  Note  that  the next set of productions in this grammar gives 
+    post-increment a higher precedence that pre-increment.   This  is 
+    not  clearly  stated  in  the  C++  Reference manual, and is only 
+    implied by the grammar in the ANSI C Standard. */
+
+    /* I *DON'T* use  argument_expression_list_opt  to  simplify  the 
+    grammar  shown  below.   I am deliberately deferring any decision 
+    until    *after*     the     closing     paren,     and     using 
+    "argument_expression_list_opt" would commit prematurely.  This is 
+    critical to proper conflict resolution. */
+
+    /*  The  {}  in  the following rules allow the parser to tell the 
+    lexer to search for the member name  in  the  appropriate  scope, 
+    much the way the CLCL operator works.*/
+
+postfix_expression:
+        primary_expression { $$ = $1 ; }
+        | postfix_expression '[' comma_expression ']'   
+         {     char *temp ;    
+               strcpy(SendPe,$3);
+               strcpy(SendChare,$1) ;
+               SendMsgBranchPoss = TRUE ;
+               temp = Concat3($1,"[",$3) ;
+               $$ = Concat2(temp,"]") ;
+         }
+        | postfix_expression '(' ')'
+         { $$ = Concat3($1,"(",")") ; 
+           if ( MakeGraph && ( InsideChareCode || CurrentAggType==CHARE 
+                               || CurrentAggType==BRANCHED) )
+               Graph_OutputPrivateCall($1) ; 
+         }
+        | postfix_expression '(' argument_expression_list ')'
+         { char *charename, *scopestr, *temp ; 
+
+           /***
+           if ( MakeGraph && ( strcmp($1,"_CK_CreateBoc") == 0 
+                               || strcmp($1,"_CK_CreateChare") == 0)  ) 
+               Graph_OutputCreate($1,LastArg,LastChare,LastEP) ;
+           ***/
+           if ( SendType != -1 ) {
+               char *sptr = Mystrstr(OutBuf,$3) ;
+               if ( sptr != NULL ) 
+                       *sptr = '\0' ;
+               else 
+                       fprintf(stderr,"TRANSLATOR ERROR : %s, line %d : couldnt discard => etc.\n",CurrentFileName,CurrentLine) ;
+               FLUSHBUF() ;
+       
+           /* Now output the Send functions */
+               scopestr = CheckSendError(SendChare,SendEP,$3,SendType,
+                                                               &charename) ;
+               OutputSend(SendChare,SendEP,$3,SendType,charename,scopestr,
+                                                               SendPe) ;
+
+               SendType = -1 ;
+           }
+           else if ( MakeGraph && ( InsideChareCode || CurrentAggType==CHARE 
+                                    || CurrentAggType==BRANCHED) )
+               Graph_OutputPrivateCall($1) ; 
+
+           temp = Concat3($1,"(",$3) ;
+           $$ = Concat2(temp,")") ;
+         }
+
+        | postfix_expression {StructScope=1;} '.'   member_name
+         { $$ = Concat3($1,".",$4) ;StructScope=0; }
+        | postfix_expression {StructScope=1;} ARROW 
+         { if ( strcmp(CurrentSharedHandle,"_CK_NOTACCHANDLE") != 0 ) {
+               int handleindex ;
+               char *sptr = Mystrstr(OutBuf,CurrentSharedHandle) ;
+
+               if ( sptr != NULL ) 
+                   *sptr = '\0' ;
+               else 
+                   fprintf(stderr,"TRANSLATOR ERROR in shared object handle use: %s, line %d: \n",CurrentFileName,CurrentLine) ;
+               FLUSHBUF() ;
+               handleindex = SearchHandleTable(AccHandleTable,
+                               AccHandleTableSize,CurrentSharedHandle) ;
+               if ( handleindex != -1 ) {
+                   fprintf(outfile,"((%s *)(_CK_9GetAccDataPtr(GetBocDataPtr(%s))))",AccHandleTable[handleindex].typestr,CurrentSharedHandle) ;
+                   IsAccCall = TRUE ;
+               }
+               else if ( (handleindex = SearchHandleTable(MonoHandleTable,
+                             MonoHandleTableSize,CurrentSharedHandle)) != -1 )
+               {   fprintf(outfile,"((%s *)(_CK_9GetMonoDataPtr(GetBocDataPtr(%s))))",MonoHandleTable[handleindex].typestr,CurrentSharedHandle) ;
+                   IsMonoCall = TRUE ;
+               }
+               else if ( SearchHandleTable(WrOnHandleTable,
+                               WrOnHandleTableSize,CurrentSharedHandle) != -1)
+                       ;  /* action taken at end of this rule */ 
+               else 
+                   fprintf(stderr,"TRANSLATOR ERROR: %s, line %d, couldnt find acc/mono handle in table.\n",CurrentFileName,CurrentLine) ;
+
+
+               strcat(OutBuf,prevtoken) ; /* prevtoken now is "->" */
+               strcpy(prevtoken,"") ;  
+           }
+         } 
+         member_name
+         {     char *wovid ;
+               StructScope = 0 ;
+               if ( SearchHandleTable(WrOnHandleTable,
+                               WrOnHandleTableSize,CurrentSharedHandle) != -1 )
+               {       if ( strcmp($5,"DerefWriteOnce") != 0 )
+                               CharmError("writeonce variables have only the DerefWriteOnce method") ;
+                       else {  
+                               wovid = Mystrstr(OutBuf,CurrentSharedHandle) ;
+                               *wovid = '\0' ;
+                               strcat(OutBuf,"DerefWriteOnce(") ;
+                               strcat(OutBuf,CurrentSharedHandle) ;
+                               strcat(OutBuf,")") ;
+                       /*      strcpy(prevtoken,"") ;  */
+                       }
+               }
+               strcpy(CurrentSharedHandle,"_CK_NOTACCHANDLE") ;        
+               $$ = Concat3($1,"->",$5) ;
+         }
+        | postfix_expression ICR
+         { $$ = Concat2($1,"++") ; }
+        | postfix_expression DECR
+         { $$ = Concat2($1,"--") ; }
+
+/* The next 3 are CHARM++ rules for SendMsg, SendMsgBranch, Broadcast */
+
+       | postfix_expression '[' LOCAL ']' 
+         {     char *sptr ; int i ; char str[64] ;
+               sptr = Mystrstr(OutBuf,$1) ;
+               if ( sptr != NULL ) 
+                       *sptr = '\0' ;
+               else 
+                       fprintf(stderr,"TRANSLATOR ERROR : %s, line %d : couldnt discard [LOCAL] etc.\n",CurrentFileName,CurrentLine) ;
+               i = SearchHandleTable(BOCHandleTable,BOCHandleTableSize,$1) ;
+               if ( i == -1 ) {
+                       fprintf(stderr,"ERROR : %s, line %d : %s is not a branched chare group id.\n",CurrentFileName,CurrentLine,$1) ;
+               }
+               sprintf(str,"((%s *)GetBocDataPtr(%s))",BOCHandleTable[i].typestr,$1);
+               strcat(OutBuf,str) ;
+               strcpy(prevtoken,"") ;   /* prevtoken is ']' */
+               FLUSHBUF() ;
+
+               if ( MakeGraph ) {
+                       fprintf(graphfile,"CALLBOC %s %s : %s", CurrentChare, 
+                                       CurrentEP, BOCHandleTable[i].typestr) ;
+               }
+         }
+         ARROW member_name
+         {
+               if ( MakeGraph ) 
+                       fprintf(graphfile," %s\n",$7) ;
+         }
+       | postfix_expression DOUBLEARROW 
+         {     if ( !SendMsgBranchPoss ) {
+                       SendType = SIMPLE ;
+                       strcpy(SendChare,$1) ;
+               }
+               else {
+                       SendType = BRANCH ;
+                       SendMsgBranchPoss = FALSE ;
+               }
+         }
+         member_name   
+         {     char *sptr ;    
+               strcpy(SendEP,$4) ; 
+               /* discard all the CHARM++ `=>' stuff */
+               sptr = Mystrstr(OutBuf,$4) ;
+               if ( sptr != NULL ) 
+                       *sptr = '\0' ;
+               sptr = Mystrstr(OutBuf,SendChare) ;
+               if ( sptr != NULL ) 
+                       *sptr = '\0' ;
+               else 
+                       fprintf(stderr,"TRANSLATOR ERROR : %s, line %d : couldnt discard => etc.\n",CurrentFileName,CurrentLine) ;
+               strcpy(prevtoken,"") ;
+               FLUSHBUF() ;
+         }
+
+       | postfix_expression '[' ALL_NODES ']' DOUBLEARROW 
+         {     strcpy(SendChare,$1) ;
+               SendType = BROADCAST ;
+         }
+         member_name   
+         {     char *sptr ;
+               strcpy(SendEP,$7) ; 
+               /* discard all the CHARM++ `=>' stuff */
+               sptr = Mystrstr(OutBuf,$7) ;
+               if ( sptr != NULL ) 
+                       *sptr = '\0' ;
+               sptr = Mystrstr(OutBuf,SendChare) ;
+               if ( sptr != NULL ) 
+                       *sptr = '\0' ;
+               else 
+                       fprintf(stderr,"TRANSLATOR ERROR : %s, line %d : couldnt discard => etc.\n",CurrentFileName,CurrentLine) ;
+               strcpy(prevtoken,"") ;
+               FLUSHBUF() ;
+         }
+
+/* NOTE: the SendMsgBranch rule : Chare[PEnum]=>EP() is a special case
+   of the SendMsg rule. Adding it explicitly causes a Shift reduce conflict
+   because of the "postfix_expression '[' comma_expression ']'" rule above.
+   - SANJEEV
+*/
+
+                /* The next 4 rules are the source of cast ambiguity */
+        | TYPEDEFname                  '(' ')'
+         { $$ = Concat3($1,"(",")") ; }
+        | global_or_scoped_typedefname '(' ')'
+         { $$ = Concat3($1,"(",")") ; }
+        | TYPEDEFname                  '(' argument_expression_list ')'
+         { char *temp ;
+           temp = Concat3($1,"(",$3) ;
+           $$ = Concat2(temp,")") ;
+         }
+        | global_or_scoped_typedefname '(' argument_expression_list ')'
+         { char *temp ;
+           temp = Concat3($1,"(",$3) ;
+           $$ = Concat2(temp,")") ;
+         }
+        | basic_type_name '(' assignment_expression ')'
+         { char *temp ;
+           temp = Concat3($1,"(",$3) ;
+           $$ = Concat2(temp,")") ;
+         }
+            /* If the following rule is added to the  grammar,  there 
+            will  be 3 additional reduce-reduce conflicts.  They will 
+            all be resolved in favor of NOT using the following rule, 
+            so no harm will be done.   However,  since  the  rule  is 
+            semantically  illegal  we  will  omit  it  until  we  are 
+            enhancing the grammar for error recovery */
+/*      | basic_type_name '(' ')'  /* Illegal: no such constructor*/
+        ;
+
+
+    /* The last two productions in the next set are questionable, but 
+    do not induce any conflicts.  I need to ask X3J16 :  Having  them 
+    means that we have complex member function deletes like:
+
+          const unsigned int :: ~ const unsigned int
+    */
+
+member_name:
+        scope_opt_identifier           
+       {       char *str ;     
+               if ( IsMonoCall && strcmp($1,"Update")==0 ) {
+                       str=Mystrstr(OutBuf,"Update") ;
+                       *str = '\0' ;
+                       strcat(OutBuf,"_CK_Update") ;
+               }
+               else 
+                       $$ = $1;
+               IsMonoCall = FALSE ;
+               IsAccCall = FALSE ;
+       }
+        | scope_opt_complex_name
+        | basic_type_name CLCL '~' basic_type_name  /* C++, not ANSI C */
+
+        | declaration_qualifier_list  CLCL '~'   declaration_qualifier_list
+        | type_qualifier_list         CLCL '~'   type_qualifier_list
+        ;
+
+argument_expression_list:
+        assignment_expression  { $$ = $1 ; /* FLUSHBUF() ;*/ }
+        | argument_expression_list ',' assignment_expression
+         { $$ = Concat3($1,",",$3) ; 
+           strcpy(LastArg,$3) ;
+         }
+        ;
+
+unary_expression:
+        postfix_expression 
+       {       $$ = $1 ; 
+               strcpy(CurrentSharedHandle,"_CK_NOTACCHANDLE") ; 
+               SendMsgBranchPoss = FALSE ;
+       }
+        | ICR  unary_expression                { $$ = Concat2("++",$2) ; }
+        | DECR unary_expression                { $$ = Concat2("--",$2) ; }
+        | asterisk_or_ampersand cast_expression        
+          {  if ( ! FoundChareEPPair ) 
+               $$ = Concat2(CurrentAsterisk,$2) ; 
+             else
+               $$ = $2 ;
+            FoundChareEPPair = 0 ;
+         }
+        | '-'                   cast_expression        { $$ = Concat2("-",$2) ; }
+        | '+'                   cast_expression        { $$ = Concat2("+",$2) ; }
+        | '~'                   cast_expression        { $$ = Concat2("~",$2) ; }
+        | '!'                   cast_expression        { $$ = Concat2("!",$2) ; }
+        | SIZEOF unary_expression      { $$ = Concat2("sizeof",$2) ; }
+        | SIZEOF '(' type_name ')'     { char *temp = Concat3("sizeof","(",$3) ;
+                                         $$ = Concat2(temp,")") ;
+                                       }
+        | allocation_expression                { $$ = $1 ; }
+        ;
+
+
+    /* Note that I could have moved the  newstore  productions  to  a 
+    lower  precedence  level  than  multiplication  (binary '*'), and 
+    lower than bitwise AND (binary '&').  These moves  are  the  nice 
+    way  to  disambiguate a trailing unary '*' or '&' at the end of a 
+    freestore expression.  Since the freestore expression (with  such 
+    a  grammar  and  hence  precedence  given)  can never be the left 
+    operand of a binary '*' or '&', the ambiguity would  be  removed. 
+    These  problems  really  surface when the binary operators '*' or 
+    '&' are overloaded, but this must be syntactically  disambiguated 
+    before the semantic checking is performed...  Unfortunately, I am 
+    not  creating  the language, only writing a grammar that reflects 
+    its specification, and  hence  I  cannot  change  its  precedence 
+    assignments.   If  I  had  my  druthers,  I would probably prefer 
+    surrounding the type with parens all the time, and  avoiding  the 
+    dangling * and & problem all together.*/
+
+       /* Following are C++, not ANSI C */
+allocation_expression:
+        global_opt_scope_opt_operator_new '(' type_name ')'
+                operator_new_initializer_opt
+       {       OutputNewChareMsg($3, $5, NULL) ; }
+
+        | global_opt_scope_opt_operator_new '(' argument_expression_list ')' '(' type_name ')' operator_new_initializer_opt
+         {     OutputNewChareMsg($6, $8, $3) ; }
+
+                /* next two rules are the source of * and & ambiguities */
+        | global_opt_scope_opt_operator_new operator_new_type
+         {     OutputNewChareMsg(NewType, $2, NULL) ;}
+
+        | global_opt_scope_opt_operator_new '(' argument_expression_list ')' operator_new_type
+         {     OutputNewChareMsg(NewType, $5, $3) ; }
+        ;
+
+
+       /* Following are C++, not ANSI C */
+global_opt_scope_opt_operator_new:
+        NEW                    { NewOpType = NEW ; }
+        | NEWCHARE             { NewOpType = NEWCHARE ; }
+        | NEWGROUP             { NewOpType = NEWGROUP ; }
+        | global_or_scope NEW  { NewOpType = NEW ; }
+        ;
+
+operator_new_type:
+        type_qualifier_list              operator_new_declarator_opt
+                        operator_new_initializer_opt
+
+        | non_elaborating_type_specifier operator_new_declarator_opt
+                        operator_new_initializer_opt
+         {     NewType = (char *)malloc(strlen($1)+1) ;
+               strcpy(NewType, $1) ;
+               $$ = $3 ;
+         }
+               
+        ;
+
+    
+    /*  Right  recursion  is critical in the following productions to 
+    avoid a conflict on TYPEDEFname */
+
+operator_new_declarator_opt:
+        /* Nothing */ { FoundDeclarator = FALSE; }
+        | operator_new_array_declarator                
+         { FoundDeclarator = TRUE; }
+        | asterisk_or_ampersand operator_new_declarator_opt            
+         { FoundDeclarator = TRUE; }
+        | unary_modifier        operator_new_declarator_opt            
+         { FoundDeclarator = TRUE; }
+        ;
+
+operator_new_array_declarator:
+                                        '['                  ']'
+        |                               '[' comma_expression ']'
+        | operator_new_array_declarator '[' comma_expression ']'
+        ;
+
+operator_new_initializer_opt:
+        /* Nothing */                          { $$ = NULL ; }
+        | '('                          ')'     { $$ = NULL ; }
+        | '(' argument_expression_list ')'     { $$ = $2 ; }
+        ;
+
+cast_expression:
+        unary_expression       { $$=$1 ; }
+        | '(' type_name ')' cast_expression
+         { char *temp = Concat3("(",$2,")") ; 
+           $$ = Concat2(temp,$4) ;
+         }
+        ;
+
+
+    /* Following are C++, not ANSI C */
+deallocation_expression:
+        cast_expression        { $$=$1 ; }
+        | global_opt_scope_opt_delete deallocation_expression
+        | global_opt_scope_opt_delete '[' comma_expression ']' deallocation_expression  /* archaic C++, what a concept */
+        | global_opt_scope_opt_delete '[' ']' deallocation_expression
+        ;
+
+
+    /* Following are C++, not ANSI C */
+global_opt_scope_opt_delete:
+        DELETE
+        | global_or_scope DELETE
+        ;
+
+
+    /* Following are C++, not ANSI C */
+point_member_expression:
+        deallocation_expression        { $$=$1 ; }
+        | point_member_expression DOTstar  deallocation_expression
+         { $$ = Concat3($1,".*",$3) ; }
+        | point_member_expression ARROWstar  deallocation_expression
+         { $$ = Concat3($1,"->*",$3) ; }
+        ;
+
+multiplicative_expression:
+        point_member_expression        { $$=$1 ; }
+        | multiplicative_expression '*' point_member_expression
+         { $$ = Concat3($1,"*",$3) ; }
+        | multiplicative_expression '/' point_member_expression
+         { $$ = Concat3($1,"/",$3) ; }
+        | multiplicative_expression '%' point_member_expression
+         { $$ = Concat3($1,"%",$3) ; }
+        ;
+
+additive_expression:
+        multiplicative_expression      { $$=$1 ; }
+        | additive_expression '+' multiplicative_expression
+         { $$ = Concat3($1,"+",$3) ; }
+        | additive_expression '-' multiplicative_expression
+         { $$ = Concat3($1,"-",$3) ; }
+        ;
+
+shift_expression:
+        additive_expression    { $$=$1 ; }
+        | shift_expression LS additive_expression
+         { $$ = Concat3($1,"<<",$3) ; }
+        | shift_expression RS additive_expression
+         { $$ = Concat3($1,">>",$3) ; }
+        ;
+
+relational_expression:
+        shift_expression       { $$=$1 ; }
+        | relational_expression '<' shift_expression
+         { $$ = Concat3($1,"<",$3) ; }
+        | relational_expression '>' shift_expression
+         { $$ = Concat3($1,">",$3) ; }
+        | relational_expression LE  shift_expression
+         { $$ = Concat3($1,"<=",$3) ; }
+        | relational_expression GE  shift_expression
+         { $$ = Concat3($1,">=",$3) ; }
+        ;
+
+equality_expression:
+        relational_expression  { $$=$1 ; }
+        | equality_expression EQ relational_expression
+         { $$ = Concat3($1,"==",$3) ; }
+        | equality_expression NE relational_expression
+         { $$ = Concat3($1,"!=",$3) ; }
+        ;
+
+AND_expression:
+        equality_expression    { $$=$1 ; }
+        | AND_expression '&' equality_expression
+         { $$ = Concat3($1,"&",$3) ; }
+        ;
+
+exclusive_OR_expression:
+        AND_expression { $$=$1 ; }
+        | exclusive_OR_expression '^' AND_expression
+         { $$ = Concat3($1,"^",$3) ; }
+        ;
+
+inclusive_OR_expression:
+        exclusive_OR_expression        { $$=$1 ; }
+        | inclusive_OR_expression '|' exclusive_OR_expression
+         { $$ = Concat3($1,"|",$3) ; }
+        ;
+
+logical_AND_expression:
+        inclusive_OR_expression        { $$=$1 ; }
+        | logical_AND_expression ANDAND inclusive_OR_expression
+         { $$ = Concat3($1,"&&",$3) ; }
+        ;
+
+logical_OR_expression:
+        logical_AND_expression { $$=$1 ; }
+        | logical_OR_expression OROR logical_AND_expression
+         { $$ = Concat3($1,"||",$3) ; }
+        ;
+
+conditional_expression:
+        logical_OR_expression  { $$=$1 ; }
+
+        | logical_OR_expression '?' comma_expression ':'
+                conditional_expression
+         { char *temp = Concat3($1,"?",$3) ;
+           $$ = Concat3(temp,":",$5) ;
+         }
+        ;
+
+assignment_expression:
+        conditional_expression { $$=$1 ; }
+        | unary_expression assignment_operator assignment_expression
+         { $$ = Concat3($1,CurrentAssOp,$3) ; }
+        ;
+
+assignment_operator:
+        '='                    { $$ = $1 ; strcpy(CurrentAssOp,"=") ;}
+        | MULTassign           { $$ = $1 ; strcpy(CurrentAssOp,"*=") ;}
+        | DIVassign            { $$ = $1 ; strcpy(CurrentAssOp,"/=") ;}
+        | MODassign            { $$ = $1 ; strcpy(CurrentAssOp,"%=") ;}
+        | PLUSassign           { $$ = $1 ; strcpy(CurrentAssOp,"+=") ;}
+        | MINUSassign          { $$ = $1 ; strcpy(CurrentAssOp,"-=") ;}
+        | LSassign             { $$ = $1 ; strcpy(CurrentAssOp,"<<=") ;}
+        | RSassign             { $$ = $1 ; strcpy(CurrentAssOp,">>=") ;}
+        | ANDassign            { $$ = $1 ; strcpy(CurrentAssOp,"&=") ;}
+        | ERassign             { $$ = $1 ; strcpy(CurrentAssOp,"^=") ;}
+        | ORassign             { $$ = $1 ; strcpy(CurrentAssOp,"|=") ;}
+        ;
+
+comma_expression:
+        assignment_expression  { $$=$1 ; }
+        | comma_expression ',' assignment_expression
+         { $$ = Concat3($1,",",$3) ; }
+        ;
+
+constant_expression:
+        conditional_expression
+        ;
+
+
+    /* The following was used for clarity */
+comma_expression_opt:
+        /* Nothing */
+        | comma_expression
+        ;
+
+
+/******************************* DECLARATIONS ********************************/
+
+
+    /*  The  following are notably different from the ANSI C Standard 
+    specified grammar, but  are  present  in  my  ANSI  C  compatible 
+    grammar.  The changes were made to disambiguate typedefs presence 
+    in   declaration_specifiers   (vs.    in   the   declarator   for 
+    redefinition); to allow struct/union/enum/class tag  declarations 
+    without  declarators,  and  to  better  reflect  the  parsing  of 
+    declarations    (declarators    must     be     combined     with 
+    declaration_specifiers  ASAP, so that they can immediately become 
+    visible in the current scope). */
+
+declaration:
+        declaring_list ';'     
+         {     
+               strcpy(CurrentDeclType,"") ;
+               FoundReadOnly = FALSE ;
+         }
+                                 
+        | default_declaring_list ';'
+         {     
+               strcpy(CurrentDeclType,"") ;
+               FoundReadOnly = FALSE ;
+         }
+        | sue_declaration_specifier ';' { /* this is constraint error, as it
+                                        includes a storage class!?!*/ }
+        | sue_type_specifier ';'
+        | sue_type_specifier_elaboration ';'
+       | error  ';'    { FLUSHBUF() ; }
+        ;
+
+
+    /* Note that if a typedef were  redeclared,  then  a  declaration 
+    specifier  must be supplied (re: ANSI C spec).  The following are 
+    declarations wherein no declaration_specifier  is  supplied,  and 
+    hence the 'default' must be used.  An example of this is
+
+        const a;
+
+    which by default, is the same as:
+
+        const int a;
+
+    `a' must NOT be a typedef in the above example. */
+
+
+    /*  The  presence of `{}' in the following rules indicates points 
+    at which the symbol table MUST be updated so that  the  tokenizer 
+    can  IMMEDIATELY  continue  to  maintain  the  proper distinction 
+    between a TYPEDEFname and an IDENTIFIER. */
+
+default_declaring_list:  /* Can't  redeclare typedef names */
+        declaration_qualifier_list   identifier_declarator {} initializer_opt
+        | type_qualifier_list        identifier_declarator {} initializer_opt
+        | default_declaring_list ',' identifier_declarator {} initializer_opt
+
+        | declaration_qualifier_list constructed_identifier_declarator
+        | type_qualifier_list        constructed_identifier_declarator
+        | default_declaring_list ',' constructed_identifier_declarator
+        ;
+
+
+    /* Note how type_qualifier_list is  NOT  used  in  the  following 
+    productions.    Qualifiers   are   NOT   sufficient  to  redefine 
+    typedef-names (as prescribed by the ANSI C standard).*/
+
+declaring_list:
+        declaration_specifier          declarator 
+       {       strcpy(CurrentDeclType,$1) ;
+               if ( CurrentStorage == TYPEDEF ) {
+                       InsertSymTable($2) ;
+               }
+               else if ( CurrentStorage == EXTERN && CurrentScope == 0 
+                         && FoundParms )
+                       InsertFunctionTable($2,FALSE) ;
+               else if ( FoundReadOnly && CurrentStorage != EXTERN ) {
+                       if ( FoundInMsgTable($1) != -1 )
+                               CurrentAggType = READMSG ;
+                       else 
+                               CurrentAggType = READONLY ;
+                       InsertObjTable($2) ;
+               }
+               CurrentStorage = -1 ;
+       } 
+       initializer_opt
+        | type_specifier               declarator 
+         {     strcpy(CurrentDeclType,$1) ; 
+               if ( FoundReadOnly && CurrentStorage != EXTERN ) {
+                       if ( FoundInMsgTable($1) != -1 )
+                               CurrentAggType = READMSG ;
+                       else
+                               CurrentAggType = READONLY ;
+                       InsertObjTable($2) ;
+               }
+               CurrentStorage = -1 ;
+         } initializer_opt
+        | basic_type_name              declarator 
+         {strcpy(CurrentDeclType,$1) ;} initializer_opt
+        | TYPEDEFname                  declarator 
+         {     strcpy(CurrentDeclType,$1) ;
+               if ( strcmp($1,"table")==0 ) {
+                       CurrentAggType = DTABLE ;
+                       InsertObjTable($2) ;
+               }
+         }
+         initializer_opt
+        | global_or_scoped_typedefname declarator 
+         {strcpy(CurrentDeclType,$1) ;} initializer_opt
+        | declaring_list ','           declarator 
+         {     if ( FoundReadOnly && CurrentStorage != EXTERN ) {
+                       if ( FoundInMsgTable(CurrentDeclType) != -1 )
+                               CurrentAggType = READMSG ;
+                       else
+                               CurrentAggType = READONLY ;
+                       InsertObjTable($3) ;
+               }
+               else if ( strcmp(CurrentDeclType,"table")==0 ) {
+                        CurrentAggType = DTABLE ;
+                       InsertObjTable($3) ;
+               }
+               CurrentStorage = -1 ;
+         } initializer_opt
+
+        | declaration_specifier        constructed_declarator
+        | type_specifier               constructed_declarator
+        | basic_type_name              constructed_declarator
+        | TYPEDEFname                  constructed_declarator
+        | global_or_scoped_typedefname constructed_declarator
+        | declaring_list ','           constructed_declarator
+        ;
+
+
+    /* Declarators with  parenthesized  initializers  present  a  big 
+    problem.  Typically  a  declarator  that looks like: "*a(...)" is 
+    supposed to bind FIRST to the "(...)", and then to the "*".  This 
+    binding  presumes  that  the  "(...)" stuff is a prototype.  With 
+    constructed declarators, we must (officially) finish the  binding 
+    to the "*" (finishing forming a good declarator) and THEN connect 
+    with  the argument list. Unfortunately, by the time we realize it 
+    is an argument list (and not a  prototype)  we  have  pushed  the 
+    separate  declarator  tokens  "*"  and  "a"  onto  the yacc stack 
+    WITHOUT combining them. The solution is to use odd productions to 
+    carry  the  incomplete  declarator  along  with   the   "argument 
+    expression  list" back up the yacc stack.  We would then actually 
+    instantiate the symbol table after we have  fully  decorated  the 
+    symbol  with all the leading "*" stuff.  Actually, since we don't 
+    have all the type information in one spot till  we  reduce  to  a 
+    declaring_list,  this delay is not a problem.  Note that ordinary 
+    initializers REQUIRE (ANSI C Standard) that the symbol be  placed 
+    into  the symbol table BEFORE its initializer is read, but in the 
+    case of parenthesized initializers,  this  is  not  possible  (we 
+    don't  even  know  we  have  an  initializer till have passed the 
+    opening "(". ) */
+
+constructed_declarator:
+        nonunary_constructed_identifier_declarator
+        | constructed_paren_typedef_declarator
+        | simple_paren_typedef_declarator '(' argument_expression_list ')'
+
+        | simple_paren_typedef_declarator postfixing_abstract_declarator
+                                          '(' argument_expression_list ')'  /* constraint error */
+
+        | constructed_parameter_typedef_declarator
+        | asterisk_or_ampersand constructed_declarator
+        | unary_modifier        constructed_declarator
+        ;
+
+constructed_paren_typedef_declarator:
+        '(' paren_typedef_declarator ')'
+                    '(' argument_expression_list ')'
+
+        | '(' paren_typedef_declarator ')' postfixing_abstract_declarator
+                   '(' argument_expression_list ')'
+
+        | '(' simple_paren_typedef_declarator postfixing_abstract_declarator ')'
+                   '(' argument_expression_list ')'
+
+        | '(' TYPEDEFname postfixing_abstract_declarator ')'
+                   '(' argument_expression_list ')'
+        ;
+
+
+constructed_parameter_typedef_declarator:
+        TYPEDEFname    '(' argument_expression_list ')'
+
+        | TYPEDEFname  postfixing_abstract_declarator
+                       '(' argument_expression_list ')'  /* constraint error */
+
+        | '(' clean_typedef_declarator ')'
+                       '(' argument_expression_list ')'
+
+        | '(' clean_typedef_declarator ')'  postfixing_abstract_declarator
+                       '(' argument_expression_list ')'
+        ;
+
+
+constructed_identifier_declarator:
+        nonunary_constructed_identifier_declarator
+        | asterisk_or_ampersand constructed_identifier_declarator
+        | unary_modifier        constructed_identifier_declarator
+        ;
+
+
+    /* The following are restricted to NOT  begin  with  any  pointer 
+    operators.   This  includes both "*" and "T::*" modifiers.  Aside 
+    from  this  restriction,   the   following   would   have   been: 
+    identifier_declarator '(' argument_expression_list ')' */
+
+nonunary_constructed_identifier_declarator:
+        paren_identifier_declarator   '(' argument_expression_list ')'
+
+        | paren_identifier_declarator postfixing_abstract_declarator
+                       '(' argument_expression_list ')'  /* constraint error*/
+
+        | '(' unary_identifier_declarator ')'
+                       '(' argument_expression_list ')'
+
+        | '(' unary_identifier_declarator ')' postfixing_abstract_declarator
+                       '(' argument_expression_list ')'
+        ;
+
+
+declaration_specifier:
+        basic_declaration_specifier  {$$=$1;}     /* Arithmetic or void */
+        | sue_declaration_specifier               /* struct/union/enum/class */
+         { $$ = (char *)malloc(sizeof(char)*2) ;
+           strcpy($$,"") ; 
+          }
+        | typedef_declaration_specifier {$$=$1;}  /* typedef*/
+        ;
+
+type_specifier:
+        basic_type_specifier   {$$ = $1;}    /* Arithmetic or void */
+        | sue_type_specifier                 /* Struct/Union/Enum/Class */
+        | sue_type_specifier_elaboration     /* elaborated Struct/Union/Enum/Class */
+        | typedef_type_specifier  {$$ = $1;} /* Typedef */
+        ;
+
+declaration_qualifier_list:  /* storage class and optional const/volatile */
+        storage_class
+        | type_qualifier_list storage_class
+        | declaration_qualifier_list declaration_qualifier
+        ;
+
+type_qualifier_list:
+        type_qualifier
+        | type_qualifier_list type_qualifier
+        ;
+
+declaration_qualifier:
+        storage_class
+        | type_qualifier                  /* const or volatile */
+        ;
+
+type_qualifier:
+        CONST
+        | VOLATILE
+       | READONLY      
+       { if ( CurrentScope > 0 ) 
+               CharmError("readonly variables allowed only at file scope") ;
+         else 
+               FoundReadOnly = TRUE ;
+       }
+        ;
+
+basic_declaration_specifier:      /*Storage Class+Arithmetic or void*/
+        declaration_qualifier_list    basic_type_name  { $$ = $2 ; }
+        | basic_type_specifier        storage_class    { $$ = $1 ; }
+        | basic_type_name             storage_class    { $$ = $1 ; }
+        | basic_declaration_specifier declaration_qualifier    { $$ = $1 ; }
+        | basic_declaration_specifier basic_type_name  { $$ = $1 ; }
+        ;
+
+basic_type_specifier:
+        type_qualifier_list    basic_type_name /* Arithmetic or void */        
+         { $$ = $1 ; }
+        | basic_type_name      basic_type_name { $$ = $1 ; }
+        | basic_type_name      type_qualifier  { $$ = $1 ; }
+        | basic_type_specifier type_qualifier  { $$ = $1 ; }
+        | basic_type_specifier basic_type_name { $$ = $1 ; }
+        ;
+
+sue_declaration_specifier:          /* Storage Class + struct/union/enum/class */
+        declaration_qualifier_list       elaborated_type_name
+        | declaration_qualifier_list     elaborated_type_name_elaboration
+        | sue_type_specifier             storage_class
+        | sue_type_specifier_elaboration storage_class
+        | sue_declaration_specifier      declaration_qualifier
+        ;
+
+sue_type_specifier_elaboration:
+        elaborated_type_name_elaboration     /* elaborated struct/union/enum/class */
+        | type_qualifier_list elaborated_type_name_elaboration
+        | sue_type_specifier_elaboration type_qualifier
+        ;
+
+sue_type_specifier:
+        elaborated_type_name              /* struct/union/enum/class */
+        | type_qualifier_list elaborated_type_name
+        | sue_type_specifier type_qualifier
+        ;
+
+typedef_declaration_specifier:       /*Storage Class + typedef types */
+        declaration_qualifier_list   TYPEDEFname       { $$ = $2; }
+        | declaration_qualifier_list global_or_scoped_typedefname  { $$ = $2; }
+        | typedef_type_specifier       storage_class   { $$ = $1; }
+        | TYPEDEFname                  storage_class   { $$ = $1; }
+        | global_or_scoped_typedefname storage_class   { $$ = $1; }
+        | typedef_declaration_specifier declaration_qualifier  { $$ = $1; }
+        ;
+
+typedef_type_specifier:              /* typedef types */
+        type_qualifier_list      TYPEDEFname                   { $$ = $2 ; }
+        | type_qualifier_list    global_or_scoped_typedefname  { $$ = $2 ; }
+
+        | TYPEDEFname                  type_qualifier          { $$ = $1 ; }
+        | global_or_scoped_typedefname type_qualifier          { $$ = $1 ; }
+
+        | typedef_type_specifier type_qualifier                        { $$ = $1 ; }
+        ;
+
+
+/*  There  are  really  several distinct sets of storage_classes. The 
+sets vary depending on whether the declaration is at file scope, is a 
+declaration within a struct/class, is within a function body, or in a 
+function declaration/definition (prototype  parameter  declarations).  
+They   are   grouped  here  to  simplify  the  grammar,  and  can  be 
+semantically checked.  Note that this  approach  tends  to  ease  the 
+syntactic restrictions in the grammar slightly, but allows for future 
+language  development,  and tends to provide superior diagnostics and 
+error recovery (i_e.: a syntax error does not disrupt the parse).
+
+
+                File    File    Member  Member  Local   Local  Formal
+                Var     Funct   Var     Funct   Var     Funct  Params
+TYPEDEF         x       x       x       x       x       x
+EXTERN          x       x                       x       x
+STATIC          x       x       x       x       x
+AUTO                                            x              x
+REGISTER                                        x              x
+FRIEND                                  x
+OVERLOAD                x               x               x
+INLINE                  x               x               x
+VIRTUAL                                 x               x
+*/
+
+storage_class:
+        EXTERN         { CurrentStorage = EXTERN ; }
+        | TYPEDEF      { CurrentStorage = TYPEDEF ; }
+        | STATIC       { CurrentStorage = STATIC ; }
+        | AUTO         { CurrentStorage = AUTO ; }
+        | REGISTER     { CurrentStorage = REGISTER ; }
+        | FRIEND   /* C++, not ANSI C */       { CurrentStorage = FRIEND ; }
+        | OVERLOAD /* C++, not ANSI C */       { CurrentStorage = OVERLOAD ; }
+        | INLINE   /* C++, not ANSI C */       { CurrentStorage = INLINE ; 
+                                                 CurrentFnIsInline = TRUE ;
+                                               }
+        | UNDERSCORE_INLINE   /* C++, not ANSI C */    { CurrentStorage = INLINE ; }
+        | VIRTUAL  /* C++, not ANSI C */       { CurrentStorage = VIRTUAL ; }
+        ;
+
+basic_type_name:
+        INT            { $$ = (char *)malloc(4) ; 
+                         strcpy($$,"int") ;       }
+        | CHAR         { $$ = (char *)malloc(5) ; 
+                         strcpy($$,"char") ;      }
+        | SHORT                { $$ = (char *)malloc(6) ; 
+                         strcpy($$,"short") ;     }
+        | LONG         { $$ = (char *)malloc(5) ; 
+                         strcpy($$,"long") ;      }
+        | FLOAT                { $$ = (char *)malloc(6) ; 
+                         strcpy($$,"float") ;     }
+        | PTRDIFF_TOKEN        { $$ = (char *)malloc(10) ; 
+                         strcpy($$,"ptrdiff_t") ; }
+        | WCHAR_TOKEN  { $$ = (char *)malloc(10) ; 
+                         strcpy($$,"wchar_t") ; }
+        | __WCHAR_TOKEN        { $$ = (char *)malloc(10) ; 
+                         strcpy($$,"__wchar_t") ; }
+        | DOUBLE       { $$ = (char *)malloc(7) ; 
+                         strcpy($$,"double") ;    }
+        | SIGNED       { $$ = (char *)malloc(7) ; 
+                         strcpy($$,"signed") ;    }
+        | UNSIGNED     { $$ = (char *)malloc(9) ; 
+                         strcpy($$,"unsigned") ;  }
+        | VOID         { $$ = (char *)malloc(5) ; 
+                         strcpy($$,"void") ;      }
+        ;
+
+elaborated_type_name_elaboration:
+        aggregate_name_elaboration
+        | enum_name_elaboration
+        ;
+
+elaborated_type_name:
+        aggregate_name
+        | enum_name
+        ;
+
+
+    /* Since the expression "new type_name" MIGHT use  an  elaborated 
+    type  and a derivation, it MIGHT have a ':'.  This fact conflicts 
+    with the requirement that a new expression can be placed  between 
+    a '?' and a ':' in a conditional expression (at least it confuses 
+    LR(1)   parsers).   Hence   the   aggregate_name_elaboration   is 
+    responsible for a series of SR conflicts on ':'.*/
+
+    /* The intermediate actions {}  represent  points  at  which  the 
+    database  of  typedef  names  must  be  updated  in C++.  This is 
+    critical to the lexer, which must begin to tokenize based on this 
+    new information. */
+
+aggregate_name_elaboration:
+        aggregate_name derivation_opt  
+       {       if ( CurrentAggType == CHARE ) {
+                       FLUSHBUF() ;    
+                       if ( numparents == 0  )
+                               fprintf(outfile," : public _CK_Object ") ;
+               }
+               /*
+               else if ( CurrentAggType == BRANCHED ) {
+                       FLUSHBUF() ;    
+                       if ( numparents == 0  )
+                               fprintf(outfile," : public _CK_BOC ") ;
+               }
+               */
+               else if ( CurrentAggType == ACCUMULATOR ) {
+                       FLUSHBUF() ;    
+                       if ( numparents == 0  )
+                               fprintf(outfile," : public _CK_Accumulator ") ;
+               }
+               else if ( CurrentAggType == MONOTONIC ) {
+                       FLUSHBUF() ;    
+                       if ( numparents == 0  )
+                               fprintf(outfile," : public _CK_Monotonic ") ;
+               }
+               else if ( CurrentAggType == MESSAGE ) {
+                       FLUSHBUF() ;    
+                       if ( numparents == 0  )
+                               fprintf(outfile," : public comm_object ") ;
+               }
+       } 
+       '{' 
+       {       int num, i ;    
+               ChareInfo *chare ;
+               char *mymsg ;
+               char *myacc ;
+
+               FLUSHBUF() ;
+
+               
+               if ( CurrentAggType != CHARE )
+                       InsertObjTable($1) ;
+               else {
+                       /* First find out if this is a normal chare or a BOC */
+                       if ( numparents > 0 ) {
+                           /* Find if any parent is "groupmember" or a BOC */
+                           for ( i=0; i<numparents; i++ ) {
+                               if (strcmp(ParentArray[i], "groupmember")==0) {
+                                   CurrentAggType = BRANCHED ;
+                                   break ;
+                               }
+                               else if ( FoundInChareTable(BOCTable,boccount+1,ParentArray[i]) != -1 ) {
+                                   CurrentAggType = BRANCHED ;
+                                   break ;
+                               }
+                           }
+                       }
+
+                       InsertObjTable($1) ;
+
+
+                       if ( shouldprint ) fprintf(outfile,"%s",prevtoken) ;
+                       strcpy(prevtoken,"") ;
+
+/***** Sanjeev 10/10/95
+                       if ( numparents == 0 ) { * got to be a chare *
+                           fprintf(outfile,"\n\tpublic: %s(CHARE_BLOCK *c) : _CK_Object(c) {}\n",CurrentChare) ;   
+                       }
+                       else {
+                           fprintf(outfile,"\n\tpublic: %s(CHARE_BLOCK *c) : ",CurrentChare) ;   
+                           for ( i=0; i<numparents-1; i++ ) 
+                               fprintf(outfile,"%s(c), ",ParentArray[i]) ;
+                           fprintf(outfile,"%s(c) {}\n",
+                                                  ParentArray[numparents-1]) ;
+                       }
+                       if ( strcmp(CurrentChare,"main") != 0 )
+                           fprintf(outfile,"\n\t        %s() {}\n",CurrentChare) ;   
+                       fprintf(outfile,"private:\n") ;
+                       fprintf(outfile,"#line %d \"%s\"\n",CurrentLine,
+                                                       CurrentFileName) ;
+******/
+
+                        
+                       if ( CurrentAggType == CHARE )
+                               chare = ChareTable[FoundInChareTable(ChareTable,charecount+1,CurrentChare)] ;
+                       else
+                               chare = BOCTable[FoundInChareTable(BOCTable,boccount+1,CurrentChare)] ;
+
+                       for ( i=0; i<numparents; i++ ) {
+                           if ( CurrentAggType == CHARE )
+                               InsertParent(chare,ParentArray[i],ChareTable,charecount+1) ;
+                           else
+                               InsertParent(chare,ParentArray[i],BOCTable,boccount+1) ;
+                       }
+                       AddInheritedEps(chare) ;
+               }
+               numparents = 0 ; /* so that sequential class derivations dont
+                                   affect us */
+
+               CurrentAccess = PRIVATE ;
+       } 
+       member_declaration_list_opt     { FillPermanentAggTable($1) ; }
+       '}'   
+       {   FLUSHBUF() ;        
+           if ( CurrentAggType == ACCUMULATOR || CurrentAggType == MONOTONIC )
+           {   if ( !FilledAccMsg ) 
+                   CharmError("Unable to detect message in accumulator/monotonic class") ;
+               else {
+                   fprintf(outfile,"\npublic:void * _CK_GetMsgPtr() {\n");
+                   fprintf(outfile,"\t\treturn((void *)%s) ;\n\t}\n",
+                                                            CurrentAcc->msg) ;
+                   if ( CurrentAggType == ACCUMULATOR ) {
+                       fprintf(outfile,"\n       void _CK_Combine(void *msg) {\n");
+                       fprintf(outfile,"\t\tCombine((%s *)msg) ;\n\t}\n",
+                                                        CurrentAcc->msgtype) ;
+                   }
+                   else { /*  MONOTONIC  */
+                       fprintf(outfile,"\n       void _CK_SysUpdate(void *msg) {\n");
+                       fprintf(outfile,"\t\tUpdate((%s *)msg) ;\n\t}\n",
+                                                        CurrentAcc->msgtype) ;
+                       fprintf(outfile,"\n       %s *MonoValue() {\n",
+                                                        CurrentAcc->msgtype) ;
+                       fprintf(outfile,"\t\treturn( (%s *)(::MonoValue(_CK_MyId)) ) ;\n\t}\n",CurrentAcc->msgtype) ;
+
+
+                       fprintf(outfile,"\n      int _CK_Update(%s *msg) {\n",
+                                                        CurrentAcc->msgtype) ;
+                       fprintf(outfile,"\t\tint v ;\n") ;
+                       /* Locking not needed anymore 
+                       fprintf(outfile,"\t\t_CK_9LockMonoDataArea(GetBocDataPtr(_CK_MyId)) ;\n") ;
+                       */
+                       fprintf(outfile,"\t\tv = Update(msg) ;\n") ;
+                       /* Locking not needed anymore 
+                       fprintf(outfile,"\t\t_CK_9UnlockMonoDataArea(GetBocDataPtr(_CK_MyId)) ;\n") ;
+                       */
+                       fprintf(outfile,"\t\tif ( v )\n") ;
+                       fprintf(outfile,"\t\t\t_CK_BroadcastMono((void *)%s,_CK_MyId) ;\n",CurrentAcc->msg) ;
+                       fprintf(outfile,"\t\treturn v ;\n\t}\n") ;
+
+                   }
+                   fprintf(outfile,"\n#line %d \"%s\"\n",CurrentLine,CurrentFileName) ;
+               }
+           }
+           else if ( CurrentAggType == MESSAGE && 
+                                    MessageTable[TotalMsgs-1].numvarsize!=0 ) 
+           { /* Output the pack and unpack and alloc functions for varSize */
+               int i ;
+
+               MsgStruct *thismsg = &(MessageTable[TotalMsgs-1]) ;
+               VarSizeStruct *vs = thismsg->varsizearray ;
+
+               fprintf(outfile,"\nvoid *pack(int *length) \n\t{\n") ;
+
+             /*fprintf(outfile,"\n\t*length = _CK_3GetSizeOfMsg(this) ;\n");
+               the length (size) parm is no longer used in the PACK macro
+               in common/headers/communication.h : Sanjeev, 1 Sep 94 */
+               fprintf(outfile,"\n\t*length = 0 ;\n") ;
+
+               for ( i=0; i<thismsg->numvarsize; i++ ) 
+                       fprintf(outfile,"\n\t%s = (%s *) ((char *)%s - ((char *)&(%s)));\n",vs[i].name,vs[i].type,vs[i].name,vs[i].name) ;
+               fprintf(outfile,"\treturn((void *)this) ;\n}\n") ;
+
+               fprintf(outfile,"\nvoid unpack() \n\t{\n") ;
+               for ( i=0; i<thismsg->numvarsize; i++ ) 
+                       fprintf(outfile,"\n\t%s = (%s *) ((char *)(&%s) + (int)(%s));\n",vs[i].name,vs[i].type,vs[i].name,vs[i].name) ;
+               fprintf(outfile,"}\n") ;
+
+               /* Output the operator delete */
+               fprintf(outfile,"\nvoid operator delete(void *msg) {\n") ;
+               fprintf(outfile,"\tCkFreeMsg(msg) ;\n}\n") ;
+
+               fprintf(outfile,"#line %d \"%s\"\n",CurrentLine,CurrentFileName) ;
+           }
+               
+               
+           CurrentAggType = -1 ; 
+           CurrentAccess = -1 ; 
+           strcpy(CurrentAggName,"") ;
+           strcpy(CurrentChare,"_CK_NOTACHARE") ;
+           CurrentCharePtr = NULL ;
+           InsideChareCode = 0 ;
+       }
+        | aggregate_key derivation_opt '{' member_declaration_list_opt '}'
+        ;
+
+    /* We distinguish between the above, which  support  elaboration, 
+    and  this  set  of  productions  so  that  we can provide special 
+    declaration specifiers for operator_new_type, and for  conversion 
+    functions.  Note that without this restriction a large variety of 
+    conflicts  appear  when  processing  operator_new and conversions 
+    operators (which can be  followed  by  a  ':'  in  a  ternary  ?: 
+    expression) */
+
+    /*  Note that at the end of each of the following rules we should 
+    be sure that the tag name is  in,  or  placed  in  the  indicated 
+    scope.   If  no  scope  is  specified, then we must add it to our 
+    current scope IFF it cannot  be  found  in  an  external  lexical 
+    scope. */
+
+aggregate_name:
+                             aggregate_key tag_name 
+         {     strcpy(CurrentAggName,$2);
+               InsertSymTable($2) ;
+               $$ = $2 ;
+         }
+        | global_scope scope aggregate_key tag_name 
+         {     if ( AddedScope > 0 ) {
+                       PopStack() ;    
+                       AddedScope = 0 ;
+               }
+               strcpy(CurrentAggName,$4);
+               InsertSymTable($4) ;
+               $$ = $4 ;
+         }
+        | global_scope       aggregate_key tag_name 
+         {     strcpy(CurrentAggName,$3);
+               InsertSymTable($3) ;
+               $$ = $3 ;
+         }
+        | scope              aggregate_key tag_name 
+         {     if ( AddedScope > 0 ) {
+                       PopStack() ;    
+                       AddedScope = 0 ;
+               }
+               strcpy(CurrentAggName,$3);
+               InsertSymTable($3) ;
+               $$ = $3 ;
+         }
+        ;
+
+derivation_opt:
+        /* nothing */
+        | ':' derivation_list
+       | ':' error             {FLUSHBUF(); SyntaxError("class defn header");}
+        ;
+
+derivation_list:
+        parent_class   
+       {       ParentArray[numparents] = (char *)malloc(strlen($1)+1) ;
+               strcpy(ParentArray[numparents],$1) ;
+               numparents++ ;
+       }                        
+        | derivation_list ',' parent_class
+       {       ParentArray[numparents] = (char *)malloc(strlen($3)+1) ;
+               strcpy(ParentArray[numparents],$3) ;
+               numparents++ ;
+       }                        
+        ;
+
+parent_class:
+                                       global_opt_scope_opt_typedefname{$$=$1;}
+        | VIRTUAL access_specifier_opt global_opt_scope_opt_typedefname{$$=$3;}
+        | access_specifier virtual_opt global_opt_scope_opt_typedefname{$$=$3;}
+        ;
+
+virtual_opt:
+        /* nothing */
+        | VIRTUAL
+        ;
+
+access_specifier_opt:
+        /* nothing */
+        | access_specifier
+        ;
+
+access_specifier:
+        PUBLIC                 { CurrentAccess = PUBLIC ; }
+        | PRIVATE              { CurrentAccess = PRIVATE ; }
+        | PROTECTED            { CurrentAccess = PROTECTED ; }
+       | ENTRY                 { CurrentAccess = ENTRY ; }
+        ;
+
+aggregate_key:
+        STRUCT                 { CurrentAggType = STRUCT ; }
+        | UNION                        { CurrentAggType = UNION ; }
+        | CLASS /* C++, not ANSI C */  { CurrentAggType = CLASS ; }
+       | CHARE CLASS           { CurrentAggType = CHARE ; }
+/*     | BRANCHED CHARE CLASS  { CurrentAggType = BRANCHED ; }         */
+       | MESSAGE CLASS         { CurrentAggType = MESSAGE ; }
+       | ACCUMULATOR CLASS     { CurrentAggType = ACCUMULATOR ; 
+                                 FilledAccMsg=FALSE; }
+       | MONOTONIC CLASS       { CurrentAggType = MONOTONIC ; 
+                                 FilledAccMsg=FALSE; }
+        ;
+
+
+    /* Note that an empty list is ONLY allowed under C++. The grammar 
+    can  be modified so that this stands out.  The trick is to define 
+    member_declaration_list, and have that referenced for non-trivial 
+    lists. */
+
+member_declaration_list_opt:
+        /* nothing */
+        | member_declaration_list_opt member_declaration 
+         { FLUSHBUF() ;}
+        ;
+
+member_declaration:
+        member_declaring_list ';'              { strcpy(CurrentDeclType,"") ;}
+        | member_default_declaring_list ';'    { strcpy(CurrentDeclType,"") ;}
+
+        | access_specifier ':'               /* C++, not ANSI C */
+
+        | new_function_definition            /* C++, not ANSI C */
+        | constructor_function_in_class      /* C++, not ANSI C */
+
+        | sue_type_specifier             ';' /* C++, not ANSI C */
+        | sue_type_specifier_elaboration ';' /* C++, not ANSI C */
+        | identifier_declarator          ';' /* C++, not ANSI C
+                                                access modification
+                                                conversion functions,
+                                                unscoped destructors */
+
+        | typedef_declaration_specifier ';' /* friend T */       /* C++, not ANSI C */
+        | sue_declaration_specifier ';'     /* friend class C*/  /* C++, not ANSI C */
+        ;
+
+member_default_declaring_list:        /* doesn't redeclare typedef*/
+        type_qualifier_list
+                identifier_declarator member_pure_opt
+
+        | declaration_qualifier_list
+                identifier_declarator member_pure_opt /* C++, not ANSI C */
+
+        | member_default_declaring_list ','
+                identifier_declarator member_pure_opt
+
+        | type_qualifier_list                bit_field_identifier_declarator
+        | declaration_qualifier_list         bit_field_identifier_declarator /* C++, not ANSI C */
+        | member_default_declaring_list ','  bit_field_identifier_declarator
+        ;
+
+
+    /* There is a conflict when "struct A" is used as  a  declaration 
+    specifier,  and  there  is a chance that a bit field name will be 
+    provided.  To fix this syntactically would require distinguishing 
+    non_elaborating_declaration_specifiers   the   way   I    handled 
+    non_elaborating_type_specifiers.   I   think  this  should  be  a 
+    constraint error anyway :-). */
+
+member_declaring_list:        /* Can possibly redeclare typedefs */
+        type_specifier                 declarator member_pure_opt
+         {strcpy(CurrentDeclType,$1) ; 
+          if (FoundParms&&(CurrentAggType==CHARE||CurrentAggType==BRANCHED)) {
+               if ( CurrentAccess == PRIVATE || CurrentAccess == PUBLIC )
+                   ProcessFn($2) ;
+          }
+         }
+        | basic_type_name              declarator 
+         {int ind ;
+          if ( FoundParms ) {
+            if (CurrentAggType==CHARE || CurrentAggType==BRANCHED) {
+               if ( CurrentAccess == ENTRY )
+                   ProcessEP($2,FALSE);
+               else if ( CurrentAccess == PRIVATE||CurrentAccess == PUBLIC ) 
+                   ProcessFn($2) ;
+            }
+            else if ( CurrentAggType == MESSAGE ) {
+               if ( strcmp($2,"pack")==0 || strcmp($2,"unpack")==0 ) {
+                   if ( (ind=FoundInMsgTable(CurrentAggName)) != -1 )
+                       MessageTable[ind].pack = TRUE ; 
+                   else 
+                       CharmError("TRANSLATOR : did not find message type in message table") ;
+               }                       
+               else 
+                       CharmError("Messages are allowed to have only pack or unpack functions") ;
+            }
+            FoundParms = FALSE ;
+          }
+          else if ( CurrentAggType == MESSAGE && FoundVarSize ) {
+               char *varname = Mystrstr(OutBuf,$2) ;
+               *varname = '*' ;
+               *(varname+1) = '\0' ;
+               strcat(OutBuf,$2) ;
+               
+               InsertVarSize($1,$2) ;
+               FoundVarSize = FALSE ;
+          } 
+         }     
+         member_pure_opt
+
+        | global_or_scoped_typedefname declarator member_pure_opt
+         {strcpy(CurrentDeclType,$1) ; 
+          if (FoundParms&&(CurrentAggType==CHARE||CurrentAggType==BRANCHED)) {
+               if ( CurrentAccess == PRIVATE || CurrentAccess == PUBLIC )
+                   ProcessFn($2) ;
+          }
+         }
+        | member_conflict_declaring_item
+        | member_declaring_list ','    declarator member_pure_opt
+
+        | type_specifier                bit_field_declarator
+        | basic_type_name               bit_field_declarator
+        | TYPEDEFname                   bit_field_declarator
+        | global_or_scoped_typedefname  bit_field_declarator
+        | declaration_specifier         bit_field_declarator /* constraint violation: storage class used */
+        | member_declaring_list ','     bit_field_declarator
+        ;
+
+
+    /* The following conflict with constructors-
+      member_conflict_declaring_item:
+        TYPEDEFname             declarator member_pure_opt
+        | declaration_specifier declarator member_pure_opt /* C++, not ANSI C * /
+        ;
+    so we inline expand declarator to get the following productions...
+    */
+member_conflict_declaring_item:
+        TYPEDEFname             identifier_declarator            member_pure_opt
+       { if ( (CurrentAggType==ACCUMULATOR || CurrentAggType==MONOTONIC) 
+               && !FilledAccMsg ) 
+         {     CurrentAcc->msgtype = (char *)malloc((strlen($1)+1)*sizeof(char));
+               strcpy(CurrentAcc->msgtype,$1) ;        
+
+               CurrentAcc->msg = (char *)malloc((strlen($2)+1)*sizeof(char)) ;
+               strcpy(CurrentAcc->msg,$2) ;    
+               FilledAccMsg = TRUE ;
+         }
+         else if ( CurrentAggType == MESSAGE && FoundVarSize ) {
+               char *varname = Mystrstr(OutBuf,$2) ;
+               *varname = '*' ;
+               *(varname+1) = '\0' ;
+               strcat(OutBuf,$2) ;
+               
+               if ( SearchHandleTable(ChareHandleTable,ChareHandleTableSize,$2) != -1 ) 
+                       InsertVarSize("ChareIDType",$2) ;
+               else
+                       InsertVarSize($1,$2) ;
+               FoundVarSize = FALSE ;
+         } 
+         strcpy(CurrentDeclType,$1) ;
+       }
+
+        | TYPEDEFname           parameter_typedef_declarator     member_pure_opt
+         {     strcpy(CurrentDeclType,$1) ;    }
+        | TYPEDEFname           simple_paren_typedef_declarator  member_pure_opt
+          {     strcpy(CurrentDeclType,$1) ;    }
+
+        | declaration_specifier identifier_declarator            member_pure_opt
+          {     strcpy(CurrentDeclType,$1) ;    
+               if ( CurrentStorage == TYPEDEF ) {
+                       InsertSymTable($2) ;
+                       CurrentStorage = -1 ;
+               }
+               else if ( FoundParms ) {
+                       if (CurrentAggType==CHARE || CurrentAggType==BRANCHED){
+                               if ( CurrentAccess == ENTRY ) {
+                                       ProcessEP($2,FALSE);
+                               }
+                               else if ( CurrentAccess == PRIVATE || 
+                                         CurrentAccess == PUBLIC )
+                                       ProcessFn($2) ;
+                       }       
+                       FoundParms = FALSE ;
+               }
+         }
+        | declaration_specifier parameter_typedef_declarator     member_pure_opt
+          {     strcpy(CurrentDeclType,$1) ;    }
+        | declaration_specifier simple_paren_typedef_declarator  member_pure_opt
+          {     strcpy(CurrentDeclType,$1) ;    }
+
+        | member_conflict_paren_declaring_item
+        ;
+
+
+    /* The following still conflicts with constructors-
+      member_conflict_paren_declaring_item:
+        TYPEDEFname             paren_typedef_declarator     member_pure_opt
+        | declaration_specifier paren_typedef_declarator     member_pure_opt
+        ;
+    so paren_typedef_declarator is expanded inline to get...*/
+
+member_conflict_paren_declaring_item:
+        TYPEDEFname   asterisk_or_ampersand
+                '(' simple_paren_typedef_declarator ')' member_pure_opt
+        | TYPEDEFname unary_modifier
+                '(' simple_paren_typedef_declarator ')' member_pure_opt
+        | TYPEDEFname asterisk_or_ampersand
+                '(' TYPEDEFname ')'                     member_pure_opt
+        | TYPEDEFname unary_modifier
+                '(' TYPEDEFname ')'                     member_pure_opt
+        | TYPEDEFname asterisk_or_ampersand
+                 paren_typedef_declarator               member_pure_opt
+        | TYPEDEFname unary_modifier
+                 paren_typedef_declarator               member_pure_opt
+
+        | declaration_specifier asterisk_or_ampersand
+                '(' simple_paren_typedef_declarator ')' member_pure_opt
+        | declaration_specifier unary_modifier
+                '(' simple_paren_typedef_declarator ')' member_pure_opt
+        | declaration_specifier asterisk_or_ampersand
+                '(' TYPEDEFname ')'                     member_pure_opt
+        | declaration_specifier unary_modifier
+                '(' TYPEDEFname ')'                     member_pure_opt
+        | declaration_specifier asterisk_or_ampersand
+                paren_typedef_declarator                member_pure_opt
+        | declaration_specifier unary_modifier
+                paren_typedef_declarator                member_pure_opt
+
+        | member_conflict_paren_postfix_declaring_item
+        ;
+
+
+    /* but we still have the following conflicts with constructors-
+   member_conflict_paren_postfix_declaring_item:
+      TYPEDEFname             postfix_paren_typedef_declarator member_pure_opt
+      | declaration_specifier postfix_paren_typedef_declarator member_pure_opt
+      ;
+    so we expand paren_postfix_typedef inline and get...*/
+
+member_conflict_paren_postfix_declaring_item:
+        TYPEDEFname     '(' paren_typedef_declarator ')'
+                                                           member_pure_opt
+        | TYPEDEFname   '(' simple_paren_typedef_declarator
+                        postfixing_abstract_declarator ')' member_pure_opt
+        | TYPEDEFname   '(' TYPEDEFname
+                        postfixing_abstract_declarator ')' member_pure_opt
+        | TYPEDEFname   '(' paren_typedef_declarator ')'
+                        postfixing_abstract_declarator     member_pure_opt
+
+        | declaration_specifier '(' paren_typedef_declarator ')'
+                                                           member_pure_opt
+        | declaration_specifier '(' simple_paren_typedef_declarator
+                        postfixing_abstract_declarator ')' member_pure_opt
+        | declaration_specifier '(' TYPEDEFname
+                        postfixing_abstract_declarator ')' member_pure_opt
+        | declaration_specifier '(' paren_typedef_declarator ')'
+                        postfixing_abstract_declarator     member_pure_opt
+        ;
+    /* ...and we are done.  Now all  the  conflicts  appear  on  ';', 
+    which can be semantically evaluated/disambiguated */
+
+
+member_pure_opt:
+        /* nothing */
+        | '=' OCTALconstant /* C++, not ANSI C */ /* Pure function*/
+        ;
+
+
+    /*  Note  that  bit  field  names, where redefining TYPEDEFnames, 
+    cannot be parenthesized in C++ (due to  ambiguities),  and  hence 
+    this  part of the grammar is simpler than ANSI C. :-) The problem 
+    occurs because:
+
+         TYPEDEFname ( TYPEDEFname) : .....
+
+    doesn't look like a bit field, rather it looks like a constructor 
+    definition! */
+
+bit_field_declarator:
+        bit_field_identifier_declarator
+        | TYPEDEFname {} ':' constant_expression
+        ;
+
+
+    /* The actions taken in the "{}" above and below are intended  to 
+    allow  the  symbol  table  to  be  updated when the declarator is 
+    complete.  It is critical for code like:
+
+            foo : sizeof(foo + 1);
+    */
+
+bit_field_identifier_declarator:
+                                   ':' constant_expression
+        | identifier_declarator {} ':' constant_expression
+        ;
+
+enum_name_elaboration:
+        global_opt_scope_opt_enum_key '{' enumerator_list '}'
+        | enum_name                   '{' enumerator_list '}'
+        ;
+
+
+    /* As with structures, the distinction between "elaborating"  and 
+    "non-elaborating"  enum  types  is  maintained.  In actuality, it 
+    probably does not cause much in the way of conflicts, since a ':' 
+    is not allowed.  For symmetry, we maintain the distinction.   The 
+    {}  actions are intended to allow the symbol table to be updated.  
+    These updates are significant to code such as:
+
+        enum A { first=sizeof(A)};
+    */
+
+enum_name:
+        global_opt_scope_opt_enum_key tag_name { InsertSymTable($2) ; }
+        ;
+
+global_opt_scope_opt_enum_key:
+        ENUM
+        | global_or_scope ENUM
+        ;
+
+enumerator_list:
+        enumerator_list_no_trailing_comma
+        | enumerator_list_no_trailing_comma ',' /* C++, not ANSI C */
+        ;
+
+
+    /* Note that we do not need to rush to add an enumerator  to  the 
+    symbol  table  until  *AFTER* the enumerator_value_opt is parsed. 
+    The enumerated value is only in scope  AFTER  its  definition  is 
+    complete.   Hence the following is legal: "enum {a, b=a+10};" but 
+    the following is (assuming no external matching of names) is  not 
+    legal:  "enum {c, d=sizeof(d)};" ("d" not defined when sizeof was 
+    applied.) This is  notably  contrasted  with  declarators,  which 
+    enter scope as soon as the declarator is complete. */
+
+enumerator_list_no_trailing_comma:
+        enumerator_name enumerator_value_opt
+        | enumerator_list_no_trailing_comma ',' enumerator_name enumerator_value_opt
+        ;
+
+enumerator_name:
+        IDENTIFIER
+        | TYPEDEFname
+        ;
+
+enumerator_value_opt:
+        /* Nothing */
+        | '=' constant_expression
+        ;
+
+
+    /*  We special case the lone type_name which has no storage class 
+    (even though it should be an example of  a  parameter_type_list). 
+    This helped to disambiguate type-names in parenthetical casts.*/
+
+parameter_type_list:
+        '(' ')'                             type_qualifier_list_opt
+        | '(' type_name ')'                 type_qualifier_list_opt
+         {     EpMsg=$2; 
+         }
+        | '(' type_name initializer ')'     type_qualifier_list_opt /* C++, not ANSI C */
+        | '(' named_parameter_type_list ')' type_qualifier_list_opt 
+                       
+        ;
+
+
+    /* The following are used in old style function definitions, when 
+    a complex return type includes the "function returning" modifier. 
+    Note  the  subtle  distinction  from  parameter_type_list.  These 
+    parameters are NOT the parameters for the function being defined, 
+    but are simply part of the type definition.  An example would be:
+
+        int(*f(   a  ))(float) long a; {...}
+
+    which is equivalent to the full new style definition:
+
+        int(*f(long a))(float) {...}
+
+    The   type   list    `(float)'    is    an    example    of    an 
+    old_parameter_type_list.   The  bizarre point here is that an old 
+    function definition declarator can be followed by  a  type  list, 
+    which  can  start  with a qualifier `const'.  This conflicts with 
+    the new syntactic construct for const member  functions!?!  As  a 
+    result,  an  old  style function definition cannot be used in all 
+    cases for a member function.  */
+
+old_parameter_type_list:
+        '(' ')'
+        | '(' type_name ')'
+        | '(' type_name initializer ')'  /* C++, not ANSI C */
+        | '(' named_parameter_type_list ')'
+        ;
+
+named_parameter_type_list:  /* WARNING: excludes lone type_name*/
+        parameter_list
+        | parameter_list comma_opt_ellipsis
+        | type_name comma_opt_ellipsis
+        | type_name initializer comma_opt_ellipsis  /* C++, not ANSI C */
+        | ELLIPSIS /* C++, not ANSI C */
+        ;
+
+comma_opt_ellipsis:
+        ELLIPSIS       /* C++, not ANSI C */
+        | ',' ELLIPSIS
+        ;
+
+parameter_list:
+        non_casting_parameter_declaration
+        | non_casting_parameter_declaration initializer /* C++, not ANSI C */
+        | type_name             ',' parameter_declaration
+        | type_name initializer ',' parameter_declaration  /* C++, not ANSI C */
+        | parameter_list        ',' parameter_declaration
+        ;
+
+
+    /* There is some very subtle disambiguation going  on  here.   Do 
+    not be tempted to make further use of the following production in 
+    parameter_list,  or else the conflict count will grow noticeably. 
+    Specifically, the next set  of  rules  has  already  been  inline 
+    expanded for the first parameter in a parameter_list to support a 
+    deferred disambiguation. The subtle disambiguation has to do with 
+    contexts where parameter type lists look like old-style-casts. */
+
+parameter_declaration:
+        type_name
+        | type_name                         initializer  /* C++, not ANSI C */
+        | non_casting_parameter_declaration
+        | non_casting_parameter_declaration initializer /* C++, not ANSI C */
+        ;
+
+
+    /* There is an LR ambiguity between old-style parenthesized casts 
+    and parameter-type-lists.  This tends to happen in contexts where 
+    either  an  expression or a parameter-type-list is possible.  For 
+    example, assume that T is an  externally  declared  type  in  the 
+    code:
+
+           int (T ((int
+
+    it might continue:
+
+           int (T ((int)0));
+
+    which would make it:
+
+           (int) (T) (int)0 ;
+
+    which  is  an  expression,  consisting  of  a  series  of  casts.  
+    Alternatively, it could be:
+
+           int (T ((int a)));
+
+    which would make it the redeclaration of T, equivalent to:
+
+           int T (dummy_name (int a));
+
+    if we see a type that either has a named variable (in  the  above 
+    case "a"), or a storage class like:
+
+           int (T ((int register
+
+    then  we  know  it  can't  be  a cast, and it is "forced" to be a 
+    parameter_list.
+
+    It is not yet clear that the ANSI C++ committee would  decide  to 
+    place this disambiguation into the syntax, rather than leaving it 
+    as  a  constraint check (i.e., a valid parser would have to parse 
+    everything as though it were  a  parameter  list  (in  these  odd 
+    contexts),  and  then  give an error if is to a following context 
+    (like "0" above) that invalidated this syntax evaluation. */
+
+    /* One big thing implemented here is that a TYPEDEFname CANNOT be 
+    redeclared when we don't have declaration_specifiers! Notice that 
+    when we do use a TYPEDEFname based declarator, only the "special" 
+    (non-ambiguous  in  this  context)  typedef_declarator  is  used. 
+    Everything else that is "missing" shows up as a type_name. */
+
+non_casting_parameter_declaration: /*have names or storage classes */
+        declaration_specifier
+        | declaration_specifier abstract_declarator
+        | declaration_specifier identifier_declarator
+        | declaration_specifier parameter_typedef_declarator
+
+        | declaration_qualifier_list
+        | declaration_qualifier_list abstract_declarator
+        | declaration_qualifier_list identifier_declarator
+
+        | type_specifier identifier_declarator
+        | type_specifier parameter_typedef_declarator
+
+        | basic_type_name identifier_declarator
+        | basic_type_name parameter_typedef_declarator
+
+        | TYPEDEFname     identifier_declarator        
+         {     EpMsg=$1; 
+               strcpy(CurrentMsgParm,$1) ;
+         }
+        | TYPEDEFname     parameter_typedef_declarator 
+         {     EpMsg=$1; 
+               strcpy(CurrentMsgParm,$1) ;
+         }
+
+        | global_or_scoped_typedefname  identifier_declarator
+        | global_or_scoped_typedefname  parameter_typedef_declarator
+
+        | type_qualifier_list identifier_declarator
+        ;
+
+type_name:
+        type_specifier
+        | basic_type_name              
+        | TYPEDEFname                  { $$ = $1 ; }
+        | global_or_scoped_typedefname
+        | type_qualifier_list
+
+        | type_specifier               abstract_declarator
+        | basic_type_name              abstract_declarator
+        | TYPEDEFname                  abstract_declarator
+        | global_or_scoped_typedefname abstract_declarator
+        | type_qualifier_list          abstract_declarator
+        ;
+
+initializer_opt:
+        /* nothing */
+        | initializer
+        ;
+
+initializer:
+        '=' initializer_group
+        ;
+
+initializer_group:
+        '{' initializer_list '}'
+        | '{' initializer_list ',' '}'
+        | assignment_expression
+        ;
+
+initializer_list:
+        initializer_group
+        | initializer_list ',' initializer_group
+        ;
+
+
+/*************************** STATEMENTS *******************************/
+
+statement:
+        labeled_statement
+        | compound_statement
+        | expression_statement
+        | selection_statement
+        | iteration_statement
+        | jump_statement
+        | declaration /* C++, not ANSI C */
+        ;
+
+labeled_statement:
+        label                      ':' statement
+        | CASE constant_expression ':' statement
+        | DEFAULT                  ':' statement
+        ;
+
+
+    /*  I sneak declarations into statement_list to support C++.  The 
+    grammar is a little clumsy this  way,  but  the  violation  of  C 
+    syntax is heavily localized */
+
+compound_statement:
+        '{' 
+       {       if ( FoundAccFnDef ) {
+                       strcat(OutBuf,prevtoken) ;
+                       strcpy(prevtoken,"") ;
+                       FLUSHBUF() ;
+                       /* No locking needed anymore 
+                       fprintf(outfile,"\n_CK_9LockAccDataArea(GetBocDataPtr(_CK_MyId)) ;\n") ;
+                       */
+                       fprintf(outfile,"\n#line %d \"%s\"\n",CurrentLine,CurrentFileName) ;
+                       AccFnScope = CurrentScope ;
+                       FoundAccFnDef = FALSE ;
+               }
+       } 
+       statement_list_opt 
+       {       if ( AccFnScope == CurrentScope+1 ) {
+               /* +1 because the '}' has already been lexed at this point */
+                       FLUSHBUF() ;
+                       /* No locking needed anymore 
+                       fprintf(outfile,"\n_CK_9UnlockAccDataArea(GetBocDataPtr(_CK_MyId)) ;\n") ;
+                       */
+                       fprintf(outfile,"\n#line %d \"%s\"\n",CurrentLine,CurrentFileName) ;
+                       AccFnScope = -1 ;
+               }
+       } 
+       '}'     { FLUSHBUF() ; }
+
+/*     | '{' statement_list_opt error  { FLUSHBUF() ; 
+                                         SyntaxError("compound statement") ; }
+         '}'
+this rule caused conflicts with the one above, so I removed it : SANJEEV */
+        ;
+
+declaration_list:
+        declaration                    { FLUSHBUF() ; }
+        | declaration_list declaration { FLUSHBUF() ; }
+        ;
+
+statement_list_opt:
+        /* nothing */
+        | statement_list_opt statement { FLUSHBUF() ; }
+        ;
+
+expression_statement:
+        comma_expression_opt ';'
+        ;
+
+selection_statement:
+          IF if_cond statement
+        | IF if_cond statement ELSE statement
+        | SWITCH if_cond statement
+        ;
+
+if_cond:
+         '(' comma_expression ')'  { FLUSHBUF(); }
+       | '(' error ')' { FLUSHBUF(); 
+                         SyntaxError("if/switch condition") ;}
+       ;
+
+iteration_statement:
+        WHILE '(' comma_expression_opt ')' {FLUSHBUF();} statement
+       | WHILE '(' error ')'   { FLUSHBUF() ; 
+                                 SyntaxError("while loop condition");}
+         statement  
+
+        | DO statement WHILE '(' comma_expression ')' ';'
+       | DO statement WHILE '(' error ')'      { FLUSHBUF() ; 
+                                   SyntaxError("do loop condition"); }
+         ';'   
+
+        | FOR '(' comma_expression_opt ';' comma_expression_opt ';'
+                comma_expression_opt ')' {FLUSHBUF();} statement
+
+        | FOR '(' declaration        comma_expression_opt ';'
+                comma_expression_opt ')' statement  /* C++, not ANSI C */
+       | FOR '(' error ')'     { FLUSHBUF() ; 
+                                 SyntaxError("for loop header") ; }
+         statement     
+        ;
+
+jump_statement:
+        GOTO label                     ';'
+        | CONTINUE                     ';'
+        | BREAK                        ';'
+        | RETURN comma_expression_opt  ';'
+        ;
+
+
+    /*  The  following  actions should update the symbol table in the 
+    "label" name space */
+
+label:
+        IDENTIFIER
+        | TYPEDEFname
+        ;
+
+
+/***************************** EXTERNAL DEFINITIONS *****************************/
+
+translation_unit:
+        /* nothing */
+        | translation_unit external_definition         { FLUSHBUF() ; 
+                                                 strcpy(CurrentAggName,"") ;
+                                               }
+
+external_definition:
+        function_declaration                         /* C++, not ANSI C*/
+        | function_definition
+        | declaration
+        | linkage_specifier function_declaration     /* C++, not ANSI C*/
+        | linkage_specifier function_definition      /* C++, not ANSI C*/
+        | linkage_specifier declaration              /* C++, not ANSI C*/
+        | linkage_specifier '{'        
+         {     
+               if ( FoundLBrace ) 
+                       FoundLBrace = 0 ;
+         }
+         translation_unit 
+         {
+               if ( FoundRBrace ) 
+                       FoundRBrace = 0 ;
+         }
+         '}' /* C++, not ANSI C*/
+        ;
+
+linkage_specifier:
+        EXTERN STRINGliteral
+        ;
+
+
+    /* Note that declaration_specifiers are left out of the following 
+    function declarations.  Such omission is illegal in ANSI C. It is 
+    sometimes necessary in C++, in instances  where  no  return  type 
+    should be specified (e_g., a conversion operator).*/
+
+function_declaration:
+        identifier_declarator ';'   /*  semantically  verify  it is a 
+                                    function, and (if ANSI says  it's 
+                                    the  law for C++ also...) that it 
+                                    is something that  can't  have  a 
+                                    return  type  (like  a conversion 
+                                    function, or a destructor */
+
+        | constructor_function_declaration ';'
+        ;
+
+function_definition:
+        new_function_definition                
+       {       
+               if ( !CurrentFnIsInline )
+                       InsertFunctionTable($1,TRUE) ; 
+               else
+                       CurrentFnIsInline = FALSE ;
+       }
+        | old_function_definition
+        | constructor_function_definition
+        ;
+
+
+    /* Note that in ANSI C, function definitions *ONLY* are presented 
+    at file scope.  Hence, if there is a typedefname  active,  it  is 
+    illegal  to  redeclare  it  (there  is no enclosing scope at file 
+    scope).
+
+    In  contrast,  C++  allows   function   definitions   at   struct 
+    elaboration scope, and allows tags that are defined at file scope 
+    (and  hence  look like typedefnames) to be redeclared to function 
+    calls.  Hence several of the rules are "partially C++  only".   I 
+    could  actually  build separate rules for typedef_declarators and 
+    identifier_declarators, and mention that  the  typedef_declarator 
+    rules represent the C++ only features.
+
+    In  some  sense,  this  is  haggling, as I could/should have left 
+    these as constraints in the ANSI C grammar, rather than as syntax 
+    requirements.  */
+
+new_function_definition:
+                                       identifier_declarator 
+         {     AddScope($1) ;  } 
+         compound_statement    
+         { RemoveScope($1) ; $$ = $1 ;
+           if (CurrentAggType==CHARE || CurrentAggType==BRANCHED) {
+               if ( CurrentAccess == PRIVATE || CurrentAccess == PUBLIC )
+                   ProcessFn($1) ;
+           }
+         }
+        | declaration_specifier                   declarator 
+         {if ( CurrentAggType==CHARE || CurrentAggType==BRANCHED ) {
+                if ( CurrentAccess == ENTRY )
+                        ProcessEP($2,TRUE);
+               else if ( CurrentAccess == PRIVATE || CurrentAccess == PUBLIC )
+                       ProcessFn($2) ;
+               InsideChareCode = 1 ;
+          }
+          else 
+               SetDefinedIfEp($2) ;
+          AddScope($2) ;               
+         } 
+         compound_statement /* partially C++ only */   
+         { RemoveScope($2) ; 
+           $$ = $2 ;
+           InsideChareCode = 0 ;
+         }
+       | declaration_specifier error   { FLUSHBUF() ; 
+                                         SyntaxError("function header") ; }
+         compound_statement
+
+        | type_specifier                          declarator 
+         {       AddScope($2) ;  } 
+         compound_statement /* partially C++ only */   
+         { RemoveScope($2) ; 
+           $$ = $2 ;
+         }
+
+        | basic_type_name                         declarator 
+         {int ind ;
+          if ( CurrentAggType==CHARE || CurrentAggType==BRANCHED ) {
+               if ( CurrentAccess == ENTRY )
+                       ProcessEP($2,TRUE);
+               else if ( CurrentAccess == PRIVATE || CurrentAccess == PUBLIC )
+                       ProcessFn($2) ;
+               InsideChareCode = 1 ;
+          }
+          else if ( CurrentAggType == MESSAGE ) {
+               if ( strcmp($2,"pack")==0 || strcmp($2,"unpack")==0 ) {
+                       if ( (ind=FoundInMsgTable(CurrentAggName)) != -1 )
+                               MessageTable[ind].pack = TRUE ; 
+                       else 
+                               CharmError("TRANSLATOR : did not find message type in message table") ;
+               }                       
+               else 
+                       CharmError("Messages are allowed to have only pack or unpack functions") ;
+          }
+          else if ( CurrentAggType == ACCUMULATOR ) {
+               if ( strcmp($2,"Accumulate")==0 && strcmp($1,"void")==0 ) 
+                       FoundAccFnDef = TRUE ;
+          }
+          else 
+               SetDefinedIfEp($2) ;
+          FLUSHBUF() ;
+          AddScope($2) ;               
+         } 
+         compound_statement /* partially C++ only */   
+         { RemoveScope($2) ; 
+           $$ = $2 ;
+           InsideChareCode = 0 ;
+         }
+
+       | basic_type_name error { FLUSHBUF() ; 
+                                 SyntaxError("function header") ; }
+         compound_statement
+
+        | TYPEDEFname                             declarator 
+         {AddScope($2) ;} compound_statement /* partially C++ only */  
+         { RemoveScope($2) ; 
+           $$ = $2 ;
+         }
+        | global_or_scoped_typedefname            declarator 
+         {AddScope($2) ;} compound_statement /* partially C++ only */  
+         { RemoveScope($2) ; 
+           $$ = $2 ;
+         }
+        | declaration_qualifier_list   identifier_declarator 
+         {AddScope($2) ;} compound_statement   
+         { RemoveScope($2) ; 
+           $$ = $2 ;
+         }
+        | type_qualifier_list          identifier_declarator 
+         {AddScope($2) ;} compound_statement   
+         { RemoveScope($2) ; 
+           $$ = $2 ;
+         }
+        ;
+
+
+    /* Note that I do not support redeclaration of TYPEDEFnames  into 
+    function  names  as I did in new_function_definitions (see note). 
+    Perhaps I should do it, but for now, ignore the issue. Note  that 
+    this  is  a  non-problem  with  ANSI  C,  as  tag  names  are not 
+    considered TYPEDEFnames. */
+
+old_function_definition:
+                                       old_function_declarator {} old_function_body
+        | declaration_specifier        old_function_declarator {} old_function_body
+        | type_specifier               old_function_declarator {} old_function_body
+        | basic_type_name              old_function_declarator {} old_function_body
+        | TYPEDEFname                  old_function_declarator {} old_function_body
+        | global_or_scoped_typedefname old_function_declarator {} old_function_body
+        | declaration_qualifier_list   old_function_declarator {} old_function_body
+        | type_qualifier_list          old_function_declarator {} old_function_body
+        ;
+
+old_function_body:
+        declaration_list compound_statement
+        | compound_statement
+        ;
+
+
+    /*    Verify    via    constraints     that     the     following 
+        declaration_specifier           is          really          a 
+        typedef_declaration_specifier, consisting of:
+
+        ... TYPEDEFname :: TYPEDEFname
+
+    optionally *preceded* by a "inline" keyword.   Use  care  not  to 
+    support "inline" as a postfix!
+
+    Similarly, the global_or_scoped_typedefname must be:
+
+        ... TYPEDEFname :: TYPEDEFname
+
+    with matching names at the end of the list.
+
+    We  use the more general form to prevent a syntax conflict with a 
+    typical    function    definition    (which    won't    have    a 
+    constructor_init_list) */
+
+constructor_function_definition:
+        global_or_scoped_typedefname parameter_type_list
+        constructor_init_list_opt 
+       {       int ind ;       
+
+               SetDefinedIfEp($1) ;
+               CheckConstructorEP($1,TRUE) ; 
+
+               if ( (ind=FoundInAccTable(AccTable,TotalAccs,$1)) != -1 ) {
+               /* This is an Accumulator constructor */
+                       AccTable[ind]->initmsgtype = (char *)malloc((strlen(CurrentMsgParm)+1)*sizeof(char)) ;
+                       strcpy(AccTable[ind]->initmsgtype,CurrentMsgParm) ;
+                       AccTable[ind]->defined = 1 ;
+               }
+               else if ( (ind=FoundInAccTable(MonoTable,TotalMonos,$1)) != -1 ) {
+               /* This is a Monotonic constructor */
+                       MonoTable[ind]->initmsgtype = (char *)malloc((strlen(CurrentMsgParm)+1)*sizeof(char)) ;
+                       strcpy(MonoTable[ind]->initmsgtype,CurrentMsgParm) ;
+                       MonoTable[ind]->defined = 1 ;
+               }
+
+               AddScope($1) ;          
+       }
+       compound_statement
+       {       RemoveScope($1) ;
+               InsideChareCode = 0 ;
+       }
+
+        | declaration_specifier      parameter_type_list
+                     constructor_init_list_opt compound_statement
+        ;
+
+
+    /*  Same  comments  as  seen  for constructor_function_definition 
+    apply here */
+
+constructor_function_declaration:
+        global_or_scoped_typedefname parameter_type_list  /* wasteful redeclaration; used for friend decls.  */
+
+        | declaration_specifier      parameter_type_list  /* request to inline, no definition */
+        ;
+
+
+    /* The following use of declaration_specifiers are made to  allow 
+    for  a TYPEDEFname preceded by an INLINE modifier. This fact must 
+    be verified semantically.  It should also be  verified  that  the 
+    TYPEDEFname  is  ACTUALLY  the  class name being elaborated. Note 
+    that we could break out typedef_declaration_specifier from within 
+    declaration_specifier, and we  might  narrow  down  the  conflict 
+    region a bit. A second alternative (to what is done) for cleaning 
+    up  this  stuff  is  to  let the tokenizer specially identify the 
+    current class being elaborated as a special token, and not just a 
+    typedefname. Unfortunately, things would get very  confusing  for 
+    the  lexer,  as  we may pop into enclosed tag elaboration scopes; 
+    into function definitions; or into both recursively! */
+
+    /* I should make the following  rules  easier  to  annotate  with 
+    scope  entry  and exit actions.  Note how hard it is to establish 
+    the scope when you don't even know what the decl_spec is!! It can 
+    be done with $-1 hacking, but I should not encourage users to  do 
+    this directly. */
+
+constructor_function_in_class:
+        declaration_specifier   constructor_parameter_list_and_body
+         {     foundargs = FALSE ; }
+        | TYPEDEFname           constructor_parameter_list_and_body
+         {     int ind ;       
+
+               if ( (ind=FoundInAccTable(AccTable,TotalAccs,$1)) != -1 ) {
+               /* This is an Accumulator constructor */
+                       AccTable[ind]->initmsgtype = (char *)malloc((strlen(CurrentMsgParm)+1)*sizeof(char)) ;
+                       strcpy(AccTable[ind]->initmsgtype,CurrentMsgParm) ;
+                       AccTable[ind]->defined = FoundConstructorBody ;
+               }
+               else if ( (ind=FoundInAccTable(MonoTable,TotalMonos,$1)) != -1 ) {
+               /* This is a Monotonic constructor */
+                       MonoTable[ind]->initmsgtype = (char *)malloc((strlen(CurrentMsgParm)+1)*sizeof(char)) ;
+                       strcpy(MonoTable[ind]->initmsgtype,CurrentMsgParm) ;
+                       MonoTable[ind]->defined = FoundConstructorBody ;
+               }
+
+               foundargs = FALSE ;
+         }
+        ;
+
+
+    /* The following conflicts with member declarations-
+    constructor_parameter_list_and_body:
+          parameter_type_list ';'
+          | parameter_type_list constructor_init_list_opt compound_statement
+          ;
+    so parameter_type_list was expanded inline to get */
+
+    /* C++, not ANSI C */
+constructor_parameter_list_and_body:
+          '('                           ')' type_qualifier_list_opt ';'
+          { CheckConstructorEP($0,FALSE) ; 
+            FoundConstructorBody = FALSE ; }
+        | '(' type_name initializer     ')' type_qualifier_list_opt ';' 
+          { CheckConstructorEP($0,FALSE) ; 
+            FoundConstructorBody = FALSE ; }
+        | '(' named_parameter_type_list ')' type_qualifier_list_opt ';'
+          { foundargs = TRUE ; 
+            CheckConstructorEP($0,FALSE) ; 
+            FoundConstructorBody = FALSE ; }
+
+        | '('                           ')' type_qualifier_list_opt
+                constructor_init_list_opt 
+          {    CheckConstructorEP($0,TRUE) ; 
+          }
+          compound_statement
+          {    FoundConstructorBody = TRUE ; 
+          }
+        | '(' type_name initializer     ')' type_qualifier_list_opt
+                constructor_init_list_opt 
+          {    CheckConstructorEP($0,TRUE) ; 
+          }
+          compound_statement
+          {    FoundConstructorBody = TRUE ; 
+          }
+        | '(' named_parameter_type_list ')' type_qualifier_list_opt
+                constructor_init_list_opt 
+          {    foundargs = TRUE ; CheckConstructorEP($0,TRUE) ; 
+          }
+          compound_statement
+          {    FoundConstructorBody = TRUE ; 
+          }
+
+        | constructor_conflicting_parameter_list_and_body
+         {     EpMsg = CurrentTypedef ; 
+               CheckConstructorEP($0,FALSE) ;  }
+        ;
+
+
+    /* The following conflicted with member declaration-
+    constructor_conflicting_parameter_list_and_body:
+        '('   type_name ')'                 type_qualifier_list_opt ';'
+        | '(' type_name ')'                 type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+        ;
+    so type_name was inline expanded to get the following... */
+
+
+    /*  Note  that by inline expanding type_qualifier_opt in a few of 
+    the following rules I can transform 3  RR  conflicts  into  3  SR 
+    conflicts.  Since  all the conflicts have a look ahead of ';', it 
+    doesn't  really  matter  (also,  there  are  no   bad   LALR-only 
+    components in the conflicts) */
+
+constructor_conflicting_parameter_list_and_body:
+        '(' type_specifier                 ')' type_qualifier_list_opt
+                ';'
+        | '(' basic_type_name              ')' type_qualifier_list_opt
+                ';'
+
+        | '(' TYPEDEFname                  ')' type_qualifier_list_opt
+                ';'
+
+        | '(' global_or_scoped_typedefname ')' type_qualifier_list_opt
+                ';'
+
+        | '(' type_qualifier_list          ')' type_qualifier_list_opt
+                ';'
+
+
+        | '(' type_specifier               abstract_declarator ')' type_qualifier_list_opt
+                ';'
+        | '(' basic_type_name              abstract_declarator ')' type_qualifier_list_opt
+                ';'
+
+        /* missing entry posted below */
+
+        | '(' global_or_scoped_typedefname abstract_declarator ')' type_qualifier_list_opt
+                ';'
+        | '(' type_qualifier_list          abstract_declarator ')' type_qualifier_list_opt
+                ';'
+
+
+        | '(' type_specifier               ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+        | '(' basic_type_name              ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+        | '(' TYPEDEFname                  ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+        | '(' global_or_scoped_typedefname ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+        | '(' type_qualifier_list           ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+
+        | '(' type_specifier  abstract_declarator ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+        | '(' basic_type_name abstract_declarator ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+        /* missing entry posted below */
+
+        | '(' global_or_scoped_typedefname abstract_declarator ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+        | '(' type_qualifier_list          abstract_declarator ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+        | constructor_conflicting_typedef_declarator
+        ;
+
+
+    /* The following have ambiguities with member declarations-
+    constructor_conflicting_typedef_declarator:
+      '(' TYPEDEFname abstract_declarator ')' type_qualifier_list_opt
+                ';'
+      |  '(' TYPEDEFname abstract_declarator ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+      ;
+    which can be deferred by expanding abstract_declarator, and in two
+    cases parameter_qualifier_list, resulting in ...*/
+
+constructor_conflicting_typedef_declarator:
+        '(' TYPEDEFname unary_abstract_declarator          ')' type_qualifier_list_opt
+                ';'
+
+        | '(' TYPEDEFname unary_abstract_declarator       ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+        | '(' TYPEDEFname postfix_abstract_declarator     ')' type_qualifier_list_opt
+                ';'
+
+        | '(' TYPEDEFname postfix_abstract_declarator     ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+
+
+        | '(' TYPEDEFname postfixing_abstract_declarator  ')' type_qualifier_list_opt
+                ';'
+
+        | '(' TYPEDEFname postfixing_abstract_declarator  ')' type_qualifier_list_opt
+                constructor_init_list_opt compound_statement
+        ;
+
+
+constructor_init_list_opt:
+        /* nothing */
+        | constructor_init_list
+        ;
+
+constructor_init_list:
+        ':' constructor_init
+        | constructor_init_list ',' constructor_init
+        ;
+
+constructor_init:
+        IDENTIFIER   '(' argument_expression_list ')'
+        | IDENTIFIER '('                          ')'
+
+        | TYPEDEFname '(' argument_expression_list ')'
+        | TYPEDEFname '('                          ')'
+        | global_or_scoped_typedefname '(' argument_expression_list ')'
+        | global_or_scoped_typedefname '('                          ')'
+
+        | '(' argument_expression_list ')' /* Single inheritance ONLY*/
+        | '(' ')' /* Is this legal? It might be default! */
+        ;
+
+declarator:
+        identifier_declarator  { $$ = $1; }
+        | typedef_declarator   { $$ = $1; }
+        ;
+
+typedef_declarator:
+        paren_typedef_declarator          /* would be ambiguous as parameter*/
+        | simple_paren_typedef_declarator /* also ambiguous */
+        | parameter_typedef_declarator {$$=$1;} /* not ambiguous as parameter*/
+        ;
+
+parameter_typedef_declarator:
+        TYPEDEFname                                    { $$ = $1; }
+        | TYPEDEFname postfixing_abstract_declarator   { $$ = $1; }
+        | clean_typedef_declarator
+        ;
+
+
+    /*  The  following  have  at  least  one  '*'or '&'.  There is no 
+    (redundant) '(' between the '*'/'&'  and  the  TYPEDEFname.  This 
+    definition  is  critical  in  that  a redundant paren that it too 
+    close to the TYPEDEFname (i.e.,  nothing  between  them  at  all) 
+    would  make  the TYPEDEFname into a parameter list, rather than a 
+    declarator.*/
+
+clean_typedef_declarator:
+        clean_postfix_typedef_declarator
+        | asterisk_or_ampersand parameter_typedef_declarator
+        | unary_modifier        parameter_typedef_declarator
+        ;
+
+clean_postfix_typedef_declarator:
+        '('   clean_typedef_declarator ')'
+        | '(' clean_typedef_declarator ')' postfixing_abstract_declarator
+        ;
+
+
+    /* The following have a redundant '(' placed immediately  to  the 
+    left  of the TYPEDEFname.  This opens up the possibility that the 
+    TYPEDEFname is really the start of a parameter list, and *not*  a 
+    declarator*/
+
+paren_typedef_declarator:
+        postfix_paren_typedef_declarator
+        | asterisk_or_ampersand '(' simple_paren_typedef_declarator ')'
+        | unary_modifier        '(' simple_paren_typedef_declarator ')'
+        | asterisk_or_ampersand '(' TYPEDEFname ')' /* redundant paren */
+        | unary_modifier        '(' TYPEDEFname ')' /* redundant paren */
+        | asterisk_or_ampersand paren_typedef_declarator
+        | unary_modifier        paren_typedef_declarator
+        ;
+
+postfix_paren_typedef_declarator:
+        '(' paren_typedef_declarator ')'
+        | '(' simple_paren_typedef_declarator postfixing_abstract_declarator ')'
+        | '(' TYPEDEFname postfixing_abstract_declarator ')'              /* redundant paren */
+        | '(' paren_typedef_declarator ')' postfixing_abstract_declarator
+        ;
+
+
+    /*  The following excludes lone TYPEDEFname to help in a conflict 
+    resolution.  We have special cased lone  TYPEDEFname  along  side 
+    all uses of simple_paren_typedef_declarator */
+
+simple_paren_typedef_declarator:
+        '(' TYPEDEFname ')'
+        | '(' simple_paren_typedef_declarator ')'
+        ;
+
+identifier_declarator:
+        unary_identifier_declarator    { $$ = $1; }
+        | paren_identifier_declarator  { $$ = $1; FoundParms = FALSE ;}
+        ;
+
+
+    /*  The  following  allows  "function return array of" as well as 
+    "array of function returning".  It COULD be cleaned  up  the  way 
+    abstract  declarators  have been.  This change might make it hard 
+    to recover from user's syntax errors, whereas now they appear  as 
+    simple constraint errors. */
+
+unary_identifier_declarator:
+        postfix_identifier_declarator   { $$ = $1; }
+        | asterisk_or_ampersand identifier_declarator  
+         { if ( FoundHandle > 0 ) {
+               if ( CurrentCharmType == ACCUMULATOR )
+                       InsertHandleTable(AccHandleTable,&AccHandleTableSize,$2) ;
+               else if ( CurrentCharmType == MONOTONIC )
+                       InsertHandleTable(MonoHandleTable,&MonoHandleTableSize,$2) ;
+               else if ( CurrentCharmType == WRITEONCE )
+                       InsertHandleTable(WrOnHandleTable,&WrOnHandleTableSize,$2) ;
+               else if ( FoundHandle == GROUP )
+                       InsertHandleTable(BOCHandleTable,&BOCHandleTableSize,$2) ;
+               else if (CurrentCharmType==CHARE || CurrentCharmType==BRANCHED)
+                       InsertHandleTable(ChareHandleTable,&ChareHandleTableSize,$2);
+               else 
+                       fprintf(stderr,"ERROR : %s, line %d : %s is not a proper type for a handle.\n",CurrentFileName,CurrentLine,CurrentAsterisk) ;
+                       
+               FoundHandle = -1 ;
+           }
+           $$ = $2 ;
+         }
+          
+        | unary_modifier        identifier_declarator
+        ;
+
+postfix_identifier_declarator:
+        paren_identifier_declarator           postfixing_abstract_declarator 
+        { $$ = $1; }
+        | '(' unary_identifier_declarator ')'
+        | '(' unary_identifier_declarator ')' postfixing_abstract_declarator
+         { $$ = $2 ; }
+        ;
+
+old_function_declarator:
+        postfix_old_function_declarator
+        | asterisk_or_ampersand old_function_declarator
+        | unary_modifier      old_function_declarator
+        ;
+
+
+    /*  ANSI  C  section  3.7.1  states  "An identifier declared as a 
+    typedef name shall not be redeclared as a parameter".  Hence  the 
+    following is based only on IDENTIFIERs.
+
+    Instead  of identifier_lists, an argument_expression_list is used 
+    in  old  style  function   definitions.    The   ambiguity   with 
+    constructors   required   the  use  of  argument  lists,  with  a 
+    constraint verification of the list (e_g.: check to see that  the 
+    "expressions" consisted of lone identifiers).
+
+    An interesting ambiguity appeared:
+        const constant=5;
+        int foo(constant) ...
+
+    Is  this an old function definition or constructor?  The decision 
+    is made later by THIS grammar based on trailing context :-). This 
+    ambiguity is probably what caused many parsers to give up on  old 
+    style function definitions. */
+
+postfix_old_function_declarator:
+        paren_identifier_declarator '(' argument_expression_list ')'
+        | '(' old_function_declarator ')'
+        | '(' old_function_declarator ')' old_postfixing_abstract_declarator
+        ;
+
+old_postfixing_abstract_declarator:
+        array_abstract_declarator /* array modifiers */
+        | old_parameter_type_list  /* function returning modifiers */
+        ;
+
+abstract_declarator:
+        unary_abstract_declarator
+        | postfix_abstract_declarator
+        | postfixing_abstract_declarator
+        ;
+
+postfixing_abstract_declarator:
+        array_abstract_declarator
+        | parameter_type_list  { FoundParms = TRUE ; }
+        ;
+
+array_abstract_declarator:
+        '[' ']'
+        | '[' constant_expression ']'
+        | array_abstract_declarator '[' constant_expression ']'
+        ;
+
+unary_abstract_declarator:
+        asterisk_or_ampersand
+        | unary_modifier
+        | asterisk_or_ampersand abstract_declarator
+        | unary_modifier        abstract_declarator
+        ;
+
+postfix_abstract_declarator:
+        '(' unary_abstract_declarator ')'
+        | '(' postfix_abstract_declarator ')'
+        | '(' postfixing_abstract_declarator ')'
+        | '(' unary_abstract_declarator ')' postfixing_abstract_declarator
+        ;
+
+asterisk_or_ampersand:
+        '*'       { strcpy(CurrentAsterisk,"*") ; }
+        | '&'     { strcpy(CurrentAsterisk,"&") ; }
+       | HANDLE   {    /* CheckCharmName() ;   Done in t.l now */
+                       FoundHandle = HANDLE ;
+                       strcpy(CurrentAsterisk, CurrentTypedef) ;
+                  }    
+       | GROUP   {     /* CheckCharmName() ;   Done in t.l now */
+                       FoundHandle = GROUP ;
+                       strcpy(CurrentAsterisk, CurrentTypedef) ;
+                  }    
+        ;
+
+unary_modifier:
+        scope '*' type_qualifier_list_opt      { if ( AddedScope > 0 ) {
+                                                       AddedScope = 0 ;
+                                                       PopStack() ;
+                                                 }
+                                               }
+        | asterisk_or_ampersand type_qualifier_list
+        ;
+
+
+
+/************************* NESTED SCOPE SUPPORT ******************************/
+
+
+    /*  The  actions taken in the rules that follow involve notifying 
+    the lexer that it should use the scope specified to determine  if 
+    the  next  IDENTIFIER  token is really a TYPEDEFname token.  Note 
+    that the actions must be taken before the parse has a  chance  to 
+    "look-ahead" at the token that follows the "::", and hence should 
+    be  done  during  a  reduction to "scoping_name" (which is always 
+    followed by CLCL).  Since we are defining an  LR(1)  grammar,  we 
+    are  assured  that  an action specified *before* the :: will take 
+    place before the :: is shifted, and hence before the  token  that 
+    follows the CLCL is scanned/lexed. */
+
+    /*  Note that at the end of each of the following rules we should 
+    be sure that the tag name is  in,  or  placed  in  the  indicated 
+    scope.   If  no  scope  is  specified, then we must add it to our 
+    current scope IFF it cannot  be  found  in  an  external  lexical 
+    scope. */
+
+scoping_name:
+        tag_name       
+         {     $$ = $1 ; 
+               AddOneScope($1) ;
+         }
+        | aggregate_key tag_name 
+         {     $$ = $2 ; 
+               AddOneScope($2) ;
+         }
+/* also update symbol table here by notifying it about a (possibly) new tag*/
+        ;
+
+scope:
+        scoping_name CLCL      
+         {     $$ = (char *)malloc(sizeof(char)*(strlen($1)+3)) ;
+               strcpy($$,$1) ;
+               strcat($$,$2) ; 
+         }
+        | scope scoping_name  CLCL     
+         {     $$ = (char *)malloc(sizeof(char)*(strlen($1)+strlen($2)+3)) ;
+               strcpy($$,$1) ;
+               strcat($$,$2) ; 
+               strcat($$,$3) ; 
+         }
+        ;
+
+
+    /*  Don't try to simplify the count of non-terminals by using one 
+    of the other definitions of  "IDENTIFIER  or  TYPEDEFname"  (like 
+    "label").   If you reuse such a non-terminal, 2 RR conflicts will 
+    appear. The conflicts are LALR-only. The underlying cause of  the 
+    LALR-only   conflict   is  that  labels,  are  followed  by  ':'.  
+    Similarly, structure elaborations which provide a derivation have 
+    have ':' just  after  tag_name  This  reuse,  with  common  right 
+    context, is too much for an LALR parser. */
+
+tag_name:
+        IDENTIFIER     { $$ = $1 ; }
+        | TYPEDEFname  { $$ = $1 ; }
+        ;
+
+global_scope:
+        { /*scan for upcoming name in file scope */ FoundGlobalScope=1 ; } CLCL
+        ;
+
+global_or_scope:
+        global_scope
+        | scope                { if ( AddedScope > 0 ) { 
+                               PopStack() ;            
+                               AddedScope = 0 ;
+                         }
+                       }
+        | global_scope scope   { if ( AddedScope > 0 ) { 
+                                       PopStack() ;            
+                                       AddedScope = 0 ;
+                                 }
+                               }
+        ;
+
+
+    /*  The  following can be used in an identifier based declarator. 
+    (Declarators  that  redefine  an  existing  TYPEDEFname   require 
+    special  handling,  and are not included here).  In addition, the 
+    following are valid "identifiers" in  an  expression,  whereas  a 
+    TYPEDEFname is NOT.*/
+
+scope_opt_identifier:
+                IDENTIFIER                          
+         {     $$ = $1 ; 
+               CheckSharedHandle($1);
+         }
+        | scope IDENTIFIER  /* C++ not ANSI C */     
+         {     char *sptr, *sptr2, *lastcoln ;
+               int ch, bo ;    
+               EP *ep ;
+               char epstr[128] ;
+
+                if ( AddedScope > 0 ) { 
+                       PopStack() ;            
+                       AddedScope = 0 ;
+               }
+
+                /* Note : $$ must fit Chare::EP and _CK_ep_Chare_EP */
+                $$ = (char *)malloc(sizeof(char)*(strlen($1)+strlen($2)+10)) ;
+               strcpy($$,$1) ;
+               strcat($$,$2) ; 
+               FoundChareEPPair = 0 ;
+
+               CheckSharedHandle($2);
+               if ( SendType == -1 ) {
+                   lastcoln = Mystrstr($1,"::") ;
+                   *lastcoln = '\0' ;
+       
+                   ch = FoundInChareTable(ChareTable,charecount+1,$1) ;
+                   bo = FoundInChareTable(BOCTable,boccount+1,$1) ;
+                   if ( ch != -1 || bo != -1 )  {
+                       
+                       /* Now we have a Chare::EP pair */
+                       if ( ch != -1 )
+                               ep = SearchEPList(ChareTable[ch]->eps,$2) ;
+                       else if ( bo != -1 )
+                               ep = SearchEPList(BOCTable[bo]->eps,$2) ;
+                       if ( ep != NULL ) {
+                         sptr = Mystrstr(OutBuf,"&") ; 
+                         if ( sptr != NULL ) {
+                               *sptr = ' ' ; /* remove ampersand */
+                               sptr2 = Mystrstr(sptr,$1) ;
+                               if ( sptr2 != NULL ) 
+                                       *sptr2 = '\0' ;
+                               else 
+                                       fprintf(stderr,"TRANSLATOR ERROR in ChareType::EntryFn usage, %s, line %d\n",CurrentFileName,CurrentLine) ;
+
+                               /* dont flush because OutBuf may have stuff we
+                                  FLUSHBUF() ; want later */ 
+
+                               sprintf(epstr,"_CK_ep_%s_%s",$1,$2) ;
+                               strcat(OutBuf,epstr) ;
+
+                               FoundChareEPPair = 1 ;
+                               strcpy($$,epstr) ; 
+                               /* so that higher-level rules get _CK_ep_...
+                                  instead of &(Chare::EP) */
+                               
+                               strcpy(LastChare,$1) ;
+                               strcpy(LastEP,$2) ;
+                         }
+                       }
+                   }
+               }
+         }
+        ;
+
+scope_opt_complex_name:
+                complex_name   {       $$ = $1 ; }
+        | scope complex_name   {       if ( AddedScope > 0 ) { 
+                                               PopStack() ;            
+                                               AddedScope = 0 ;
+                                       }
+                               }
+        ;
+
+complex_name:
+        '~' TYPEDEFname
+        | operator_function_name { $$ = $1 ; }
+        ;
+
+
+    /*  Note that the derivations for global_opt_scope_opt_identifier 
+    and global_opt_scope_opt_complex_name must be  placed  after  the 
+    derivation:
+
+       paren_identifier_declarator : scope_opt_identifier
+
+    There  are several states with RR conflicts on "(", ")", and "[".  
+    In these states we give up and assume a declaration, which  means 
+    resolving   in  favor  of  paren_identifier_declarator.  This  is 
+    basically the "If it can be  a  declaration  rule...",  with  our 
+    finite cut off. */
+
+global_opt_scope_opt_identifier:
+        global_scope scope_opt_identifier { $$ = $2 ; }
+        |            scope_opt_identifier { $$ = $1 ; }
+        ;
+
+global_opt_scope_opt_complex_name:
+        global_scope scope_opt_complex_name
+        |            scope_opt_complex_name
+        ;
+
+
+    /*  Note  that we exclude a lone TYPEDEFname.  When all alone, it 
+    gets involved in a lot of ambiguities (re: function like cast  vs 
+    declaration),   and  hence  must  be  special  cased  in  several 
+    contexts. Note that generally every use of scoped_typedefname  is 
+    accompanied by a parallel production using lone TYPEDEFname */
+
+scoped_typedefname:
+        scope TYPEDEFname      
+       { $$ = (char *)malloc(sizeof(char)*(strlen($1)+strlen($2)+1)) ;
+         strcpy($$,$1) ;
+         strcat($$,$2) ; 
+         strcpy(CurrentTypedef,$$) ;
+          if ( AddedScope > 0 ) { 
+                 PopStack() ;          
+                 AddedScope = 0 ;
+         }
+       }
+        ;
+
+global_or_scoped_typedefname:
+                       scoped_typedefname      { $$ = $1 ; }
+        | global_scope scoped_typedefname      
+         {     $$ = $2 ; 
+               strcpy(CurrentTypedef,$1) ;
+               strcat(CurrentTypedef,$2) ;
+         }
+        | global_scope TYPEDEFname             
+         {     $$ = $2 ; 
+               strcpy(CurrentTypedef,$1) ;
+               strcat(CurrentTypedef,$2) ;
+         }
+        ;
+
+global_opt_scope_opt_typedefname:
+        TYPEDEFname                    { $$ = $1 ; }
+        | global_or_scoped_typedefname { $$ = $1 ; }
+        ;
+
+%%
+yyerror(string)
+char*string;
+{
+       fprintf(stderr,"ERROR : %s, line %d : %s near \"%s\".\n", CurrentFileName,CurrentLine,string,prevtoken);
+       ErrVal = TRUE ;
+}
+
+
+char *Concat2(s1,s2)
+char *s1, *s2 ;
+{
+       int len = strlen(s1) + strlen(s2) + 1 ;
+       char *s = (char *)malloc(sizeof(char)*len) ;
+       sprintf(s,"%s%s",s1,s2) ;
+/*     free(s1) ; free(s2) ;  */
+       
+       return(s) ;
+}
+
+char *Concat3(s1,s2,s3)
+char *s1, *s2, *s3 ;
+{
+       int len = strlen(s1) + strlen(s2) + strlen(s3) + 1 ;
+       char *s = (char *)malloc(sizeof(char)*len) ;
+       sprintf(s,"%s%s%s",s1,s2,s3) ;
+/*     free(s1) ; free(s2) ; free(s3)  */
+       
+       return(s) ;
+}
diff --git a/src/xlat-i/xi-parse.bison b/src/xlat-i/xi-parse.bison
new file mode 100644 (file)
index 0000000..67541be
--- /dev/null
@@ -0,0 +1,170 @@
+
+%{
+
+#include "xi-symbol.h"
+
+extern int lineno;
+extern int yylex (void) ;
+extern Module *thismodule ;
+
+// Local data and functions
+int yyerror(char *);
+
+%}
+
+/* Conventions:
+       Terminal symbols (tokens) are written in CAPITALS.
+*/
+
+%union {
+       char *strval;
+       int intval;
+}
+
+%token BOC
+%token CHARE
+%token ENTRY
+%token MESSAGE
+%token READONLY
+%token TABLE
+%token THREADED
+%token EXTERN
+%token <strval>        IDENTIFIER
+
+%type <strval> Id ChareName EntryName MessageName ReadOnlyName TableName
+%type <strval> SimpleType PtrType OptionalMessagePtr
+%type <intval> OptionalThreaded OptionalExtern
+
+%%
+
+File   :       ItemElist
+       ;
+
+ItemElist:     /* empty */
+       |       ItemList
+       ;
+
+ItemList:      Item
+       |       ItemList Item
+       ;
+
+Item   :       Boc | Chare | Message | ReadOnly | Table
+       ;
+
+OptionalExtern
+       :       /* empty */
+               { $$ = FALSE; }
+       |       EXTERN
+               { $$ = TRUE; }
+       ;
+
+Boc    :       OptionalExtern BOC ChareName '{'
+               {
+                       Chare *c = new Chare($3, BOC, $1) ;
+                       delete $3;
+                       thismodule->AddChare(c) ;
+               }
+               EntryList '}' ';'
+       ;
+
+Chare  :       OptionalExtern CHARE ChareName '{'
+               {
+                       Chare *c = new Chare($3, CHARE, $1) ;
+                       delete $3;
+                       thismodule->AddChare(c) ;
+               }
+               EntryList '}' ';'
+       ;
+
+ChareName:     Id
+       ;
+
+Id     :       IDENTIFIER
+       ;
+
+EntryList:     Entry
+       |       EntryList Entry
+       ;
+
+OptionalMessagePtr
+       :       /* empty */
+               {
+                       $$ = NULL;
+               }
+       |       MessageName '*'
+       ;
+
+OptionalThreaded
+       :       /* empty */
+               { $$ = FALSE; }
+       |       THREADED
+               { $$ = TRUE; }
+       ;
+
+Entry  :       OptionalThreaded OptionalMessagePtr ENTRY EntryName '(' OptionalMessagePtr ')' ';'
+               {
+                       thismodule->chares->AddEntry($4, $6, $1, $2) ;
+                       delete $4; delete $6;
+               }
+       ;
+
+EntryName:     Id
+       ;
+
+Message        :       OptionalExtern MESSAGE MessageName ';'
+               {
+                       Message *m = new Message($3, 0, $1) ;
+                       delete $3;
+                       thismodule->AddMessage(m) ;
+               }
+       ;
+
+MessageName:   Id
+       ;
+
+ReadOnly:      READONLY SimpleType ReadOnlyName ';'
+               {
+                       ReadOnly *r = new ReadOnly($3, $2, 0) ;
+                       delete $2;
+                       thismodule->AddReadOnly(r) ;
+               }
+       |       READONLY PtrType ReadOnlyName ';'
+               {
+                       ReadOnly *r = new ReadOnly($3, $2, 1) ;
+                       delete $2;
+                       thismodule->AddReadOnly(r) ;
+               }
+       ;
+
+SimpleType:    Id
+       ;
+
+PtrType        :       Id '*'
+               {
+                       $$ = strcat(strcpy(new char[2+strlen($1)], $1), "*");
+                       delete $1;
+               }
+       ;
+
+ReadOnlyName:  Id
+       ;
+
+Table  :       TABLE TableName ';'
+               {
+                       Table *t = new Table($2) ;
+                       delete $2;
+                       thismodule->AddTable(t) ;
+               }
+       ;
+
+TableName:     Id
+       ;
+
+%%
+
+int yyerror(char *mesg)
+{
+       cout << "Syntax error at line " << lineno << ": " << mesg << endl;
+       return 0;
+}
+
diff --git a/src/xlat-i/xi-scan.flex b/src/xlat-i/xi-scan.flex
new file mode 100644 (file)
index 0000000..57baee1
--- /dev/null
@@ -0,0 +1,118 @@
+
+%{
+
+#include "xi-symbol.h"
+#include "xi-parse.tab.h"
+#include <ctype.h>
+
+/* Global Variables and Functions - used in parse.y */
+unsigned int lineno = 1;
+// int yylex()
+
+/* Local to file */
+static unsigned char in_comment=FALSE;
+int binsearch(char *s, int lb, int ub);
+static int check_name(char *);
+
+/* We return Tokens only when not in a comment. */
+#define Return if (!in_comment) return
+#define        Token(x) x
+
+#ifdef yywrap
+#undef yywrap
+#endif
+%}
+
+ws     [ \t]+
+nl     [\n]
+alpha  [A-Za-z]
+digit  [0-9]
+
+name   ({alpha})({alpha}|{digit}|[_])*
+
+string1        \'[^\n']*\'
+string2        \'[^\n']*(\'\'[^\n']*)+\'
+string3        \"[^\n"]*\"
+string {string1}|{string2}
+
+int    [-+]?{digit}+
+
+expo   ([eE][-+]?{digit}+)?
+real1  {int}\.?{expo}
+real2  [-+]?{digit}*\.{digit}+{expo}
+real   {real1}|{real2}
+
+bool   TRUE|FALSE
+
+%%
+"//".*         { /* ignore single line comments */ }
+"/*"           { in_comment = TRUE; /* Single line C-style comments */ }
+"*/"           { in_comment = FALSE; }
+{ws}           { /* ignore white space */ }
+{nl}           { lineno++; /* Return Token(NL); */ }
+{name}         { Return Token(check_name(yytext)); }
+.              { Return Token(yytext[0]); }
+%%
+
+/* {nl}/{nl}   { lineno++; } */
+struct rwtable {
+       char *s;        int tok;
+};
+
+/* Reserved word table */
+struct rwtable rwtable[] = {
+       "",             9,
+/* MUST BE IN SORTED ORDER */
+       "boc",          BOC,
+       "chare",        CHARE,
+       "entry",        ENTRY,
+       "extern",       EXTERN,
+       "group",        BOC,
+       "message",      MESSAGE,
+       "readonly",     READONLY,
+       "table",        TABLE,
+       "threaded",     THREADED,
+/* MAKE SURE TO UPDATE THE NUMBER OF ENTRIES ABOVE */
+       "",             0,
+};
+
+int binsearch(char *s, int lb, int ub)
+{
+       int mid = (lb+ub)/2;
+       int result = 0;
+
+       if (lb>ub) return 0;    /* not found */
+       else if ((result = strcmp(s, rwtable[mid].s))==0)
+               return mid; /* found */
+       else if (result<0) return binsearch(s, lb, mid-1);      /* lower half */
+       else return binsearch(s, mid+1, ub);    /* upper half */
+}
+
+/* Distinguish between reserved words and identifiers. */
+static int check_name(char *ss)
+{
+       int i;
+       char *s = new char[1+strlen(ss)];
+
+       /* for case insensitivity, we convert to lower case */
+       for(i=0; i<= strlen(ss); i++) s[i] = tolower(ss[i]);
+
+       /* Is "s" a reserved word ? */
+       if ( (i=binsearch(s, 1, rwtable[0].tok)) )
+               {       delete s;
+                       return rwtable[i].tok;
+               }
+
+       /* ... otherwise it must be an identifier. */
+       yylval.strval = strcpy(new char[yyleng+1], yytext);
+/*
+       yylval = createASTnode( AIDENTIFIER, lookup(s),
+                       NULL, NULL, NULL, NULL);
+*/
+
+       delete s;
+
+       return IDENTIFIER;
+}
+
+int yywrap() { return 1; }
diff --git a/src/xlat/xl-lexsp.flex b/src/xlat/xl-lexsp.flex
new file mode 100755 (executable)
index 0000000..e356fb2
--- /dev/null
@@ -0,0 +1,229 @@
+%{
+#define YYSTYPE YSNPTR
+#include "xl-lex.h"
+#include "xl-yacc.tab.h"
+#include "xl-sym.h"
+#include <string.h>
+
+extern YSNPTR yylval;
+extern int MsgToStructFlag;
+int CurrentInputLineNo=1;
+int SavedLineNo;
+int CurrentOutputLineNo=0;
+char CurrentFileName[2*FILENAMELENGTH];
+char SavedFileName[2*FILENAMELENGTH];
+int OutputLineLength=0;
+extern FILE *outfile;
+
+extern SYMTABPTR GlobalModuleSearch();
+extern char token[];
+int PrevToken=0;
+
+#define CREATE 1
+#define NOCREATE 0
+
+#ifdef yywrap
+#undef yywrap
+#endif
+%}
+
+
+%e 1500
+%p 3900
+
+EXP    ([eE][+-]?[0-9]+)
+FS     [flFL]
+IS     ([uU][lL]?|[lL][uU]?)
+ASTRNG ([^"\\\n]|\\(['"?\\abfnrtv\n]|[0-7]{1,3}|[xX][0-9a-fA-F]{1,3}))*
+WhiteSpace     [ \t]*
+ID     [_a-zA-Z][_a-zA-Z0-9]*
+WS     [ \t\n]*
+
+%%
+"@"            { strcpy(token,yytext);return(PrevToken=AT); }
+"?"            { mywriteoutput("?",NOCREATE);strcpy(token,yytext);return(PrevToken=QUESTION); }
+":"            { strcpy(token,yytext);return(PrevToken=COLON); }
+"|"            { mywriteoutput("|",NOCREATE);strcpy(token,yytext);return(PrevToken=OR); }
+"&"            { mywriteoutput("&",NOCREATE);strcpy(token,yytext);return(PrevToken=AND); }
+"^"            { mywriteoutput("^",NOCREATE);strcpy(token,yytext);return(PrevToken=HAT); }
+"+"            { mywriteoutput("+",NOCREATE);strcpy(token,yytext);return(PrevToken=PLUS); }
+"-"            { mywriteoutput("-",NOCREATE);strcpy(token,yytext);return(PrevToken=MINUS); }
+"*"            { mywriteoutput("*",NOCREATE);strcpy(token,yytext);return(PrevToken=MULT); }
+"/"            { mywriteoutput("/",NOCREATE);strcpy(token,yytext);return(PrevToken=DIV); }
+"%"            { mywriteoutput("%",NOCREATE);strcpy(token,yytext);return(PrevToken=MOD); }
+"("            { mywriteoutput("(",NOCREATE);strcpy(token,yytext);return(PrevToken=L_PAREN); }
+")"            { mywriteoutput(")",NOCREATE);strcpy(token,yytext);return(PrevToken=R_PAREN); }
+"["            { mywriteoutput("[",NOCREATE);strcpy(token,yytext);return(PrevToken=L_SQUARE); }
+"]"            { mywriteoutput("]",NOCREATE);strcpy(token,yytext);return(PrevToken=R_SQUARE); }
+"."            { mywriteoutput(".",NOCREATE);strcpy(token,yytext);return(PrevToken=DOT); }
+"!"            { mywriteoutput("!",NOCREATE);strcpy(token,yytext);return(PrevToken=EXCLAIM); }
+"~"            { mywriteoutput("~",NOCREATE);strcpy(token,yytext);return(PrevToken=TILDE); }
+"->"           { mywriteoutput("->",NOCREATE);strcpy(token,yytext);return(PrevToken=POINTERREF); }
+"++"           { mywriteoutput("++",CREATE);strcpy(token,yytext);return(PrevToken=INCDEC); }
+"--"           { mywriteoutput("--",CREATE);strcpy(token,yytext);return(PrevToken=INCDEC); }
+"<<"           { mywriteoutput("<<",CREATE);strcpy(token,yytext);return(PrevToken=SHIFT); }
+">>"           { mywriteoutput(">>",CREATE);strcpy(token,yytext);return(PrevToken=SHIFT); }
+"<"            { mywriteoutput("<",CREATE);strcpy(token,yytext);return(PrevToken=COMPARE); }
+">"            { mywriteoutput(">",CREATE);strcpy(token,yytext);return(PrevToken=COMPARE); }
+"<="           { mywriteoutput("<=",CREATE);strcpy(token,yytext);return(PrevToken=COMPARE); }
+">="           { mywriteoutput(">=",CREATE);strcpy(token,yytext);return(PrevToken=COMPARE); }
+"=="           { mywriteoutput("==",NOCREATE);strcpy(token,yytext);return(PrevToken=EQUALEQUAL); }
+"!="           { mywriteoutput("!=",NOCREATE);strcpy(token,yytext);return(PrevToken=NOTEQUAL); }
+"&&"           { mywriteoutput("&&",NOCREATE);strcpy(token,yytext);return(PrevToken=ANDAND); }
+"||"           { mywriteoutput("||",NOCREATE);strcpy(token,yytext);return(PrevToken=OROR); }
+"="            { mywriteoutput("=",NOCREATE);strcpy(token,yytext);return(PrevToken=EQUAL); }
+"+="           { mywriteoutput("+=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+"-="           { mywriteoutput("-=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+"*="           { mywriteoutput("*=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+"/="           { mywriteoutput("/=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+"%="           { mywriteoutput("%=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+">>="          { mywriteoutput(">>=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+"<<="          { mywriteoutput("<<=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+"&="           { mywriteoutput("&=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+"|="           { mywriteoutput("|=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+"^="           { mywriteoutput("^=",CREATE);strcpy(token,yytext);return(PrevToken=ASGNOP); }
+","            { mywriteoutput(",",NOCREATE);strcpy(token,yytext);return(PrevToken=COMMA); }
+"{"            { strcpy(token,yytext);return(PrevToken=L_BRACE); }
+"}"            { strcpy(token,yytext);return(PrevToken=R_BRACE); }
+";"            { mywriteoutput(";",NOCREATE);strcpy(token,yytext);return(PrevToken=SEMICOLON); }
+","[ \t\n]*"{" { int i,count=0;
+               
+                 strcpy(token,yytext);
+                 for (i=0;i<yyleng;i++)
+                       if (yytext[i]=='\n') count++;
+                 CurrentInputLineNo += count;
+                 mywriteoutput(",{ ",NOCREATE);return(PrevToken=COMMA_L_BRACE); 
+               }
+","[ \t\n]*"}" { int i,count=0;
+               
+                 for (i=0;i<yyleng;i++)
+                       if (yytext[i]=='\n') count++;
+                 CurrentInputLineNo += count;
+                 mywriteoutput(",} ",NOCREATE);return(PrevToken=COMMA_R_BRACE); }
+
+"#"{WhiteSpace}("line")?{WhiteSpace}[0-9]+{WhiteSpace}\"{ASTRNG}\" { int i=0,j=0;
+                                                 char temp[FILENAMELENGTH];
+
+                                                 while ((yytext[i]<'0')||
+                                                        (yytext[i]>'9')) 
+                                                       i++;
+                                                 while ((yytext[i]>='0') &&
+                                                        (yytext[i]<='9'))
+                                                       temp[j++]=yytext[i++];
+                                                 temp[j]='\0';
+                                                 CurrentInputLineNo = 
+                                                       atoi(temp);
+                                                 while (yytext[i]!='\"')
+                                                       i++;
+                                                 yytext[yyleng-1]='\0';
+                                                 strcpy(CurrentFileName,
+                                                               yytext+i+1);
+                                               }
+
+{ID}                      { int retvalue;
+               
+                             strcpy(token,yytext);
+                             yylval=GetYSN();
+                             yylval->string=MakeString(yytext);
+                             if ((retvalue=SearchKey(yytext)) == -1)
+                                 return(PrevToken=TypeToToken(IDType(yytext)));
+                             else { if (IsKey(yytext))
+                                       writeoutput(yytext,NOFREE);
+                                    if (retvalue==0) return(IDENTIFIER);
+                                    if (MsgToStructFlag && (retvalue==MESSAGE))
+                                       { retvalue=STRUCT;
+                                         writeoutput("struct ",NOFREE);
+                                       }
+                                    if (retvalue==MAIN)
+                                       if (PrevToken!=CHARE)
+                                               return(PrevToken=IDENTIFIER);
+                                    return(PrevToken=retvalue);
+                                  }
+                           }
+
+{ID}{WS}"::"{WS}{ID}   { SYMTABPTR worksymtab;
+                         char *modname,*name,*string;
+                         int i;char ch;
+
+                         strcpy(token,yytext);
+                         yylval=GetYSN();
+                         i=0;ch=yytext[0];
+                         string=GetMem(strlen(yytext));
+                         while ((ch!=' ')&&(ch!='\t')&&(ch!='\n')&&(ch!=':'))
+                               { string[i]=ch;ch=yytext[++i]; }
+                         string[i]='\0';
+                         modname=yylval->modstring=MakeString(string);
+                         while ((ch==' ')||(ch=='\t')||(ch=='\n')||(ch==':'))
+                               { if (ch=='\n') CurrentInputLineNo++;
+                                 ch=yytext[++i]; 
+                               }
+                         name=yylval->string=MakeString(yytext+i);
+
+                         worksymtab=GlobalModuleSearch(name,modname);
+                         if (worksymtab==NULL)
+                               { error("Bad Module Reference",EXIT);
+                                 return(ID_DCOLON_ID);
+                               }
+                         switch (TypeToToken(worksymtab->idtype))
+                         { case IDENTIFIER : return(ID_DCOLON_ID);
+                           case TYPE_IDENTIFIER : return(TYPE_IDENTIFIER);
+                         }
+                       }
+
+[0-9]+"."[0-9]*{EXP}?{FS}?   |
+"."[0-9]+{EXP}?{FS}?                 |
+[0-9]+{EXP}{FS}?                     |
+[1-9][0-9]*{IS}?                     |
+0[0-7]*{IS}?                         |
+0[xX][0-9a-fA-F]+{IS}?          { mywriteoutput(yytext,CREATE);
+                                 strcpy(token,yytext);return(PrevToken=NUMBER);                
+                               }
+
+\'([^'\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|[xX][0-9a-fA-F]{1,3}))+\'   {
+                               mywriteoutput(yytext,CREATE);
+                                 strcpy(token,yytext);return(PrevToken=CHAR_CONST);              }
+
+\"{ASTRNG}\"                   { mywriteoutput(yytext,CREATE);
+                                  strcpy(token,yytext);return(PrevToken=STRING);
+                                }
+
+[ \t\f]+      { writeoutput(yytext,NOFREE); }        /* Skip whitespace...*/
+[\n]          { CurrentInputLineNo++; WriteReturn(); 
+               /*printf("%d Line\n",yylineno);*/
+               }
+
+"#"{WhiteSpace}("pragma"){WhiteSpace}[^\n]*    {writeoutput(yytext,NOFREE);
+                                       CurrentInputLineNo++;
+                                       WriteReturn();}
+
+"#"{WhiteSpace}("ident"){WhiteSpace}[^\n]*     {writeoutput(yytext,NOFREE);
+                                       CurrentInputLineNo++;
+                                       WriteReturn();}
+
+.              { error("Lexical Oddity",EXIT); }
+
+%%
+
+yywrap(){ PrevToken=0; return(1); }
+
+mywriteoutput(string,flag)
+char *string;
+int flag;
+{ if (!flag) return;
+  yylval=GetYSN();
+  yylval->string=MakeString(string);
+}
+
+TypeToToken(type)
+int type;
+{ switch (type)
+  { case TYPENAME :
+    case MESSAGENAME : return(TYPE_IDENTIFIER);
+    case MODULENAME :
+    case CHARENAME  :
+    case BOCNAME    :
+    case ENTRYNAME  :
+    default    : return(IDENTIFIER);
+  }
+}
diff --git a/src/xlat/xl-sfspec.flex b/src/xlat/xl-sfspec.flex
new file mode 100755 (executable)
index 0000000..94f5f37
--- /dev/null
@@ -0,0 +1,114 @@
+%{
+#include <string.h>
+int currentline=1;
+
+#ifdef yywrap
+#undef yywrap
+#endif
+%}
+
+WS [ \t\n]*
+WSN [ \t]*
+
+%%
+CreateChare{WS}"("     { CheckReturns(yytext);fprintf(yyout,"CreateChare("); }
+CreateBoc{WS}"("       { CheckReturns(yytext);fprintf(yyout,"CreateBoc("); }
+MyBocNum{WS}"("                { CheckReturns(yytext);fprintf(yyout,"MyBocNum("); }
+MyBranchID{WS}"("      { CheckReturns(yytext);fprintf(yyout,"MyBranchID("); }
+SendMsgBranch{WS}"("   { CheckReturns(yytext);fprintf(yyout,"SendMsgBranch("); }
+ImmSendMsgBranch{WS}"("        { CheckReturns(yytext);fprintf(yyout,"ImmSendMsgBranch("); }
+BroadcastMsgBranch{WS}"("  { CheckReturns(yytext);fprintf(yyout,"BroadcastMsgBranch("); }
+"#"{WSN}[line]?{WSN}[0-9]+ { currentline=GetLine(yytext);fprintf(yyout,"%s",yytext); }
+"#"{WSN}[line]?{WSN}[0-9]+{WSN}\"[^\n]*\"{WSN}[0-9]+ { currentline = GetLine(yytext);
+                          output_proper_line(yytext);}
+.                      { CountReturns(yytext); fprintf(yyout,"%s",yytext); }
+%%
+
+yywrap(){ return(1); }
+
+main() { writem4(); writeundef(); yylex(); }
+
+GetLine(string)
+char string[];
+{ int i=0,j;
+  char dummy[10];
+
+  while ((string[i]<'0')||(string[i]>'9')) i++;
+  j=0;
+  while ((string[i]>='0')&&(string[i]<='9')) dummy[j++] = string[i++];
+  dummy[j]='\0';
+  return(atoi(dummy));
+}
+
+output_proper_line(string)
+char string[];
+{
+   int length;
+
+   length=strlen(string)-1;
+   while (string[length-1]!='"') length--;
+   string[length]='\0';
+   fprintf(yyout,"%s",string);
+}
+
+CountReturns(string)
+char *string;
+{
+  while (*string) {
+    if (*string=='\n') currentline++;
+    string++;
+  }
+}
+
+CheckReturns(string)
+char *string;
+{
+  int anyret=0;
+  while (*string) {
+    if (*string=='\n') { currentline++; anyret=1; }
+    string++;
+  }
+  if (anyret)
+    fprintf(yyout,"# line %d\n",currentline);
+}
+
+
+char *createchare="define(CreateChare,`_CK_CreateChare($1,$2,$3,ifelse($4,,NULL_VID,$4),ifelse($5,,NULL_PE,$5))')";
+
+char *createboc="define(CreateBoc,`_CK_CreateBoc($1,$2,$3,ifelse($4,,-1`,'NULL,$4`,'$5))')";
+
+char *mybocnum="define(MyBocNum,`_CK_MyBocNum(_CK_4mydata)')";
+char *mybranchid="define(MyBranchID,`_CK_MyBranchID($1,_CK_4mydata)')";
+char *sendmsgbranch="define(SendMsgBranch,`_CK_SendMsgBranch($1,$2,ifelse($4,,_CK_MyBocNum(_CK_4mydata),$4),$3)')";
+char *immsendmsgbranch="define(ImmSendMsgBranch,`_CK_ImmSendMsgBranch($1,$2,ifelse($4,,_CK_MyBocNum(_CK_4mydata),$4),$3)')";
+char *broadcastmsgbranch="define(BroadcastMsgBranch,`_CK_BroadcastMsgBranch($1,$2,ifelse($3,,_CK_MyBocNum(_CK_4mydata),$3))')";
+char *createacc="define(CreateAcc,`_CK_CreateAcc($1,$2,ifelse($3,,-1`,'NULL,$3`,'$4))')";
+char *createmono="define(CreateMono,`_CK_CreateMono($1,$2,ifelse($3,,-1`,'NULL,$3`,'$4))')";
+
+writem4()
+{ printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",createchare,createboc,mybocnum,mybranchid,
+               sendmsgbranch,immsendmsgbranch,broadcastmsgbranch,createacc,createmono);
+}
+
+writeundef()
+{ printf("undefine(`changequote')\n");
+  printf("undefine(`divert')\n");
+  printf("undefine(`divnum')\n");
+  printf("undefine(`dnl')\n");
+  printf("undefine(`dumpdef')\n");
+  printf("undefine(`errprint')\n");
+  printf("undefine(`eval')\n");
+  printf("undefine(`ifdef')\n");
+  printf("undefine(`include')\n");
+  printf("undefine(`incr')\n");
+  printf("undefine(`index')\n");
+  printf("undefine(`len')\n");
+  printf("undefine(`maketemp')\n");
+  printf("undefine(`sinclude')\n");
+  printf("undefine(`substr')\n");
+  printf("undefine(`syscmd')\n");
+  printf("undefine(`translit')\n");
+  printf("undefine(`undivert')\n");
+  printf("undefine(`define')\n");
+  printf("undefine(`undefine')\n");
+}
diff --git a/src/xlat/xl-yacc.bison b/src/xlat/xl-yacc.bison
new file mode 100755 (executable)
index 0000000..385abc8
--- /dev/null
@@ -0,0 +1,3033 @@
+%{
+#include "xl-lex.h"
+#include "xl-sym.h"
+
+extern int CurrentInputLineNo,SavedLineNo;
+extern char CurrentFileName[],SavedFileName[];
+extern char ModuleName[];
+
+#define USERDEFINED 1
+#define SYSTEMDEFINED 2
+
+#define YYSTYPE YSNPTR
+#define YYMAXDEPTH 300
+
+#define dump(string)   writeoutput(string,NOFREE)
+
+extern char *AppendMap(),*AppendMapIndex();  
+char token[256];
+
+BUFFERTYPE buffer;
+
+extern void RestoreCurrentTable();
+extern void SetIdList();
+extern void GenerateStruct();          /* outh.c */
+extern void InsertSysCalls();          /* readtokens.c */
+extern TYPEPTR ProcessTypeIdentifier();
+
+char *dummy_ptr=NULL;
+SYMTABPTR worksymtab,SavedFnNode;
+SYMTABPTR ImportModule=NULL;
+SYMTABPTR ModuleDefined=NULL;
+SYMTABPTR Pass1Module=NULL;
+SYMTABPTR sym1,sym2;
+TYPEPTR SavedTypeNode;
+char *SavedName,*itoa(),*Map(),*AccMonoName,*AccMonoTypeName;
+char *ForwardedMsgName;
+int SaveMsgCount;
+
+SYMTABPTR GlobalModuleSearch(),GlobalEntryFind(),ProcessIdDcolonId();
+void SwapFile();
+
+char *CkMyData="_CK_4mydata->";
+char *CkLocalPtr="_CK_4localptr";
+char *CkDummyPtr="_CK_4dummyptr";
+char *CkMsgQualifier="MSG";
+char *DataSuffix="_Data";
+char *AssignMyDataPtr=" *_CK_4mydata = (";
+char *AssignMyID="\nChareIDType ThisChareID=((CHARE_BLOCK *)_CK_4mydata)[-1].selfID;";
+char *AssignMyBOC="\nint ThisBOC=((CHARE_BLOCK *)_CK_4mydata)[-1].x.boc_num;";
+char *DummyField="  char _CK;";
+extern char *REFSUFFIX;                /* outh.c */
+extern char *CkGenericAlloc,*CkVarSizeAlloc;
+
+
+int INSIDE_PRIVFUNC_PROTO=0; /* Jun 14, 1995, added by Attila */
+int PRIVATEFLAG=0;
+int StoredEPFlag;
+int IMPORTFLAG=0;
+int IMPORTMSGFLAG=0; /* Dec 30, 1991 Added by Attila */
+int SELFIMPMODULE=0; /* Jan 2, 1992  Added by Attila */
+int MULTI_STMT_TR=0; /* Feb 18, 1992  Added by Attila */
+int export_to_c_flag=0; /* March, 1994  Added by Attila */
+int ImportStruct=0;
+int ImportLevel=0;
+int OUTPUTOFF=0;
+int FUNCTIONCOUNT=0;
+int FNNAMETOREFFLAG=0;
+int FNREFTONAMEFLAG=0; /* Jan 16, 1992 Added by Attila */
+int READMSGINITFLAG=0;
+int BUFFEROUTPUT=0;
+int FORWARDEDMESSAGE=0;
+int MsgCount=10;       /* ARBITRARY - Set to > 1 */
+int MsgToStructFlag=0;
+FILE *outfile;
+
+TYPEPTR SetType(typeptr)
+TYPEPTR typeptr;
+{ (typeptr->count)++;
+  return(typeptr);
+}
+
+void RecursiveFree(typeptr)
+TYPEPTR typeptr;
+{ if (typeptr->type != NULL) RecursiveFree(typeptr->type);
+  if (typeptr->table != NULL) FreeTree(typeptr->table); 
+  dontfree(typeptr);
+}
+
+void FreeType(typeptr)
+TYPEPTR typeptr;
+{ if (typeptr==NULL) return;
+  if (--(typeptr->count) <= 0) RecursiveFree(typeptr); }
+
+%}
+%token CHARE
+%token MAIN
+%token MESSAGE
+%token ENTRY
+%token PRIVATE
+%token DATAINIT
+%token CHAREINIT
+%token QUIESCENCE
+%token MODULE
+%token BRANCHOFFICE
+%token READONLY
+%token MONOTONIC
+%token TABLE
+%token ACCUMULATOR
+%token STATIC
+%token PACK
+%token UNPACK
+%token VARSIZE
+%token FUNCTION
+%token BRANCH
+%token SIZEOF
+%token AUTO
+%token BREAK
+%token CASE
+%token CHAR
+%token CONST
+%token CONTINUE
+%token DEFAULT
+%token DO
+%token DOUBLE
+%token ELSE
+%token ENUM
+%token EXTERN
+%token FLOAT
+%token FOR
+%token GOTO
+%token IF
+%token INT
+%token LONG
+%token REGISTER
+%token RETURN
+%token SHORT
+%token SIGNED
+%token STRUCT
+%token SWITCH
+%token TYPEDEF
+%token UNION
+%token UNSIGNED
+%token VOID
+%token WHILE
+%token INTERFACE
+%token ChareIDType 
+%token EntryPointType 
+%token PeNumType     
+%token PackIDType   
+%token WriteOnceID
+%token PVECTOR  
+%token ChareNumType
+%token EntryNumType
+%token BOOLEAN
+
+%token R_PAREN
+%token R_SQUARE
+%token L_BRACE
+%token R_BRACE
+%token SEMICOLON
+%token IDENTIFIER
+%token TYPE_IDENTIFIER
+%token EPIDENTIFIER
+%token MCIDENTIFIER
+%token STRING
+%token NUMBER
+%token CHAR_CONST
+%token COMMA_R_BRACE
+%token COMMA_L_BRACE
+%token AT
+
+%left COMMA
+%right ASGNOP EQUAL
+%left QUESTION COLON
+%left OROR
+%left ANDAND
+%left OR
+%left HAT
+%left AND
+%left EQUALEQUAL NOTEQUAL
+%left COMPARE
+%left SHIFT
+%left PLUS MINUS
+%left MULT DIV MOD
+%left UNARY INCDEC TILDE EXCLAIM
+%left L_PAREN L_SQUARE DOT POINTERREF
+
+%token PRIVATECALL
+%token BRANCHCALL
+%token ID_DCOLON_ID
+%token PUBLIC
+%token FNNAMETOREF
+%token CKALLOCMSG
+%token CKALLOCPRIOMSG
+%token READMSGINIT
+%token ACCUMULATE
+%token NEWVALUE
+%token ACCIDTYPE
+%token MONOIDTYPE
+%token DUMMYMSG
+%token FunctionRefType
+%token FUNCTION_PTR
+%token FNREFTONAME
+%token IMPLICIT
+%token BLOCKEDRECV
+%token DAG
+%token MATCH
+%token AUTOFREE
+%token WHEN
+%token CHARECALL
+%token ChareNameType
+%token EXPORT_TO_C
+%start program
+
+%%
+program                : file_text
+                       { if (yylex()) 
+                            warning("Ignoring Extraneous Characters at End"); 
+                         return(0); 
+                       }
+               ;
+
+file_text      : module_text
+                       { CurrentTable=StackBase->tableptr;
+                         if (InPass1)
+                               {Pass1Module=GetSymTabNode(CurrentModule->name);
+                                Pass1Module->type=CurrentModule->type;
+                               } 
+                       }
+               | import_text module_text
+                       { CurrentTable=StackBase->tableptr;
+                         if (InPass1)
+                               {Pass1Module=GetSymTabNode(CurrentModule->name);
+                                Pass1Module->type=CurrentModule->type;
+                               } 
+                       }
+               ;
+
+import_text    : import_decl   
+                       { CurrentTable=StackBase->tableptr;
+                         CurrentModule=NULL;
+                       }
+               | import_text import_decl
+                       { CurrentTable=StackBase->tableptr;
+                         CurrentModule=NULL;
+                       }
+               ;
+
+import_decl    : INTERFACE     { IMPORTFLAG=TRUE; ImportLevel=0;}
+                 MODULE IDENTIFIER 
+                       { CurrentModule=Insert($4->string,StackBase->tableptr); 
+                         FillSymTabNode(CurrentModule,MODULENAME,IMPORTED,
+                               UNDEFINED,UNDEFINED,1,TRUE,NULL);
+                         CurrentTable=CurrentModule->type->table;
+/* Adding On Oct. 27, 1991.*/
+                         SwapFile(OUT1);
+                         if (strcmp($4->string,ModuleName)) {
+                                SELFIMPMODULE = 0;
+                               writeoutput("\nextern struct { ",NOFREE);
+                              } 
+                         else{
+                                SELFIMPMODULE = 1;
+                                writeoutput("\nstruct { ",NOFREE);
+                          }
+                         SwapFile(NULL);
+                         DestroyString($4->string);dontfree($4);
+                       }
+                 L_BRACE import_constructs R_BRACE
+                       { SwapFile(OUT1);writeoutput("} ",NOFREE);
+                         writeoutput(CkPrefix,NOFREE);
+                         writeoutput(CurrentModule->name,NOFREE);
+                         writeoutput(" ;",NOFREE);WriteReturn();
+                         SwapFile(NULL);
+                         IMPORTFLAG=FALSE;
+                       }
+               ;
+import_constructs : imp_construct
+               | import_constructs imp_construct
+               ;
+
+ITypeDef       : TYPEDEF { SwapFile(OUT0);writeoutput("typedef ",NOFREE); }
+               ;
+
+imp_construct  : ITypeDef
+                 type_spec init_decl_list semicolon
+                         { SetIdList($2->type,$3->listptr,TYPENAME,0);
+                           dontfree($2);dontfree($3);
+                           WriteReturn();      
+                           SwapFile(NULL);
+                         }
+               | ITypeDef
+                 init_decl_list semicolon
+                         { SetIdList(DUMMYPTR,$2->listptr,TYPENAME,0);
+                           dontfree($2);
+                           WriteReturn();      
+                           SwapFile(NULL);
+                         }
+               | imp_fn_decl 
+                       { SwapFile(NULL); }
+               | imp_message_defn
+                       { SwapFile(NULL); }
+               | imp_acc
+                       { SwapFile(NULL); }
+               | imp_mono
+                       { SwapFile(NULL); }
+               | imp_chare_defn
+                       { SwapFile(NULL); }
+               | imp_main_chare_defn
+                       { SwapFile(NULL); }
+               | imp_boc_defn
+                       { SwapFile(NULL); }
+               | { SwapFile(OUT0);  /* Jan 2 1992, Attila */
+                    if (SELFIMPMODULE) writeoutput("/* ",NOFREE);} 
+                 imp_readonly 
+                 { if (SELFIMPMODULE) {
+                       writeoutput("*/",NOFREE);
+              /*       WriteReturn(); Dec 15, 1993*/
+                    }
+                    WriteReturn(); /* Dec 15,1993 Attila */
+                    SwapFile(NULL); }
+               | { SwapFile(OUT0); /* Jan 6 1992, Attila */
+                    if (SELFIMPMODULE) writeoutput("/* ",NOFREE);}
+                 table_defn
+                  { if (SELFIMPMODULE) {
+                       writeoutput("*/",NOFREE);
+              /*       WriteReturn(); Dec 15 1993 */
+                    } 
+                    WriteReturn(); /* Dec 15, 1993 */
+                   SwapFile(NULL); }
+               ;
+
+imp_acc                : ACCUMULATOR { SwapFile(OUT1); }
+                 aid_list SEMICOLON
+                       { writeoutput(";",NOFREE);WriteReturn(); }
+               ;
+
+imp_mono       : MONOTONIC { SwapFile(OUT1); }
+                 mid_list SEMICOLON
+                       { writeoutput(";",NOFREE);WriteReturn(); }
+               ;
+
+aid_list       : IDENTIFIER 
+                       { worksymtab=Insert($1->string,CurrentTable);
+                         worksymtab->idtype=ACCNAME;
+                         writeoutput("int ",NOFREE);
+                         writeoutput($1->string,NOFREE);
+                         DestroyString($1->string);dontfree($1);
+                       }
+               | aid_list COMMA IDENTIFIER
+                       { worksymtab=Insert($3->string,CurrentTable);
+                         worksymtab->idtype=ACCNAME;
+                         writeoutput(",",NOFREE);
+                         writeoutput($3->string,NOFREE);
+                         DestroyString($3->string);dontfree($3);
+                       }
+               ;
+
+mid_list       : IDENTIFIER
+                       { worksymtab=Insert($1->string,CurrentTable);
+                         worksymtab->idtype=MONONAME;
+                         writeoutput("int ",NOFREE);
+                         writeoutput($1->string,NOFREE);
+                         DestroyString($1->string);dontfree($1);
+                       }
+               | mid_list COMMA IDENTIFIER
+                       { worksymtab=Insert($3->string,CurrentTable);
+                         worksymtab->idtype=MONONAME;
+                         writeoutput(",",NOFREE);
+                         writeoutput($3->string,NOFREE);
+                         DestroyString($3->string);dontfree($3);
+                       }
+               ;
+
+imp_readonly   : readonly
+               ;
+
+ID_L_R_S       : IDENTIFIER L_PAREN R_PAREN SEMICOLON
+                       { worksymtab=Insert($1->string,CurrentTable);
+                         worksymtab->idtype=FNNAME;
+                         writeoutput(" (* ",NOFREE);
+                         writeoutput($1->string,NOFREE);
+                         writeoutput(")();\n  int ",NOFREE);
+                         writeoutput($1->string,NOFREE);
+                         writeoutput(REFSUFFIX,NOFREE);
+                         writeoutput(";",NOFREE);WriteReturn();
+                         DestroyString($1->string);dontfree($1);
+                       }
+               ;
+
+imp_fn_decl    : { SwapFile(OUT1); writeoutput("  int",NOFREE); } ID_L_R_S
+               | { SwapFile(OUT1); writeoutput(" ",NOFREE); }
+                 system_types {writeoutput($2->string);} ID_L_R_S
+               | TYPE_IDENTIFIER
+                       {
+                          SwapFile(OUT1);
+                          writeoutput("  ",NOFREE); 
+                         writeoutput(Map(CurrentModule->name,"0",
+                                               $1->string),NOFREE);
+                         DestroyString($1->string);dontfree($1);
+                       }
+                 ID_L_R_S
+               | {SwapFile(OUT1); writeoutput("  ",NOFREE);} su_spec ID_L_R_S
+               ;
+       
+optID          :       
+               | IDENTIFIER    
+                       { writeoutput(Map(CurrentModule->name,"0",$1->string),NOFREE);
+                         worksymtab=Insert($1->string,CurrentTable);
+                         worksymtab->idtype=STRUCTNAME;
+                         DestroyString($1->string);dontfree($1);
+       /* NOT BOTHERING TO SET ITS TYPE */
+                       }
+               ;
+
+imp_message_defn: MESSAGE      { SwapFile(OUT0);
+                                 writeoutput("typedef struct ",NOFREE);
+                                 ImportLevel=0;
+                                  /* Dec 30 ,1991 added by Attila */
+                                  IMPORTMSGFLAG = 1;
+                                  /* End of Addition */
+                               }
+                 optID L_BRACE { PushStack(); writeoutput(" {",NOFREE); }
+                 msg_opt_su_rest R_BRACE IDENTIFIER SEMICOLON
+                       { TYPEPTR typeptr;
+                          /* Added by Attila, Dec 23 1991 */
+                                  SwapFile(OUT1);
+                                  writeoutput("    int ",NOFREE);
+                                  writeoutput($8->string,NOFREE);
+                                  writeoutput(";",NOFREE);
+                                  WriteReturn();
+                                  SwapFile(OUT0);
+                          /* End Of Addition */
+                         writeoutput(" } ",NOFREE);
+                         typeptr=GetTypeNode(1,0);
+                         typeptr->basictype=STRUCTTYPE;
+                         typeptr->table=CurrentTable;
+                         PopStack(NOFREE);RestoreCurrentTable();
+                         worksymtab=Insert($8->string,CurrentTable);
+                         worksymtab->idtype=MESSAGENAME;
+                         worksymtab->type=typeptr;
+ /*              writeoutput(Map(CurrentModule,"0",$8->string),NOFREE); */
+ /* The statement above has been modified as follows, Attila Dec 23 1991 */
+                          writeoutput(Map(CurrentModule->name,
+                                          "0",$8->string),NOFREE);
+                         writeoutput(";",NOFREE);WriteReturn();
+                         DestroyString($8->string);dontfree($8);
+                          IMPORTMSGFLAG = 0; /* Dec 30,1991 added by Attila */
+                       }
+               ;
+
+imp_chare_defn : CHARE IDENTIFIER
+                       { SwapFile(OUT1);
+                         writeoutput("  struct {",NOFREE);
+                         SwapFile(NULL);
+                         worksymtab=Insert($2->string,CurrentTable);
+                         FillSymTabNode(worksymtab,CHARENAME,IMPORTED,
+                               UNDEFINED,UNDEFINED,1,TRUE,NULL);
+                         CurrentTable=worksymtab->type->table;
+                         CurrentChare=worksymtab;
+                       }
+                 L_BRACE entry_pub_fn_list R_BRACE
+                       { SwapFile(OUT1);
+                         writeoutput("  } ",NOFREE);
+                         writeoutput(CkPrefix,NOFREE);
+                         writeoutput($2->string,NOFREE);
+                         writeoutput(";\n  int ",NOFREE);
+                         writeoutput($2->string,NOFREE);
+                         writeoutput(";",NOFREE);WriteReturn();
+                         SwapFile(NULL);
+                         DestroyString($2->string);dontfree($2);
+                         CurrentTable=CurrentModule->type->table;
+                         CurrentChare=NULL;
+                       }
+               ;
+
+imp_boc_defn   : BRANCHOFFICE IDENTIFIER
+                       { SwapFile(OUT1);
+                         writeoutput("  struct {",NOFREE);
+                         worksymtab=Insert($2->string,CurrentTable);
+                         FillSymTabNode(worksymtab,BOCNAME,IMPORTED,
+                               UNDEFINED,UNDEFINED,1,TRUE,NULL);
+                         CurrentTable=worksymtab->type->table;
+                         CurrentChare=worksymtab;
+                       }
+                 L_BRACE entry_pub_fn_list R_BRACE
+                       { SwapFile(OUT1);
+                         writeoutput("  } ",NOFREE);
+                         writeoutput(CkPrefix,NOFREE);
+                         writeoutput($2->string,NOFREE);
+                         writeoutput(";\n  int ",NOFREE);
+                         writeoutput($2->string,NOFREE);
+                         writeoutput(";",NOFREE);WriteReturn();
+                         DestroyString($2->string);dontfree($2);
+                         CurrentTable=CurrentModule->type->table;
+                         CurrentChare=NULL;
+                       }
+               ;
+
+imp_main_chare_defn : CHARE MAIN 
+                       { SwapFile(OUT1);
+                         writeoutput("  struct {",NOFREE);
+                          /* Jan 6, 1992, added by Attila */
+                          worksymtab=Insert("main",CurrentTable);
+                          FillSymTabNode(worksymtab,CHARENAME,IMPORTED,
+                                UNDEFINED,UNDEFINED,1,TRUE,NULL);
+                          CurrentTable=worksymtab->type->table;
+                          CurrentChare=worksymtab;
+                          /* end of addition */
+                       }
+                 L_BRACE entry_list R_BRACE
+                       { /* Jan 6 1992 , Attila */ SwapFile(OUT1);
+                          writeoutput("  } ",NOFREE);
+                         writeoutput(CkPrefix,NOFREE);
+                         writeoutput("main",NOFREE);
+                         writeoutput(";\n  int ",NOFREE);
+                         writeoutput("main",NOFREE);
+                         writeoutput(";",NOFREE);WriteReturn();
+                          /* Jan 6 1992, added by Attila */
+                         CurrentTable=CurrentModule->type->table;
+                         CurrentChare=NULL;
+                          /* end of addition */
+                       }
+               ;
+
+EIS            : ENTRY IDENTIFIER SEMICOLON
+                       { SwapFile(OUT1);
+                         writeoutput("    int ",NOFREE);
+                         writeoutput($2->string,NOFREE);
+                         writeoutput(";",NOFREE);WriteReturn();
+                         SwapFile(NULL);
+                         worksymtab=Insert($2->string,CurrentTable);
+                         worksymtab->idtype=ENTRYNAME;
+                         worksymtab->declflag=IMPORTED;
+                         DestroyString($2->string);dontfree($2);
+                       }
+               ;
+
+entry_list     : EIS
+               | entry_list EIS
+               ;
+
+ILRS           : IDENTIFIER L_PAREN R_PAREN SEMICOLON
+                       { OUTPUTOFF=FALSE;SwapFile(OUT1);
+                         writeoutput("    int ",NOFREE);
+                         writeoutput($1->string,NOFREE);
+                         writeoutput(";",NOFREE);WriteReturn();
+                         worksymtab=Insert($1->string,CurrentTable);
+                         worksymtab->idtype=PUBLICFNNAME;
+                         worksymtab->declflag=IMPORTED;
+                         DestroyString($1->string);dontfree($1);
+                       }
+
+PUBFN          : PUBLIC        { OUTPUTOFF=TRUE; }
+                 type_spec ILRS
+               | PUBLIC ILRS
+               ;
+entry_pub_fn_list : EIS
+               | PUBFN
+               | entry_pub_fn_list EIS
+               | entry_pub_fn_list PUBFN
+               ;
+
+module_text    : MODULE IDENTIFIER
+                       { worksymtab=LocalFind($2->string);
+                         InPass1 = !InPass1;
+                         if (!InPass1) SwapFile(OUT); else SwapFile(NULL);
+                         SavedLineNo=CurrentInputLineNo;
+                         strcpy(SavedFileName,CurrentFileName);        
+                         if (worksymtab==NULL)
+                               CurrentModule=Insert($2->string,StackBase->tableptr); 
+                         else  { if (InPass1)
+                                 { CurrentModule=worksymtab;
+                                   GenerateStruct($2->string,
+                                    worksymtab->type->table,TRUE,CkPrefix,0);
+                                   ImportModule=worksymtab->type->table;
+                                 }
+                               }
+                         FillSymTabNode(CurrentModule,MODULENAME,DECLARED,
+                               UNDEFINED,UNDEFINED,1,TRUE,NULL);
+                         CurrentTable=CurrentModule->type->table;
+                         ModuleDefined=CurrentModule;
+                         DestroyString($2->string);dontfree($2);
+                         InsertSysCalls();
+                         _dag_init(CurrentModule->name);
+                       }
+                 L_BRACE mod_constructs R_BRACE
+               ;
+
+mod_constructs : construct
+               | mod_constructs construct
+               ;
+
+ext_const      : IDENTIFIER
+                       { writeoutput($1->string,NOFREE);
+                         worksymtab = Insert($1->string,
+                                               CurrentModule->type->table);
+                         worksymtab->idtype=VARNAME;
+                         worksymtab->type=INTPTR;
+                         DestroyString($1->string);dontfree($1); }
+               | IDENTIFIER {writeoutput($1->string,NOFREE);}
+                  L_SQUARE {writeoutput("[",NOFREE);}
+                  ext_constant 
+                  R_SQUARE 
+                          {writeoutput("]",NOFREE);
+                         worksymtab = Insert($1->string,
+                                               CurrentModule->type->table);
+                         worksymtab->idtype=ARRAYNAME;
+                         worksymtab->type=INTPTR;
+                         DestroyString($1->string);dontfree($1); }
+               | IDENTIFIER L_PAREN R_PAREN
+                       { writeoutput($1->string,NOFREE);
+                         writeoutput("()",NOFREE);
+                         worksymtab = Insert($1->string,
+                                               CurrentModule->type->table);
+                         DestroyString($1->string);dontfree($1);
+                         worksymtab->idtype=SYSCALLNAME;
+                         worksymtab->type=INTPTR;
+                       }
+        | IDENTIFIER L_PAREN
+            { writeoutput($1->string, NOFREE);
+              writeoutput("(", NOFREE);
+            }
+            ext_parameter_list R_PAREN
+            { worksymtab = Insert($1->string,
+                    CurrentModule->type->table);
+              DestroyString($1->string);dontfree($1);
+              worksymtab->idtype=SYSCALLNAME;
+              worksymtab->type=INTPTR;
+              writeoutput(")", NOFREE);
+            }
+               ;
+
+ext_parameter_list : typedef_name {
+              ;
+            }
+        | typedef_name IDENTIFIER {
+              writeoutput($1->string, NOFREE);
+            }
+        | ext_parameter_list comma typedef_name {
+             /* writeoutput($3->string, NOFREE);*/
+            }
+        | ext_parameter_list comma typedef_name IDENTIFIER {
+              writeoutput($4->string, NOFREE);
+            }
+        ;
+
+
+ext_constant   : constant
+               |
+                ;
+ext_list       : mopt {if($1!=NULL) {writeoutput("*",NOFREE);dontfree($1);} }
+                  ext_const
+                      
+               | ext_list comma mopt 
+                       {if($3!=NULL) {writeoutput("*",NOFREE);dontfree($3);}}
+                  ext_const
+               ;
+
+construct      : TypeDef type_spec init_decl_list semicolon
+                       { SetIdList($2->type,$3->listptr,TYPENAME,0);
+                         dontfree($2);dontfree($3);
+                       }
+               | TypeDef init_decl_list semicolon
+                         { SetIdList(DUMMYPTR,$2->listptr,TYPENAME,0);
+                           dontfree($2);
+                         }
+               | module_su_spec module_init_decl semicolon 
+                   {  SetIdList($1->type,$2->listptr,VARNAME,0);
+                      dontfree($2); dontfree($1);
+                    }
+               | EXTERN type_spec ext_list semicolon
+               | EXTERN ext_list semicolon
+               | function_decl semicolon
+                           { worksymtab=$1->table;
+                             if (worksymtab->localid==0)
+                                       worksymtab->idtype=SYSCALLNAME;
+                               PopStack(FREE);PopStack(FREE);
+                               RestoreCurrentTable(); }
+               | function_decl function_body
+                 { worksymtab=$1->table;
+                   worksymtab->localid=1;
+                   dontfree($1); RestoreCurrentTable();} 
+               | EXPORT_TO_C
+                       { export_to_c_flag = 1;}
+                 function_decl
+                       { export_to_c_flag = 0;}
+                 function_body
+                       { worksymtab=$3->table;
+                         worksymtab->localid=1;
+                         dontfree($3); RestoreCurrentTable();
+                       }
+               | message_defn
+               | acc_defn
+               | mono_defn
+               | chare_defn
+               | dag_chare_defn
+               | boc_defn
+               | dag_boc_defn
+               | main_chare_defn
+               | readonly
+               | table_defn
+               | const_declaration
+               ;
+
+
+const_declaration : CONST typename IDENTIFIER
+            {
+              writeoutput($3->string, NOFREE);
+                      writeoutput("=", NOFREE);
+            }
+            EQUAL expression SEMICOLON
+            { writeoutput(";", NOFREE); }
+
+
+
+
+/* Feb 18, 1992 added by Attila */
+module_su_spec : Struct IDENTIFIER { if (IMPORTFLAG) ImportStruct=TRUE;
+                                     if (ImportStruct)
+                                               writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                                     else      writeoutput($2->string,NOFREE); 
+                                     ImportStruct=FALSE;
+                                   }
+                 su_rest
+                       { SYMTABPTR dummy,temp;int i;TYPEPTR type;
+
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i!=0) 
+                               { worksymtab=Insert($2->string,CurrentTable);
+                                 worksymtab->type=GetTypeNode(1,0);
+                               }
+                         else  { if ((dummy->declflag!=NOTDECLARED) ||
+                                       (dummy->idtype!=STRUCTNAME))
+                                       error("Bad Struct Name",EXIT);
+                                 worksymtab=dummy;
+                                 type=GetTypeNode(1+worksymtab->type->count,0);
+                                 dummy=(SYMTABPTR)worksymtab->type->type;
+                                 while (dummy!=NULL)
+                                       { temp=(SYMTABPTR)dummy;
+                                         dummy->type=type;dummy=temp;
+                                          /* this is an infinite loop */
+                                          /* set dummy to NULL */
+                                          dummy = NULL;
+                                       }
+                                 dontfree(worksymtab->type);
+                                 worksymtab->type=type;
+                               }
+       
+                         worksymtab->type->basictype=STRUCTTYPE;
+                         worksymtab->idtype=STRUCTNAME;
+                         worksymtab->declflag=DECLARED;
+                         worksymtab->type->table=$4->table;
+                         $$=GetYSN();$$->type=worksymtab->type;
+                         DestroyString($2->string);dontfree($2);dontfree($4);
+                       }
+               | Union IDENTIFIER      { if (IMPORTFLAG) ImportStruct=TRUE;
+                                         if (ImportStruct)
+                                               writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                                         else  writeoutput($2->string,NOFREE); 
+                                         ImportStruct=FALSE;
+                                       }
+                 su_rest
+                       { SYMTABPTR dummy,temp;int i;TYPEPTR type;
+
+                         
+                         {
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i!=0) 
+                               { worksymtab=Insert($2->string,CurrentTable);
+                                 worksymtab->type=GetTypeNode(1,0);
+                               }
+                         else  { if ((dummy->declflag!=NOTDECLARED) ||
+                                       (dummy->idtype!=UNIONNAME))
+                                       error("Bad Struct Name",EXIT);
+                                 worksymtab=dummy;
+                                 type=GetTypeNode(1+worksymtab->type->count,0);
+                                 dummy=(SYMTABPTR)worksymtab->type->type;
+                                 while (dummy!=NULL)
+                                       { temp=(SYMTABPTR)dummy;
+                                         dummy->type=type;dummy=temp;
+                                          /* this is an infinite loop */
+                                          /* set dummy to NULL */
+                                          dummy = NULL;
+                                       }
+                                 dontfree(worksymtab->type);
+                                 worksymtab->type=type;
+                               }
+       
+                         worksymtab->type->basictype=UNIONTYPE;
+                         worksymtab->idtype=UNIONNAME;
+                         worksymtab->declflag=DECLARED;
+                         worksymtab->type->table=$4->table;
+                         $$=GetYSN();$$->type=worksymtab->type;
+                         DestroyString($2->string);dontfree($2);dontfree($4); 
+                         }
+                       }
+               | Enum IDENTIFIER 
+                       { SYMTABPTR dummy; int i;
+
+                         if (IMPORTFLAG) ImportStruct=TRUE;
+                         if (!ImportStruct)
+                               writeoutput($2->string,NOFREE);  
+                         else  writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                          writeoutput(" ",NOFREE);/*Feb18,1992 added by Attila*/
+                         ImportStruct=FALSE;
+                         $$=GetYSN();
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i==0) 
+                               worksymtab=dummy;
+                         else  { worksymtab=LocalFind($2->string);
+                                 if ((worksymtab==NULL)||
+                                      (worksymtab->idtype!=ENUMNAME))
+                                       { worksymtab =
+                                               Insert($2->string,CurrentTable);
+                                         worksymtab->type=GetTypeNode(0,1);
+                                         worksymtab->idtype=ENUMNAME;
+                                         worksymtab->declflag=NOTDECLARED;
+                                         worksymtab->type->declflag=NOTDECLARED;
+                                         worksymtab->type->type=NULL;
+                                       }
+                               }
+                                 
+                         if (worksymtab->idtype!=ENUMNAME)
+                               error("Bad Struct Name",EXIT);
+                         $$->type=worksymtab->type; 
+                         DestroyString($2->string);dontfree($2);
+                       }
+               | Enum IDENTIFIER { if (IMPORTFLAG) ImportStruct=TRUE;
+                                     if (ImportStruct)
+                                               writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                                     else      writeoutput($2->string,NOFREE); 
+                                      writeoutput(" ",NOFREE); /* Feb 18,1992*/
+                                     ImportStruct=FALSE;
+                                   }
+                 enum_rest 
+                       { SYMTABPTR dummy,temp;int i;TYPEPTR type;
+
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i!=0) 
+                               { worksymtab=Insert($2->string,CurrentTable);
+                                 worksymtab->type=GetTypeNode(1,0);
+                               }
+                         else  { if ((dummy->declflag!=NOTDECLARED) ||
+                                       (dummy->idtype!=ENUMNAME))
+                                       error("Bad Struct Name",EXIT);
+                                 worksymtab=dummy;
+                                 type=GetTypeNode(1+worksymtab->type->count,0);
+                                 dummy=(SYMTABPTR)worksymtab->type->type;
+                                 while (dummy!=NULL)
+                                       { temp=(SYMTABPTR)dummy;
+                                         dummy->type=type;dummy=temp;
+                                          /* this is an infinite loop */
+                                          /* set dummy to NULL */
+                                          dummy = NULL;
+                                       }
+                                 dontfree(worksymtab->type);
+                                 worksymtab->type=type;
+                               }
+       
+                         worksymtab->type->basictype=ENUMTYPE;
+                         worksymtab->idtype=ENUMNAME;
+                         worksymtab->declflag=DECLARED;
+                         worksymtab->type->table=$4->table;
+                         $$=GetYSN();$$->type=worksymtab->type;
+                         DestroyString($2->string);dontfree($2);dontfree($4);
+                       }
+               ;
+
+module_init_decl       : {$$=GetYSN();}
+                        ;
+
+/*                                      */
+
+
+
+
+decl_specs     : type_spec             { $$=$1; }
+               | sc_spec               {$$=GetYSN();$$->type=DUMMYPTR;}
+               | type_spec sc_spec     { $$=$1; }
+               | sc_spec type_spec     { $$=$2; }
+               ;
+
+sc_spec                : AUTO 
+               | STATIC
+               | REGISTER
+               | CONST
+               ;
+
+mod_declaration        : decl_specs init_decl_list semicolon
+                         { SetIdList($1->type,$2->listptr,VARNAME,0);
+                           dontfree($2);dontfree($1);
+                         }
+               | TypeDef init_decl_list semicolon
+                         { SetIdList(DUMMYPTR,$2->listptr,TYPENAME,0);
+                           dontfree($2);
+                         }
+               | TypeDef type_spec init_decl_list semicolon
+                         { SetIdList($2->type,$3->listptr,TYPENAME,0);
+                           dontfree($2);dontfree($3);
+                         }
+               | EXTERN type_spec mopt ext_list semicolon
+               | EXTERN ext_list semicolon
+               ;
+
+declaration    : mod_declaration
+               | privpub       { StoredEPFlag=PRIVATEFLAG;
+                                 PRIVATEFLAG=FALSE; 
+                                 INSIDE_PRIVFUNC_PROTO=1;}
+                 function_decl semicolon
+                         { $3->table->idtype=$1->idtype; dontfree($3); 
+                           PopStack(FREE);PopStack(FREE);dontfree($1);
+                           PRIVATEFLAG=StoredEPFlag;
+                           INSIDE_PRIVFUNC_PROTO=0;
+                         }
+               ;
+
+system_types   : CHAR          { $$=$1; $$->type=CHARPTR; }
+               | UNSIGNED CHAR { $$=$1; $$->type=CHARPTR;
+                                  CreateUnsignedTerm(&($$->string),$2->string);
+                                }
+               | SIGNED CHAR { $$=$1; $$->type=CHARPTR;
+                                  CreateUnsignedTerm(&($$->string),$2->string);
+                                }
+               | SHORT         { $$=$1; $$->type=SHORTPTR; }
+               | UNSIGNED SHORT{ $$=$1; $$->type=SHORTPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | SIGNED SHORT{ $$=$1; $$->type=SHORTPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | INT           { $$=$1; $$->type=INTPTR; }
+               | LONG          { $$=$1; $$->type=LONGPTR; }
+               | UNSIGNED LONG { $$=$1; $$->type=LONGPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | SIGNED LONG { $$=$1; $$->type=LONGPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | SIGNED INT { $$=$1; $$->type=INTPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | DOUBLE        { $$=$1; $$->type=DOUBLEPTR; }
+               | FLOAT         { $$=$1; $$->type=FLOATPTR; }
+               | UNSIGNED      { $$=$1; $$->type=UNSIGNEDPTR; }
+               | SHORT INT     { $$=$1; $$->type=SHORTPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | LONG INT      { $$=$1; $$->type=LONGPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | LONG LONG     { $$=$1; $$->type=LONGPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | LONG FLOAT    { $$=$1; $$->type=DOUBLEPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | LONG DOUBLE   { $$=$1; $$->type=DOUBLEPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | UNSIGNED INT  { $$=$1; $$->type=UNSIGNEDPTR; 
+                                 CreateUnsignedTerm(&($$->string), $2->string);                                }
+               | UNSIGNED INT INT { $$=$1;  $$->type=UNSIGNEDPTR;
+                                 CreateUnsignedTerm2(&($$->string), $2->string,$3->string);
+                               }
+               | UNSIGNED LONG LONG { $$=$1;  $$->type=UNSIGNEDPTR;
+                                 CreateUnsignedTerm2(&($$->string), $2->string,$3->string);
+                               }
+               | UNSIGNED LONG INT { $$=$1;  $$->type=UNSIGNEDPTR;
+                                 CreateUnsignedTerm2(&($$->string), $2->string,$3->string);
+                               }
+               | VOID          { $$=$1; $$->type=VOIDPTR; }
+               | ChareIDType   { $$=$1; $$->type=CHAREIDPTR; }
+               | EntryPointType { $$=$1; $$->type=ENTRYPOINTPTR; }
+               | PeNumType     { $$=$1; $$->type=PENUMPTR; }
+               | PackIDType    { $$=$1; $$->type=PACKIDPTR; }
+               | WriteOnceID   { $$=$1; $$->type=WRITEONCEIDPTR; }
+               | PVECTOR       { $$=$1; $$->type=PVECTORPTR; }
+               | ChareNameType { $$=$1; $$->type=CHARENAMEPTR; }
+               | ChareNumType  { $$=$1; $$->type=CHARENUMPTR; }
+               | EntryNumType  { $$=$1; $$->type=ENTRYNUMPTR; }
+               | BOOLEAN       { $$=$1; $$->type=BOOLEANPTR; }
+               | ACCIDTYPE     { $$=$1; $$->type=INTPTR; /* TO SIMPLIFY */}
+               | MONOIDTYPE    { $$=$1; $$->type=INTPTR; }
+               | DUMMYMSG      { $$=$1; $$->type=INTPTR; }
+                | FunctionRefType { $$=$1; $$->type=FUNCTIONREFPTR; }
+                | FUNCTION_PTR  { $$=$1; $$->type=FUNCTIONPTR; } 
+               ;
+
+type_spec      : su_spec       { $$=$1; }
+               | typedef_name  { $$=$1; }
+               ;
+
+init_decl_list : init_decl     { $$=GetYSN();$$->listptr=GetListNode($1); }
+               | init_decl_list comma init_decl
+                         { $$ = $1;
+                           if ($$->listptr==NULL)
+                               error("Unexpected ','",EXIT);
+                           InsertNode($$->listptr,$3); 
+                         }
+               |       {  $$=GetYSN(); }
+               ;
+
+init_decl      : declarator initializer_opt    { $$=$1; }
+               ;
+
+declarator     : IDENTIFIER    { /*writeoutput($1->string,NOFREE);*/
+                       /* When in import, modified if level=0 : see lex.c */
+                               /*  if ((IMPORTFLAG)&&(ImportLevel==0)) */
+                                /*  Dec 30, 1991, modified by Attila */
+                                 if ((IMPORTFLAG)&&(ImportLevel==0)
+                                      && (!IMPORTMSGFLAG) )
+                                 writeoutput(Map(CurrentModule->name,"0",
+                                                       $1->string),NOFREE);
+                                 else writeoutput($1->string,NOFREE);
+                                 $$=$1;
+                               }
+               | lparen declarator rparen      %prec L_PAREN
+                       { $$=$2; }
+               | MULT {dump("*");} declarator  
+                       { YSNPTR dummy;
+                         
+                         $$=$3;dummy=$$;
+                         while (dummy->ysn!=NULL) dummy=dummy->ysn;
+                         dummy->ysn=GetYSN();dummy->ysn->idtype=POINTERTYPE;
+                       }
+               | declarator lparen rparen      %prec L_PAREN
+                       { YSNPTR dummy;
+                         
+                         $$=$1;dummy=$$;
+                         while (dummy->ysn!=NULL) dummy=dummy->ysn;
+                         dummy->ysn=GetYSN();dummy->ysn->idtype=FUNCTIONTYPE;
+                       }  
+               | declarator lsquare rsquare    %prec L_SQUARE
+                       { YSNPTR dummy;
+                         
+                         $$=$1;dummy=$$;
+                         while (dummy->ysn!=NULL) dummy=dummy->ysn;
+                         dummy->ysn=GetYSN();dummy->ysn->idtype=ARRAYTYPE;
+                       }
+               | declarator lsquare expression rsquare %prec L_SQUARE
+                       { YSNPTR dummy;
+                         
+                         $$=$1;dummy=$$;
+                         while (dummy->ysn!=NULL) dummy=dummy->ysn;
+                         dummy->ysn=GetYSN();dummy->ysn->idtype=ARRAYTYPE;
+                       }
+               ;
+
+su_spec                : Struct su_rest
+                       { $$=GetYSN();
+                         $$->type=GetTypeNode(0,0);
+                         $$->type->basictype=STRUCTTYPE;
+                         $$->type->table=$2->table;
+                         dontfree($2);
+                       }       
+               | Struct TYPE_OR_ID 
+                       { SYMTABPTR dummy; int i;
+
+                         if (IMPORTFLAG) ImportStruct=TRUE;
+                         if (!ImportStruct)
+                               writeoutput($2->string,NOFREE);  
+                         else  writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                          writeoutput(" ",NOFREE);/*Feb18,1992 added by Attila*/
+                         ImportStruct=FALSE;
+                         $$=GetYSN();
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i==0) 
+                               worksymtab=dummy;
+                         else  { worksymtab=LocalFind($2->string);
+                                 if ((worksymtab==NULL)||(worksymtab->idtype!=STRUCTNAME))
+                                       { worksymtab =
+                                               Insert($2->string,CurrentTable);
+                                         worksymtab->type=GetTypeNode(0,1);
+                                         worksymtab->idtype=STRUCTNAME;
+                                         worksymtab->declflag=NOTDECLARED;
+                                         worksymtab->type->declflag=NOTDECLARED;
+                                         worksymtab->type->type=NULL;
+                                       }
+                               }
+                                 
+                         if (worksymtab->idtype!=STRUCTNAME)
+                               error("Bad Struct Name",EXIT);
+                         $$->type=worksymtab->type; 
+                         DestroyString($2->string);dontfree($2);
+                       }
+               | Struct IDENTIFIER { if (IMPORTFLAG) ImportStruct=TRUE;
+                                     if (ImportStruct)
+                                               writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                                     else      writeoutput($2->string,NOFREE); 
+                                      writeoutput(" ",NOFREE); /* Feb 18,1992*/
+                                     ImportStruct=FALSE;
+                                   }
+                 su_rest
+                       { SYMTABPTR dummy,temp;int i;TYPEPTR type;
+
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i!=0) 
+                               { worksymtab=Insert($2->string,CurrentTable);
+                                 worksymtab->type=GetTypeNode(1,0);
+                               }
+                         else  { if ((dummy->declflag!=NOTDECLARED) ||
+                                       (dummy->idtype!=STRUCTNAME))
+                                       error("Bad Struct Name",EXIT);
+                                 worksymtab=dummy;
+                                 type=GetTypeNode(1+worksymtab->type->count,0);
+                                 dummy=(SYMTABPTR)worksymtab->type->type;
+                                 while (dummy!=NULL)
+                                       { temp=(SYMTABPTR)dummy;
+                                         dummy->type=type;dummy=temp;
+                                          /* this is an infinite loop */
+                                          /* set dummy to NULL */
+                                          dummy = NULL;
+                                       }
+                                 dontfree(worksymtab->type);
+                                 worksymtab->type=type;
+                               }
+       
+                         worksymtab->type->basictype=STRUCTTYPE;
+                         worksymtab->idtype=STRUCTNAME;
+                         worksymtab->declflag=DECLARED;
+                         worksymtab->type->table=$4->table;
+                         $$=GetYSN();$$->type=worksymtab->type;
+                         DestroyString($2->string);dontfree($2);dontfree($4);
+                       }
+               | Union su_rest
+                       { 
+                         { $$=GetYSN();
+                         $$->type=GetTypeNode(0,0);
+                         $$->type->basictype=UNIONTYPE;
+                         $$->type->table=$2->table;
+                         dontfree($2);
+                         }
+                       }       
+               | Union IDENTIFIER
+                       { SYMTABPTR dummy; int i;
+
+                         if (IMPORTFLAG) ImportStruct=TRUE;
+                         if (ImportStruct)
+                               writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                         else  writeoutput($2->string,NOFREE);  
+                          writeoutput(" ",NOFREE); /* Feb 18 1992 */
+                         ImportStruct=FALSE;
+                         $$=GetYSN();
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i==0) 
+                               worksymtab=dummy;
+                         else  { worksymtab=LocalFind($2->string);
+                                 if ((worksymtab==NULL)||(worksymtab->idtype!=UNIONNAME))
+                                       { worksymtab =
+                                               Insert($2->string,CurrentTable);
+                                         worksymtab->type=GetTypeNode(0,1);
+                                         worksymtab->idtype=UNIONNAME;
+                                         worksymtab->declflag=NOTDECLARED;
+                                         worksymtab->type->declflag=NOTDECLARED;
+                                         worksymtab->type->type=NULL;
+                                       }
+                               }
+                                 
+                         if (worksymtab->idtype!=UNIONNAME)
+                               error("Bad Struct Name",EXIT);
+                         $$->type=worksymtab->type; 
+                         DestroyString($2->string);dontfree($2);
+                       }
+               | Union IDENTIFIER      { if (IMPORTFLAG) ImportStruct=TRUE;
+                                         if (ImportStruct)
+                                               writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                                         else  writeoutput($2->string,NOFREE); 
+                                          writeoutput(" ",NOFREE);/*Feb18 1992*/
+                                         ImportStruct=FALSE;
+                                       }
+                 su_rest
+                       { SYMTABPTR dummy,temp;int i;TYPEPTR type;
+
+                         
+                         {
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i!=0) 
+                               { worksymtab=Insert($2->string,CurrentTable);
+                                 worksymtab->type=GetTypeNode(1,0);
+                               }
+                         else  { if ((dummy->declflag!=NOTDECLARED) ||
+                                       (dummy->idtype!=UNIONNAME))
+                                       error("Bad Struct Name",EXIT);
+                                 worksymtab=dummy;
+                                 type=GetTypeNode(1+worksymtab->type->count,0);
+                                 dummy=(SYMTABPTR)worksymtab->type->type;
+                                 while (dummy!=NULL)
+                                       { temp=(SYMTABPTR)dummy;
+                                         dummy->type=type;dummy=temp;
+                                          /* this is an infinite loop */
+                                          /* set dummy to NULL */
+                                          dummy = NULL;
+                                       }
+                                 dontfree(worksymtab->type);
+                                 worksymtab->type=type;
+                               }
+       
+                         worksymtab->type->basictype=UNIONTYPE;
+                         worksymtab->idtype=UNIONNAME;
+                         worksymtab->declflag=DECLARED;
+                         worksymtab->type->table=$4->table;
+                         $$=GetYSN();$$->type=worksymtab->type;
+                         DestroyString($2->string);dontfree($2);dontfree($4); 
+                         }
+                       }
+
+               | Enum enum_rest
+                       { $$=GetYSN();
+                         $$->type=GetTypeNode(0,0);
+                         $$->type->basictype=STRUCTTYPE;
+                         $$->type->table=$2->table;
+                         dontfree($2);
+                       }       
+               | Enum IDENTIFIER 
+                       { SYMTABPTR dummy; int i;
+
+                         if (IMPORTFLAG) ImportStruct=TRUE;
+                         if (!ImportStruct)
+                               writeoutput($2->string,NOFREE);  
+                         else  writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                          writeoutput(" ",NOFREE);/*Feb18,1992 added by Attila*/
+                         ImportStruct=FALSE;
+                         $$=GetYSN();
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i==0) 
+                               worksymtab=dummy;
+                         else  { worksymtab=LocalFind($2->string);
+                                 if ((worksymtab==NULL)||
+                                      (worksymtab->idtype!=ENUMNAME))
+                                       { worksymtab =
+                                               Insert($2->string,CurrentTable);
+                                         worksymtab->type=GetTypeNode(0,1);
+                                         worksymtab->idtype=ENUMNAME;
+                                         worksymtab->declflag=NOTDECLARED;
+                                         worksymtab->type->declflag=NOTDECLARED;
+                                         worksymtab->type->type=NULL;
+                                       }
+                               }
+                                 
+                         if (worksymtab->idtype!=ENUMNAME)
+                               error("Bad Struct Name",EXIT);
+                         $$->type=worksymtab->type; 
+                         DestroyString($2->string);dontfree($2);
+                       }
+               | Enum IDENTIFIER { if (IMPORTFLAG) ImportStruct=TRUE;
+                                     if (ImportStruct)
+                                               writeoutput(Map(CurrentModule->name,"_CKTYPE",$2->string),NOFREE); 
+                                     else      writeoutput($2->string,NOFREE); 
+                                      writeoutput(" ",NOFREE); /* Feb 18,1992*/
+                                     ImportStruct=FALSE;
+                                   }
+                 enum_rest 
+                       { SYMTABPTR dummy,temp;int i;TYPEPTR type;
+
+                         dummy=FindInTable(CurrentTable,$2->string,&i);
+                         if (i!=0) 
+                               { worksymtab=Insert($2->string,CurrentTable);
+                                 worksymtab->type=GetTypeNode(1,0);
+                               }
+                         else  { if ((dummy->declflag!=NOTDECLARED) ||
+                                       (dummy->idtype!=ENUMNAME))
+                                       error("Bad Struct Name",EXIT);
+                                 worksymtab=dummy;
+                                 type=GetTypeNode(1+worksymtab->type->count,0);
+                                 dummy=(SYMTABPTR)worksymtab->type->type;
+                                 while (dummy!=NULL)
+                                       { temp=(SYMTABPTR)dummy;
+                                         dummy->type=type;dummy=temp;
+                                          /* this is an infinite loop */
+                                          /* set dummy to NULL */
+                                          dummy = NULL;
+                                       }
+                                 dontfree(worksymtab->type);
+                                 worksymtab->type=type;
+                               }
+       
+                         worksymtab->type->basictype=ENUMTYPE;
+                         worksymtab->idtype=ENUMNAME;
+                         worksymtab->declflag=DECLARED;
+                         worksymtab->type->table=$4->table;
+                         $$=GetYSN();$$->type=worksymtab->type;
+                         DestroyString($2->string);dontfree($2);dontfree($4);
+                       }
+               ;
+
+
+TYPE_OR_ID     : IDENTIFIER
+               | TYPE_IDENTIFIER
+               ;
+
+su_rest                : L_BRACE       { if (IMPORTFLAG) ImportLevel++; 
+                                 writeoutput("{",NOFREE); PushStack(); 
+                               }
+                 s_decl_list R_BRACE   
+                       { writeoutput("}",NOFREE); 
+                         $$=GetYSN(); $$->table=CurrentTable;
+                         PopStack(NOFREE);RestoreCurrentTable();
+                         if (IMPORTFLAG) ImportLevel--;
+                       }
+               ;
+
+s_decl_list    : struct_decl
+               | s_decl_list struct_decl
+               ;
+
+struct_decl    : type_spec s_declarator_list semicolon
+                       { SetIdList($1->type,$2->listptr,FIELDNAME,0);
+                         dontfree($2);dontfree($1);
+                       }
+               ;
+
+s_declarator_list      : s_declarator  { $$=GetYSN();
+                                         $$->listptr=GetListNode($1);
+                                       }
+               | s_declarator_list comma s_declarator
+                       { $$=$1;InsertNode($$->listptr,$3); }
+               ;
+
+s_declarator   : declarator                    { $$=$1; }
+               | declarator colon const_exp    { $$=$1; }
+               | colon const_exp               {  $$=GetYSN(); } 
+               ;
+
+
+
+
+enum_rest      : L_BRACE       { if (IMPORTFLAG) ImportLevel++; 
+                                 writeoutput("{",NOFREE);
+                               }
+                 enum_opt enum_list R_BRACE    
+                       { 
+                          SetIdList($3->type,$4->listptr,VARNAME,0);
+                          writeoutput("}",NOFREE); 
+                         $$=GetYSN(); $$->table=CurrentTable;
+                         if (IMPORTFLAG) ImportLevel--;
+                       }
+               ;
+
+enum_opt       : {$$=GetYSN(); $$->type = INTPTR;}
+
+enum_list      : enum_member { $$ = GetYSN(); $$->listptr=GetListNode($1);}
+               | enum_list comma enum_member
+                      { $$ = $1;
+                        if ($$->listptr==NULL)
+                           error("error in enum definition ",EXIT);
+                        InsertNode($$->listptr,$3);
+                      } 
+
+enum_member    : IDENTIFIER
+                    { writeoutput($1->string,NOFREE);
+                      writeoutput(" ",NOFREE);
+                     $$ = $1;
+                    } 
+               | IDENTIFIER 
+                    {  writeoutput($1->string,NOFREE);
+                      writeoutput(" ",NOFREE);  
+                       $$ = $1;
+                   }
+                  equal base_expression
+                ;
+
+initializer_opt        :
+               | initializer
+               ;
+
+initializer    : equal expression
+               | equal L_BRACE         {  
+                                               writeoutput("{",NOFREE); }
+                 init_rest
+               ;
+
+init_rest      : initializer_list R_BRACE      { 
+                                                     writeoutput("}",NOFREE); }
+               | initializer_list comma_R_BRACE
+               ;
+
+initializer_list       : expression
+                       | initializer_list comma_L_BRACE initializer_list 
+                         R_BRACE               { 
+                                                    writeoutput("}",NOFREE); }
+                       | L_BRACE               { 
+                                                    writeoutput("{",NOFREE); }
+                         initializer_list R_BRACE
+                               {  writeoutput("}",NOFREE); }
+                       ;
+
+
+typename       : type_spec abstract_decl { 
+                                           { FreeType($1->type);dontfree($1); }
+                                         }
+               ;
+
+abstract_decl  :
+               | lparen abstract_decl rparen   %prec L_PAREN
+               | MULT {dump("*");} abstract_decl
+               | abstract_decl lparen rparen   %prec L_PAREN
+               | abstract_decl lsquare rsquare %prec L_SQUARE
+               | abstract_decl lsquare expression rsquare %prec L_SQUARE
+               ;
+
+typedef_name   : TYPE_IDENTIFIER       
+                       { TYPEPTR typeptr;
+
+                         worksymtab=LocalFind($1->string);typeptr=NULL;
+                         if (IMPORTFLAG)
+                        /* it is a type id : MUST be at level 0 */
+                               { writeoutput(Map(CurrentModule->name,"0",
+                                       $1->string),NOFREE);
+                                 if ((worksymtab==NULL)||
+               /*                      (worksymtab->idtype!=TYPENAME)) */
+                /*  Dec 31, Attila */
+                                       ((worksymtab->idtype!=TYPENAME) && 
+                                       (worksymtab->idtype!=MESSAGENAME)))
+                                       error("Bad Type Reference",EXIT);
+                                 else  typeptr=worksymtab->type;
+                               }
+                         else  /* writeoutput($1->string,NOFREE); */
+                               typeptr=ProcessTypeIdentifier($1);
+                         $$=GetYSN();$$->type=typeptr;
+                         $$->table=($1->modstring==NULL)?GlobalFind($1->string)
+                               :GlobalModuleSearch($1->string,$1->modstring);
+                         DestroyString($1->modstring);
+                         DestroyString($1->string);dontfree($1);
+                       }
+               | system_types  { $$=$1;writeoutput($1->string,NOFREE);
+                                 writeoutput(" ",NOFREE);
+                                 $$->table=$$->type->table; }
+               ;
+
+base_expression        : primary
+               | unary  base_expression %prec UNARY
+               | SIZEOF lparen typedef_name rparen     %prec UNARY 
+               | SIZEOF base_expression        %prec UNARY
+               | lparen typename rparen base_expression %prec UNARY
+               | base_expression MULTDIV base_expression %prec MULT
+               | base_expression ADDSUB base_expression %prec PLUS
+               | base_expression shift base_expression %prec SHIFT
+               | base_expression compare base_expression       %prec COMPARE
+               | base_expression equalequal base_expression    %prec EQUALEQUAL
+               | base_expression notequal base_expression      %prec NOTEQUAL
+               | base_expression AND {dump("&");} base_expression
+               | base_expression HAT {dump("^");} base_expression
+               | base_expression OR { dump("|"); } base_expression
+               | base_expression ANDAND { dump("&&"); } base_expression
+               | base_expression OROR {dump("||");} base_expression
+               | base_expression QUESTION {dump("?");} base_expression colon base_expression
+               | primary asgnop base_expression        %prec ASGNOP
+               | primary equal base_expression %prec EQUAL
+               ;
+CKPRIO_L       : CKALLOCPRIOMSG L_PAREN
+               ;
+
+CK_L           : CKALLOCMSG L_PAREN
+               ;
+
+expression     : primary
+               | unary  expression %prec UNARY
+               | SIZEOF lparen typedef_name rparen     %prec UNARY 
+               | SIZEOF expression     %prec UNARY
+               | lparen typename rparen expression %prec UNARY
+               | expression MULTDIV expression %prec MULT
+               | expression ADDSUB expression %prec PLUS
+               | expression shift expression   %prec SHIFT
+               | expression compare expression %prec COMPARE
+               | expression equalequal expression      %prec EQUALEQUAL
+               | expression notequal expression        %prec NOTEQUAL
+               | expression AND {dump("&");} expression
+               | expression HAT {dump("^");} expression
+               | expression OR { dump("|"); } expression
+               | expression ANDAND { dump("&&"); } expression
+               | expression OROR {dump("||");} expression
+               | expression QUESTION {dump("?");} expression colon expression
+               | primary asgnop expression     %prec ASGNOP
+               | primary equal expression      %prec EQUAL
+               | expression COMMA { dump(","); } expression
+               | PRIVATECALL lparen IDENTIFIER 
+                       { if (!InPass1)
+                         { worksymtab=GlobalFind($3->string);
+                         DestroyString($3->string);dontfree($3);
+                         if ((worksymtab==NULL)||(worksymtab->idtype!=
+                                       PRIVATEFNNAME))
+                               if (!InPass1)
+                                       error("Bad Private Call",EXIT);
+                         if (!InPass1)
+                               writeoutput(Map(CurrentModule->name,
+                               CurrentChare->name,worksymtab->name),NOFREE);
+                         }
+                       } 
+                 lparen
+                       {  
+                               writeoutput(CkLocalPtr,NOFREE);
+                       }
+                 expression_opt rparen rparen
+               | BRANCHCALL lparen { BUFFEROUTPUT=TRUE; }
+                 base_expression   { BUFFEROUTPUT=FALSE; }
+                 COMMA ck_primary lparen
+                       { writeoutput("GetBocDataPtr(",NOFREE);
+                         writeoutput(buffer.a,NOFREE);buffer.count=0;
+                         writeoutput(")",NOFREE);
+                       }
+                 expression_opt rparen rparen
+               | CHARECALL lparen {  BUFFEROUTPUT=TRUE; }
+                 base_expression {  BUFFEROUTPUT=FALSE; }
+                 COMMA ck_primary lparen
+                       { writeoutput("GetChareDataPtr(",NOFREE);
+                         writeoutput(buffer.a,NOFREE);buffer.count=0;
+                         writeoutput(")",NOFREE); 
+                       }
+                 expression_opt rparen rparen
+               | FNNAMETOREF L_PAREN   { FNNAMETOREFFLAG=TRUE; }
+                 ck_primary R_PAREN    { FNNAMETOREFFLAG=FALSE; } 
+                 /*semicolon */ /* Jan 16, 1992 Attila */
+                /* following rule added, Jan 16 1992, by Attila */
+                | FNREFTONAME L_PAREN   {
+                    FNREFTONAMEFLAG = TRUE;
+                    writeoutput("CsvAccess(_CK_9_GlobalFunctionTable)[",NOFREE);
+                    }
+                  expression R_PAREN    { 
+                    writeoutput("]",NOFREE);
+                    FNREFTONAMEFLAG=FALSE; 
+                    } 
+               | CK_L IDENTIFIER ckallocrest
+                       { if (!InPass1)
+                               { error("Bad Message Type",EXIT); }
+                       }
+               | CK_L TYPE_IDENTIFIER 
+                       { if (!InPass1)
+
+/** I changed LocalFind to GlobalFind on Oct. 27, 1991. The same change
+    has been made in Prio.. I hope it works!
+**/
+
+                         {worksymtab=($2->modstring==NULL)?GlobalFind($2->string):GlobalModuleSearch($2->string,$2->modstring);
+                         if ((worksymtab==NULL)||(worksymtab->idtype!=MESSAGENAME))
+                               error("Bad Message Type",NOEXIT);
+                         else  {
+
+                                 if (strcmp(CurrentModule->name,worksymtab->modname->name))
+                                       SavedName=ModulePrefix(worksymtab->modname->name,worksymtab->name);
+                                 else  SavedName=MyModulePrefix(worksymtab->modname->name,worksymtab->name);
+                                 if (worksymtab->localid<=0) {
+                                       writeoutput(CkGenericAlloc,NOFREE); 
+                                 }
+                                 else  { 
+                                       writeoutput("(",NOFREE);
+                                       writeoutput(CkVarSizeAlloc,NOFREE); 
+                                       writeoutput("[",NOFREE);
+                                       writeoutput(SavedName,NOFREE);
+                                       writeoutput("].alloc)",NOFREE);
+                                 }
+                                 writeoutput("(",NOFREE);
+                                 writeoutput(SavedName,FREE);
+                                 writeoutput(",",NOFREE);
+                                 writeoutput("sizeof(",NOFREE);
+                                 if (strcmp(CurrentModule->name,worksymtab->modname->name))
+                                       SavedName=Map(worksymtab->modname->name,"0",worksymtab->name);
+                                 else  SavedName=worksymtab->name;
+                                 writeoutput(SavedName,NOFREE);
+                                 writeoutput("),0",NOFREE);
+                               }
+                        }
+                       }
+                 ckallocrest
+               | CKPRIO_L TYPE_IDENTIFIER COMMA
+                       { if (!InPass1)
+                         {worksymtab=($2->modstring==NULL)?GlobalFind($2->string):GlobalModuleSearch($2->string,$2->modstring);
+                         if ((worksymtab==NULL)||(worksymtab->idtype!=MESSAGENAME))
+                               error("Bad Message Type",NOEXIT);
+                         else  {
+                                 if (strcmp(CurrentModule->name,worksymtab->modname->name))
+                                       SavedName=ModulePrefix(worksymtab->modname->name,worksymtab->name);
+                                 else  SavedName=MyModulePrefix(worksymtab->modname->name,worksymtab->name);
+                                  if (worksymtab->localid<=0) {
+                                               writeoutput(CkGenericAlloc,NOFREE); 
+                                 }
+                                 else  {
+                                       writeoutput("(",NOFREE);
+                                       writeoutput(CkVarSizeAlloc,NOFREE); 
+                                       writeoutput("[",NOFREE);
+                                       writeoutput(SavedName,NOFREE);
+                                       writeoutput("].alloc)",NOFREE);
+                                 }
+                                 writeoutput("(",NOFREE);
+                                 writeoutput(SavedName,FREE);
+                                 writeoutput(",",NOFREE);
+                                 writeoutput("sizeof(",NOFREE);
+                                 if (strcmp(CurrentModule->name,worksymtab->modname->name))
+                                       SavedName=Map(worksymtab->modname->name,"0",worksymtab->name);
+                                 else  SavedName=worksymtab->name;
+                                 writeoutput(SavedName,NOFREE);
+                                 writeoutput("),",NOFREE);
+                               }
+                         }
+                       }
+                 base_expression ckallocrest
+               | CKPRIO_L IDENTIFIER COMMA
+                 base_expression ckallocrest
+                       { if (!InPass1)
+                               { error("Bad Message Type",EXIT); }
+                       }
+               | READMSGINIT { READMSGINITFLAG=TRUE; } 
+                 lparen ck_primary rparen 
+                       { READMSGINITFLAG=FALSE; }
+               | ACCUMULATE L_PAREN    { BUFFEROUTPUT = TRUE; }
+                 base_expression COMMA
+                       { BUFFEROUTPUT = FALSE;
+                         writeoutput("\n{ _CK_4AccDataAreaType *_CK_4dptr;\n",NOFREE);
+                         writeoutput("  _CK_4dptr=_CK_9GetAccDataArea(",NOFREE);
+                         writeoutput(buffer.a,NOFREE);buffer.count=0;
+                         writeoutput(");\n");
+                         writeoutput("  _CK_9LockAccDataArea(_CK_4dptr);\n",NOFREE);
+                         writeoutput("  _CK_9GetAccumulateFn(_CK_4dptr)(_CK_9GetAccDataPtr(_CK_4dptr)",NOFREE);
+                       }
+                 IDENTIFIER L_PAREN expression_R_PAREN rparen
+                       { if (strcmp($7->string,"addfn"))
+                               error("addfn expected",EXIT);
+                         writeoutput(";\n  _CK_9UnlockAccDataArea(_CK_4dptr);\n}\n",NOFREE);
+                          MULTI_STMT_TR = 1;
+                       }
+               | NEWVALUE L_PAREN      { BUFFEROUTPUT = TRUE; }
+                 base_expression COMMA
+                       { BUFFEROUTPUT = FALSE;
+                         writeoutput("\n{ _CK_4MonoDataAreaType *_CK_4dptr;\n",NOFREE);
+                         writeoutput("  _CK_4dptr=_CK_9GetMonoDataArea(",NOFREE);
+                         writeoutput(buffer.a,NOFREE);buffer.count=0;
+                         writeoutput(");\n");
+                         writeoutput("  _CK_9LockMonoDataArea(_CK_4dptr);\n",NOFREE);
+                         /*writeoutput("  _CK_9Mono(_CK_4dptr)(_CK_9GetMonoDataPtr(_CK_4dptr)",NOFREE);*/
+                         writeoutput("  _CK_9MONO_BranchNewValue(_CK_4dptr",NOFREE);
+                       }
+                 IDENTIFIER L_PAREN expression_R_PAREN rparen
+                       { if (strcmp($7->string,"updatefn"))
+                               error("updatefn expected",EXIT);
+                         writeoutput(";\n  _CK_9UnlockMonoDataArea(_CK_4dptr);\n}\n",NOFREE);
+                          MULTI_STMT_TR = 1;
+                       }
+               | BLOCKEDRECV 
+                     {writeoutput("CkBlockedRecv",NOFREE);} 
+                     lparen
+                     {
+                          if ( CurrentChare == NULL )
+                             error("CkBlockedRecv not allowed here",EXIT);
+                          else if (CurrentChare->idtype == CHARENAME)
+                                 writeoutput("NULL,",NOFREE);
+                          else
+                                 writeoutput("_CK_4mydata,",NOFREE);
+                     }
+                  ck_primary rparen
+               ;
+
+expression_R_PAREN : R_PAREN 
+               |       { writeoutput(",",NOFREE); }
+                 expression R_PAREN 
+               ;
+
+ckallocrest    : R_PAREN 
+                       { writeoutput(")",NOFREE); }
+               | COMMA { writeoutput(",",NOFREE); }
+                 base_expression R_PAREN
+                       { writeoutput(")",NOFREE); }
+               ;
+
+expression_opt :               
+               | { writeoutput(",",NOFREE); } expression       
+               ;
+
+unary          : MULT          {dump("*");}    
+               | AND           {dump("&");}    
+               | MINUS         {dump("-");}    
+               | TILDE         {dump("~");}    
+               | EXCLAIM       {dump("!");}    
+               ;
+MULTDIV                : MULT          {dump("*");}
+               | DIV           {dump("/");}
+               | MOD           {dump("%");}
+               ;
+
+ADDSUB                 : PLUS          {dump("+");}
+               | MINUS         {dump("-");}
+               ;
+
+primary                : constant 
+               | string
+               | lparen expression rparen
+               | primary lparen rparen                 %prec L_PAREN
+               | primary lparen expression rparen      %prec L_PAREN
+               | primary lsquare expression rsquare  %prec L_SQUARE
+               | primary DOT {dump(".");} IDENTIFIER
+                       { 
+                         { writeoutput($4->string,NOFREE);
+                           DestroyString($4->string);dontfree($4);
+                         }
+                       }       
+               | primary POINTERREF {dump("->");} IDENTIFIER
+                       { 
+                         { writeoutput($4->string,NOFREE);
+                           DestroyString($4->string);dontfree($4);
+                         }
+                       }       
+               | incdec primary        %prec INCDEC
+               | primary incdec        %prec INCDEC
+               | ck_primary
+               ;
+
+ck_primary     : IDENTIFIER    { SYMTABPTR dummy;
+                                 int i;
+                                 
+                                 if ((!InPass1)&&(!SpecialVar($1)))
+                                 { 
+                                 worksymtab=GlobalFind($1->string);
+                                 if (worksymtab==NULL)
+                                       {
+                                        /*
+                                       error("Undeclared Identifier: ",NOEXIT);
+                                       PutOnScreen($1->string);
+                                        PutOnScreen("\n");
+                                        */
+                                       }
+                                 if (IsFunction(worksymtab))
+                                       writefunction(worksymtab);
+                                 else if (IsEntry(worksymtab))
+                                               writeentry(worksymtab);
+                                      else if (IsPublic(worksymtab))
+                                               writepublic(worksymtab);
+                                      else if (IsReadOnly(worksymtab))
+                                               writereadonly(worksymtab);
+                                      else if (IsAccumulator(worksymtab))
+                                               writeaccname(worksymtab);
+                                      else if (IsMonotonic(worksymtab))
+                                               writemononame(worksymtab);
+                                      else if (IsTable(worksymtab))
+                                               writetable(worksymtab);
+                                      else if (IsChare(worksymtab))
+                                               writechare(worksymtab);
+                                      else { if ((worksymtab==NULL) ||
+                                                 (worksymtab !=
+                                                 LocalFind(worksymtab->name)))
+                                            {if (!InPass1)
+                                                /*  PutOnScreen($1->string); */
+                                             {  /*
+                                               error("Bad Identifier: ",NOEXIT);
+                                              PutOnScreen($1->string);
+                                               PutOnScreen("\n"); */  }
+                                            }
+                                             if (InChareEnv($1->string,worksymtab))
+                                               writeoutput(CkMyData,NOFREE);
+                                             writeoutput($1->string,NOFREE); 
+                                           }
+                                 DestroyString($1->string);dontfree($1);
+                                 }
+                               }
+               | ID_DCOLON_ID
+                       { if (!InPass1)
+                         { worksymtab=ProcessIdDcolonId($1);
+                           if (IsReadOnly(worksymtab))
+                               writereadonly(worksymtab);
+                           else if (IsChare(worksymtab))
+                                       writechare(worksymtab);
+                                else if (IsFunction(worksymtab))
+                                       writefunction(worksymtab);
+                                     else if (IsAccumulator(worksymtab))
+                                               writeaccname(worksymtab);
+                                          else if (IsMonotonic(worksymtab))
+                                                   writemononame(worksymtab);
+                                               else if (IsTable(worksymtab))
+                                                       writetable(worksymtab);
+                                               else error("Bad Component Ref.",EXIT);
+                           DestroyString($1->modstring);DestroyString($1->string);dontfree($1);
+                         }
+                       }
+               | ID_DCOLON_ID AT IDENTIFIER
+                       { if (!InPass1)
+                         { worksymtab=ProcessIdDcolonId($1);
+                           if (!IsChare(worksymtab))
+                               error("Bad EP Reference",EXIT);
+                         sym2=GlobalEntryFind($3->string,$1->string,$1->modstring);
+                         if (IsPublic(sym2))
+                              writepublic(sym2);
+                         else if (IsEntry(sym2))
+                                   writeentry(sym2);
+                              else if (IsPrivate(sym2))
+                                       writeprivate(sym2);
+                                   else error("Bad Component Ref.",EXIT);
+                         DestroyString($1->modstring);
+                         DestroyString($1->string);dontfree($1);
+                         DestroyString($3->string);dontfree($3);
+                         }
+                       }
+               | IDENTIFIER AT IDENTIFIER
+                       { sym1=GlobalFind($1->string);
+                         sym2=GlobalEntryFind($3->string,$1->string,CurrentModule->name);
+                         if (!(IsChare(sym1)&&(IsPublic(sym2)||IsEntry(sym2))||IsPrivate(sym2)))
+                               error("Bad Reference",NOEXIT);
+                         else  if (IsPublic(sym2))
+                                       writepublic(sym2);
+                               else if (IsEntry(sym2))
+                                       writeentry(sym2);
+                                    else writeprivate(sym2);
+                         DestroyString($1->string);dontfree($1);
+                         DestroyString($3->string);dontfree($3);
+                       }
+               ;
+
+compound_statement     : L_BRACE       { 
+                                         { writeoutput("{",NOFREE);
+                                           PushStack();
+                                         }
+                                       }
+                         decl_list_opt stmt_list_opt R_BRACE
+                                       { 
+                                         { writeoutput("}",NOFREE);
+                                           PopStack(FREE);
+                                           RestoreCurrentTable();
+                                         }
+                                       }
+                       ;
+
+decl_list_opt  : 
+               | decl_list
+               ;
+
+decl_list      : declaration
+               | decl_list declaration
+               ;
+
+stmt_list_opt  :
+               | stmt_list
+               ;
+
+stmt_list      : statement
+               | stmt_list statement
+               ;
+
+statement      : compound_statement
+                | expression SEMICOLON 
+                    {                      /* Feb 18,1991 added by Attila */
+                      if (MULTI_STMT_TR)   /* Accumulate, Newvalue statements*/ 
+                         MULTI_STMT_TR = 0;/* are translated into a block.   */
+                      else                 /* If expression is one of them   */
+                         writeoutput(";",NOFREE); /* don't print semicolon   */
+                    }
+               | IF lparen expression rparen statement 
+               | IF lparen expression rparen statement ELSE statement
+               | WHILE lparen expression rparen statement
+               | DO statement 
+                 WHILE lparen expression rparen                
+               | FOR lparen exp_opt semicolon exp_opt semicolon
+                       exp_opt rparen statement
+               | SWITCH lparen expression rparen statement
+               | CASE expression colon statement
+               | DEFAULT colon statement
+               | BREAK semicolon
+               | CONTINUE semicolon
+               | RETURN semicolon
+               | RETURN expression semicolon
+               | GOTO IDENTIFIER { 
+                                   { writeoutput($2->string,NOFREE);
+                                     DestroyString($2->string);dontfree($2);
+                                   }
+                                 }
+                 semicolon 
+               | IDENTIFIER      { 
+                                    writeoutput($1->string,NOFREE);
+                                   { if (GlobalFind($1->string)!=NULL)
+                                       error("Bad Label",EXIT);
+                                     DestroyString($1->string);dontfree($1);
+                                   }
+                                 }
+                 colon statement
+               | semicolon
+               ;
+
+
+function_decl  : IDENTIFIER    
+                       { int i;
+                         if (export_to_c_flag == 0) {
+                             if (INSIDE_PRIVFUNC_PROTO ==1)
+                               writeoutput(" PROTO_PUB_PRIV ",NOFREE);
+                             else
+                               writeoutput(" static ",NOFREE);
+                          }
+                         if (CurrentChare!=NULL)
+                               writeoutput(Map(CurrentModule->name,CurrentChare
+                                               ->name,$1->string),NOFREE);
+                         else writeoutput($1->string,NOFREE);
+                         worksymtab=FindInTable(CurrentTable,$1->string,&i);
+                         if (i!=0)
+                               worksymtab=Insert($1->string,CurrentTable);
+                         DestroyString($1->string);dontfree($1);
+                         worksymtab->type=SetType(INTPTR);
+                         worksymtab->idtype=FNNAME;
+                         worksymtab->declflag=DECLARED;
+                         PushStack();
+                         SavedFnNode=worksymtab;
+                       }
+                 lparen 
+                       { 
+                            if (PRIVATEFLAG)
+                               writeoutput(CkLocalPtr,NOFREE);
+                       }
+                 parameter_list_opt rparen
+                       { 
+                         { PushStack(); $$=GetYSN();$$->table=SavedFnNode; 
+                         if (PRIVATEFLAG) {
+                         WriteReturn();
+                         writeoutput("void *",NOFREE);
+                         writeoutput(CkLocalPtr,NOFREE);
+                         writeoutput(";",NOFREE); }
+                         }
+                       }
+               | type_spec mopt IDENTIFIER 
+                       { int i;
+                         if (export_to_c_flag == 0) {
+                             if (INSIDE_PRIVFUNC_PROTO==1)
+                               writeoutput(" PROTO_PUB_PRIV ",NOFREE);
+                             else
+                               writeoutput(" static ",NOFREE);
+                          }
+                         if ($2!=NULL) { writeoutput("*",NOFREE);dontfree($2); }
+                         if (CurrentChare!=NULL)
+                               writeoutput(Map(CurrentModule->name,CurrentChare
+                                               ->name,$3->string),NOFREE);
+                         else writeoutput($3->string,NOFREE);
+               /*Attila  worksymtab=FindInTable(CurrentTable,$1->string,&i);*/
+                         worksymtab=FindInTable(CurrentTable,$3->string,&i);
+                         if (i!=0)
+               /* Attila       worksymtab=Insert($1->string,CurrentTable); */
+                               worksymtab=Insert($3->string,CurrentTable);
+                         DestroyString($3->string);dontfree($3);
+                         worksymtab->type=SetType($1->type);dontfree($1);
+                         worksymtab->idtype=FNNAME;
+                         worksymtab->declflag=DECLARED;
+                         PushStack();
+                         SavedFnNode=worksymtab;
+                       }
+                 lparen 
+                       { 
+                           if (PRIVATEFLAG)
+                               writeoutput(CkLocalPtr,NOFREE);
+                       }
+                 parameter_list_opt rparen
+                       { 
+                         { PushStack(); $$=GetYSN();$$->table=SavedFnNode; 
+                         if (PRIVATEFLAG) {
+                         WriteReturn();
+                         writeoutput("void *",NOFREE);
+                         writeoutput(CkLocalPtr,NOFREE);
+                         writeoutput(";",NOFREE); }
+                         }
+                       }
+               ;
+
+mopt           :  MULT { $$=GetYSN(); }
+               | { $$=NULL; }
+               ;
+
+parameter_list_opt     : 
+                       | parameter_list
+                       ;
+
+parameter_list : IDENTIFIER    { 
+                                 { if (PRIVATEFLAG)
+                                       writeoutput(",",NOFREE);
+                                 writeoutput($1->string,NOFREE);
+                                 Insert($1->string,CurrentTable);
+                                 DestroyString($1->string);dontfree($1); 
+                                 }
+                               }
+               | parameter_list comma IDENTIFIER
+                       { 
+                         { writeoutput($3->string,NOFREE);
+                         Insert($3->string,CurrentTable);
+                         DestroyString($3->string);dontfree($3);
+                         }
+                       }
+          /* added by Robert Allan Zeh, 9/19/1993 */
+        | typedef_name IDENTIFIER {
+            { if (PRIVATEFLAG)
+                writeoutput(",", NOFREE);
+              writeoutput($2->string, NOFREE);
+              Insert($2->string, CurrentTable);
+              DestroyString($2->string); dontfree($2); } }
+               ;
+
+function_body  : decl_list_opt
+                 { 
+                   { worksymtab=CurrentTable;
+                   PopStack(NOFREE);
+                       /* Removed by Robert Allan Zeh, 9/20/1993, so that
+               ANSI C type declarations aren't flagged as errors. */
+            /* if (CheckDeclaration(worksymtab,CurrentTable))
+                       error("Bad Parameter List",EXIT);
+                   if (CheckDeclaration(CurrentTable,worksymtab))
+                       error("Bad Parameter List",EXIT); */
+                  FreeTree(CurrentTable);
+                  CurrentTable=StackTop->tableptr=worksymtab;
+                  PushStack();
+                 }
+                }
+                 function_stmt
+                 { 
+                   {
+                   PopStack(FREE);
+                   PopStack(FREE);
+                   RestoreCurrentTable();
+                   }
+                 }
+               ;
+
+function_stmt  : L_BRACE 
+                       { 
+                         { writeoutput("{ ",NOFREE); 
+                         if (PRIVATEFLAG)                
+                               { writeoutput(CurrentChare->name,NOFREE);
+                                 writeoutput(DataSuffix,NOFREE);
+                                 writeoutput(AssignMyDataPtr,NOFREE);
+                                 writeoutput(CurrentChare->name,NOFREE);
+                                 writeoutput(DataSuffix,NOFREE);
+                                 writeoutput(" *)",NOFREE);
+                                 writeoutput(CkLocalPtr,NOFREE);
+                                 writeoutput(";",NOFREE);
+                                  writeoutput(AssignMyID,NOFREE);
+                                  if (CurrentChare->idtype==BOCNAME)
+                                    writeoutput(AssignMyBOC,NOFREE);
+                                  WriteReturn();
+                               }
+                         }
+                       }
+                 decl_list_opt stmt_list_opt R_BRACE
+                       {  writeoutput("}",NOFREE); }
+               ;
+
+exp_opt                :
+               | expression
+               ;
+
+constant       : number