Yacc++ and the Language Objects Library

Copyright © 1997-2004, Compiler Resources, Inc.
Introduction

    Table of Contents

    1. Yacc++(r) is Object-Oriented Successor to Lex and Yacc         1
       1.1. Overview                                                  1
       1.2. For C++ Programmers                                       1
       1.3. Company Information                                       2
       1.4. History of the Software                                   2
       1.5. Yacc++ vs. Lex and Yacc                                   2
       1.6. Customer References                                       3

    2. The Yacc++ Table Generator -- Object-Oriented Features         4
       2.1. Multiple Languages in One Application                     4
       2.2. Lexer and Parser Class Construct                          4
       2.3. AST CONSTRUCT Declaration                                 5
       2.4. Inheritance of Grammars                                   6

    3. The Yacc++ Table Generator -- General Features                 7
       3.1. Unified Syntax                                            7
       3.2. Direct Translation Regular Expressions                    7
       3.3. LR(1) Parsing                                             9
       3.4. INCLUDE Search-Rules and #INCLUDE Declaration             9
       3.5. Large Grammar Support                                     9

    4. The Yacc++ Table Generator -- Lexer Features                  10
       4.1. KEYWORD Declaration                                      10
       4.2. CHARSET ASCII7 and CHARSET ASCII8 Declarations           10
       4.3. DISCARD Symbols                                          11
       4.4. Lexer Non-Terminals                                      11
       4.5. State Specific Defaulting                                11

    5. The Yacc++ Table Generator -- Parser Features                 12
       5.1. PUBLIC Declaration                                       12
       5.2. IGNORE Declaration                                       13
       5.3. REMOVE Declaration                                       14
       5.4. State Based Syntax Assists                               15
       5.5. Shift Action Code                                        16

    6. The Language Objects Library Features                         17
       6.1. Lexer Objects                                            18
            6.1.1. Dynamic Binding                                   18
            6.1.2. Multiple Reentrant Lexer and Parser Objects       18
       6.2. Parser Objects                                           19
            6.2.1. Call-Back Mode                                    19
       6.3. Input Objects                                            20
       6.4. Symbol Table Objects                                     20
       6.5. AST (Abstract Syntax Tree) Objects                       21
       6.6. Error Objects                                            21

    7. Documentation                                                 23
       7.1. The Reference Guide and Sample Applications              23
       7.2. The Tutorial Guide and On-line Examples                  24

    8. Ordering Information                                          25
       8.1. Placing an Order                                         25
       8.2. Contact Information                                      25
       8.3. Pricing                                                  26
       8.4. Current Revision                                         26
       8.5. Platforms/Compilers Supported                            28
       8.6. The Yacc++ Software License Agreement                    29
       8.7. The Yacc++ Customer Contact Sheet                        31

                                                                 Page 1


    +---------------------------------------------------------+
    | 1. Yacc++ is Object-Oriented Successor to Lex and Yacc  |
    +---------------------------------------------------------+   

    +---------------+
    | 1.1. Overview |
    +---------------+

    Yacc++  and  the Language Objects Library from Compiler  Resources,
    Inc.  is  an object-oriented rewrite of lex and yacc which  creates
    C++ classes from grammars.

       - Yacc++  directly  translates regular  expressions  without
         introducing  artificial productions and  produces  minimal
         state LR(1) lexers and parsers.

       - Multiple   lexer  and  parser  objects   can   be   active
         concurrently and are fully reentrant.

       - Automatic  class  generation  for  ASTs  (abstract  syntax
         trees).

       - Multiple inheritance features for modularizing and reusing
         grammars.

       - Grammar  classes  can be dynamically bound  to  lexer  and
         parser objects.

       - Multiple  entry  point  grammars  allow  the  matching  of
         partial parse trees.

       - Lexer  and  parser  objects act  as  call-back  coroutines
         within  Windows(tm),  Motif(tm), and  other  event  driven
         applications.

       - Yacc++  comes  with the Language Objects  Library,  a  C++
         class  library  with  syntactic and semantic  support  for
         building applications.  The library provides base  classes
         which define lexer, parser, input, AST, symbol table,  and
         error objects.

       - Includes  three  ready  to  run  example  applications,  a
         complete  reference  manual, a  comprehensive  developer's
         guide,  sources  to  the  class  library,  and  a  set  of
         tutorials with one hundred sample grammars.


    Yacc++ is a registered trademark of Compiler Resources, Inc.
    Windows is a trademark of Microsoft Corporation.
    Motif is a trademark of The Open Software Foundation, Inc.

    +--------------------------+
    | 1.2. For C++ Programmers |
    +--------------------------+

    Yacc++   and  the  Language  Objects  Library,  Revision  2.x,   is
    specifically  designed for use by programmers using C++.   This  is
    not  just a lex and yacc with C++ class wrappers!!  Yacc++ provides
    options for C++ class generation in many ways:

       - C++  classes  for  lexers and parsers are  generated  from
         grammars.   Grammars can contain lexer  and  parser  class
         constructs   to  further  customize  the  classes   Yacc++
         generates.

       - Optionally, C++ classes can be generated for one  or  more
         tokens in the lexer.

       - Optionally, C++ classes can be generated for one  or  more
         non-terminals in the parser.

       - Optionally, C++ classes can be generated for one  or  more
         alternatives in a parser rule.

    The Language Objects Library is a C++ class library with additional
    support for building your application.

                                                                 Page 2
    +--------------------------+
    | 1.3. Company Information |
    +--------------------------+

    Compiler  Resources, Inc. formed in 1986, develops systems software
    and provides technical consulting services.  The  principal  member
    is Chris Clark.

    +------------------------------+
    | 1.4. History of the Software |
    +------------------------------+   
                                                        April 1994

    Hello Software Developers!

    We are compiler software engineers who have a long history of using
    lexer  and parser generators such as lex and yacc.  It is  probably
    best  described as a "love/hate relationship".  They are  amazingly
    helpful, yet at times very frustrating software tools!

    In  1987,  we were working on prototyping some ideas for  a  syntax
    directed   editor  when  we  realized  we  desperately   needed   a
    replacement for yacc in order to accomplish our goals.  And  so  we
    wrote  newer tools from scratch.  They fit what we needed  and  the
    more  we  thought about it, the more we realized other  programmers
    would have the same needs for updated tools.  This gave us the idea
    to make the tools commercially available.  We named them Yacc++ and
    the  Language Objects Library and after taking the time for  polish
    and documentation, the first commercial release shipped in 1990  on
    the SPARC.

    Almost  immediately, we got requests for Yacc++ on other  platforms
    and  began porting the software.  The PC version was the first port
    and  released  in  1992.  Based on customer feedback  and  our  own
    deepening  understanding,  we  began improving  and  extending  the
    product  and  shipped new releases every year.  It  has  been  very
    exciting for us to see other programmers successfully develop quite
    a variety of applications with Yacc++ over the years.

    The  most  significant change in programming we've noticed  is  the
    overwhelming embrace of C++ for new software development.  Revision
    2.0,  the  1994 release of Yacc++ and the Language Objects Library,
    focuses on those features most requested by C++ programmers.   More
    options  for automated C++ class generation are available  in  this
    release and additional classes were added to the library.

    We  believe  a  powerful and versatile lexer and  parser  generator
    environment  like  Yacc++ is of use to all C++ programmers  at  one
    time  or another.  Yacc++ has been a tremendous help to us  and  we
    hope it will prove useful to you.  Even with Yacc++ in our toolbox,
    we  still  admit  to that "love/hate relationship" with  lexer  and
    parser  generators, but we feel Yacc++ is a significant improvement
    from  its  LALR predecessors like yacc.  We hope you will feel  the
    same way too.

    :-) chris clark

    +------------------------------+
    | 1.5. Yacc++ vs. Lex and Yacc |
    +------------------------------+

    Lex  and Yacc were written by Lesk and Johnson at AT&T in the  mid-
    70's.    They  were  tools  matched  to  the  software  development
    environment of their time which was oriented towards building small
    single  purpose applications for linking together.  The environment
    was  based on the C language, structured programming concepts,  and
    I/O  via  UNIX character streams.  The tools focused on  automating
    the  syntax development of a language only.  Lex and yacc are still
    available  on  UNIX  and other systems today, but  are  essentially
    unchanged.

                                                                 Page 3

    Yacc++  and  the Language Objects Library supersedes  the  standard
    UNIX  utilities lex and yacc, combining the functionality  of  both
    utilities  in  one  tool and adding semantic  support.   Yacc++  is
    designed for C++ programmers working in an object-oriented software
    development  environment and is suitable  for  developing  a  wider
    variety  of  applications  than  its  predecessors.   The  numerous
    extensions are presented throughout this document.

    Please  note that Yacc++ is a complete rewrite of yacc and although
    it  is  similar, it is not strictly upwardly compatible  with  yacc
    grammars.  [A chapter describing the conversion of yacc grammars to
    Yacc++  is included in the Yacc++ and the Language Objects  Library
    Reference Guide].


    +--------------------------+
    | 1.6. Customer References |
    +--------------------------+

    Yacc++ and the Language Objects Library is in use by C++ developers
    throughout  the  world.   Here is what customers  have  said  about
    Yacc++ --

        "After using lex/yacc on Unix and then moving to Yacc++ 
         on Windows NT, there's no comparison at all.  Yacc++ 
         provides many additional support methods and parsing/lexing 
         shortcuts that make it a joy to use compared to lex/yacc.  
         When you through in the fact that it is a full C++ class 
         library, you've got a very powerful tool."

                           Chris J. Martinez
                          Coulter Corporation
                      http://www.fiu.edu/~martinec

         "Yacc++ is great.  Fabulous manual, very powerful, best parser
          generator I've ever seen (even better than PCCTS, which is
          pretty darned good).  Well supported.  Very expensive."

                          Dwight VandenBerghe 
                         Pentasoft Corporation
                Recommendation for a WinNT/95 parser generator
                        Newsgroups: comp.compilers
                    Date: 30 Aug 1997 00:51:18 -0400
                         dwight@pentasoft.com

        "I want to congratulate Compiler Resources on a great product. 
      I started development with Yacc++ and the Language Objects Library
      in 1992 using Borland C++ under Windows and I've been quite happy
      with it.  It wasn't easy to develop our software with Yacc++, but
      it would have been impossible with any other product I've seen".

                               Mike Giroux
                              SYNTELL, Inc.
                              Charny, Quebec

        "I think Compiler Resources did a great job with the overall 
         design of Yacc++.  I like it very much.  I have successfully 
         used it within a Microsoft Visual C++ built MFC application".

                                Roy Sprowl 
                         Swfte Development Center 
                               Kirkland, WA 

         "Our move from yacc to Yacc++ has been as beneficial as our
           transition from C to C++.  Yacc++ is a tool that enables
         developers to concentrate on designing and building software
        rather than wrestling with hacks and kludges.  Yacc++ allows us
       to make the implementation of a language as elegant as its design".

                                Paul Ambrose 
                            Quintus Corporation
                               Palo Alto, CA

              "Yacc++ and the Language Objects Library is an
          avant-garde piece of technology by a responsive team".

                                J.L. Leroy
                            CETRAD Informatique
                             Brussels, Belgium

            "Yacc++ is a nice product that removes most of the
                    long-standing problems with yacc".

                              James Rumbaugh
                        Modeling and Design Column
            Let there be objects: a short guide to reification
                  Journal of Object-Oriented Programming
                          November/December 1992

     "Yacc++ and the Language Objects Library is a comprehensive suite
     of language processing tools.  If you've used lex and yacc in the
     past, you will find that Yacc++ and the Language Objects Library
                     offer substantial improvements".

                               David Koosis
       Parsing with class:  Yacc++ and the Language Objects Library
                                C++ Report
                               Nov-Dec 1992

                                                                 Page 4

    +-----------------------------------------------------------+
    | 2. The Yacc++ Table Generator -- Object-Oriented Features |
    +-----------------------------------------------------------+

    The  following  sections provide an overview of the object-oriented
    features in Yacc++.

    +--------------------------------------------+
    | 2.1. Multiple Languages in One Application |
    +--------------------------------------------+

    Yacc++  grammars  are  comprised of Yacc++ grammar  classes.   Each
    class  contains  a  lexer and/or parser and  begins  with  a  CLASS
    declaration  which Yacc++ uses to determine the  name  of  the  C++
    class  it  generates.   Classes provide the  scoping  which  allows
    lexers  and  parsers for multiple languages to be used  within  one
    application.

    +---------------------------------------+
    | 2.2. Lexer and Parser Class Construct |
    +---------------------------------------+

    The  class construct is used to customize the classes generated for
    your  lexer  and  parser.   Example 1 specifies  a  NAME  field  to
    override  the  default  naming rules Yacc++  uses  when  generating
    parser  classes.   The DESTRUCTOR class field specifies  additional
    code  for Yacc++ to output in the destructor for this parser class.
    In  this example, the lexer object is to be deleted when the parser
    object  is  destroyed.   Other  parser  class  construct  modifiers
    include  changing the base class to derive from, adding  additional
    data  members,  adding  code to the constructor  initializer  list,
    constructor body, or dump member functions.  (Likewise,  the  lexer
    class construct is available for the lexer).

      +----------------------------------------------------------------+
      |                                                                |
      |  class example;                                                |
      |                                                                |
      |  lexer                                                         |
      |                                                                | 
      |  parser ::   // customize the class generated for this parser  |
      |                                                                |
      |        name  example_parser                                    |
      |                                                                |
      |        destructor  { delete yy_this_lex_obj; }                 |
      |        ;                                                       |
      |                                                                |
      +----------------------------------------------------------------+

               Example 1:  Class Construct following Parser

                                                                 Page 5

    +--------------------------------+
    | 2.3. AST CONSTRUCT Declaration |
    +--------------------------------+

    AST   CONSTRUCT  declarations  define  classes  for  tokens,   non-
    terminals,   and   non-terminal   alternatives.    BASE   CONSTRUCT
    declarations  define  classes  to  use  as  base  classes.   Yacc++
    generates classes for each CONSTRUCT or BASE CONSTRUCT declaration.
    Yacc++ also generates the appropriate code to construct objects  of
    the   classes  when  the  tokens,  non-terminals,  or  non-terminal
    alternatives are recognized.  The model used in Yacc++ was inspired
    by  Yacc Meets C++, by Stephen Johnson [Computing Systems, Vol.  I,
    No. 2, Spring 1988].

    Example  2  shows  some  simple  CONSTRUCT  declarations  for  tree
    building  for  a  calculator  which supports  variables.   The  AST
    objects are constructed as the expressions are lexed and parsed.

      +----------------------------------------------------------------+
      |                                                                |
      |  class example;   // simple construct declarations             |
      |                                                                |
      |  lexer                                                         |
      |                                                                |
      |  construct   identifier :: symbol                              |
      |        base { public base_class }                              |
      |        member {                                                |
      |            public:                                             |
      |                int value();                                    |
      |            }                                                   |
      |        ;                                                       |
      |                                                                |    
      |  . . .                                                         |
      |                                                                |
      |  parser                                                        |
      |                                                                |      
      |  base construct  base_class                                    |
      |        member {                                                |
      |            public:                                             |
      |                int value() = 0;                                |
      |            }                                                   |
      |        ;                                                       |
      |                                                                |
      |  construct   expression :: infix                               |
      |        base { public base_class }                              |
      |        member {                                                |
      |            public:                                             |
      |                int value();                                    |
      |            }                                                   |
      |        ;                                                       |
      |                                                                |
      |  . . .                                                         |
      |                                                                |
      |  expression  :  identifier "+" identifier                      |
      |              ;                                                 |
      |                                                                |
      +----------------------------------------------------------------+

                         Example 2:  AST CONSTRUCT

                                                                 Page 6
    +------------------------------+
    | 2.4. Inheritance of Grammars |
    +------------------------------+

    Yacc++  supports multiple inheritance of grammars using  the  CLASS
    declaration  and the FROM statement.  New grammars may  be  derived
    from one or more base grammar classes.

    Example 3 shows two class grammars.  Language_2 is a derived  class
    which uses language_1 as a base class.  Language_2 defines the same
    grammar  as  language_1  except the IF  statement  was  changed  to
    support an optional ELSE clause.

      +----------------------------------------------------------------+
      |                                                                |     
      |  virtual  class  language_1;  // base grammar                  |
      |                                                                |      
      |  lexer                                                         |
      |                                                                | 
      |  discard token    whitespace;                                  |
      |  token            identifier  constant;                        |
      |  keyword          while  if;                                   |
      |                                                                |      
      |  construct   identifier :: keyword;                            |
      |                                                                |      
      |  identifier  :  ('a' .. 'z' | 'A' .. 'Z')+ ;                   |
      |                                                                |     
      |  constant    :  '0' .. '9' + ;                                 |
      |                                                                |      
      |  whitespace  :  (' ' | '\t' | '\n')+ ;                         |
      |                                                                |      
      |  parser                                                        |
      |                                                                |      
      |  program     :   block+ ;                                      |
      |                                                                |      
      |  block       :   '{'  statement*  '}' ;                        |
      |                                                                |      
      |  statement   :   assignment  |  if_stmt  |  while_stmt ;       |
      |                                                                |      
      |  assignment  :   identifier  '='  expression ;                 |
      |                                                                |      
      |  if_stmt     :   if  expression  block ;                       |
      |                                                                |      
      |  while_stmt  :   while  expression  block ;                    |
      |                                                                |      
      |  expression  :   ...                                           |
      |                                                                |     
      |                                                                |     
      |  class  language_2  from  language_1;  // derived grammar      |
      |                                                                |     
      |  lexer                                                         |
      |                                                                |     
      |  keyword     else ;                                            |
      |                                                                |     
      |  parser                                                        |
      |                                                                |     
      |  if_stmt     :  if  expression  block  (else  block)? ;        |
      |                                                                |
      +----------------------------------------------------------------+

                     Example 3:  Yacc++ Class Grammar

                                                                 Page 7

    +---------------------------------------------------+
    | 3. The Yacc++ Table Generator -- General Features |
    +---------------------------------------------------+   

    The  following  sections provide an overview of  the  new  features
    common to generating both lexers and parsers using Yacc++.

    +---------------------+
    | 3.1. Unified Syntax |
    +---------------------+

    Lex  and  yacc  are distinct utilities which differ in  syntax  and
    style.   Lexers and parsers are defined in separate files  and  lex
    and yacc are invoked in separate steps.

    The  Yacc++ lexer and parser generator accepts the same syntax  and
    style in the lexer and parser sections.  Lexers and parsers may  be
    generated at the same time or in separate steps.

    +---------------------------------------------+
    | 3.2. Direct Translation Regular Expressions |
    +---------------------------------------------+

    The  unified  Yacc++  syntax combines regular expressions  with  LR
    grammars in both the lexer and parser.  Regular expressions provide
    a   compact   representation  for  writing  grammars   with   fewer
    productions.   Yacc++ directly translates regular  expressions  for
    efficiency.   Compare the following small grammar fragment  written
    for  both  Yacc++  and  yacc.  The grammar represents  a  contrived
    language for:

       - Declarations  with  lists of one or  more  variable  names
         optionally separated by commas and terminated by  a  semi-
         colon.

       - Zero  or  more declarations permitted before  the  keyword
         PROGRAM.

      +----------------------------------------------------------------+   
      |                                                                |
      |  lang     :   dcls  PROGRAM  ;                                 |
      |                                                                |     
      |  dcls     :   /* empty */                                      |
      |           |   dcls  dcl                                        |
      |           ;                                                    |
      |                                                                |     
      |  dcl      :   INT  var_list  ';'                               |
      |           |   FLOAT  var_list ';'                              |
      |           ;                                                    |
      |                                                                |     
      |  var_list :   variable                                         |
      |           |   var_list  variable                               |
      |           |   var_list  COMMA  variable                        |
      |           ;                                                    |
      |                                                                |
      +----------------------------------------------------------------+   

                   Example 4:  Test Case : yacc Version

                                                                 Page 8

      +----------------------------------------------------------------+   
      |                                                                |
      |  lang  :   dcl*  PROGRAM  ;                                    |
      |                                                                |     
      |  dcl   :   INT  variable  (COMMA?  variable)*  ';'             |
      |        |   FLOAT  variable  (COMMA?  variable)*  ';'           |
      |        ;                                                       |
      |                                                                |
      +----------------------------------------------------------------+   

                  Example 5:  Test Case : Yacc++ Version

    Direct  translation of regular expressions reduces  the  number  of
    parser non-terminals and states in the Yacc++ grammar.  There is  a
    side  by  side  grammar comparison with statistics  in  The  Domino
    Effect: Parsing and Lexing Objects with Yacc++ [SunWorld, May 1991,
    page 86].

    -------------------------------
    Semantic Value Member Functions
    -------------------------------

    The regular expression extensions give Yacc++ a dynamic action code
    model  as  opposed  to  the static model  in  yacc.   With  Yacc++,
    information  needed for semantic processing may  not  be  known  at
    build  time.   The  yacc pre-counted $1, $2...  $i  semantic  value
    references are insufficient.  Yacc++ provides semantic value member
    functions to support the dynamic action code model.

    +------------------------------------------------------------------------+
    |                        PARSER MEMBER FUNCTIONS                         |
    +------------------------------------------------------------------------+
    |                                                                        |
    | yy_psr_last()  returns the number of symbols shifted in the production |
    |                                                                        |
    | yy_psr_ref(i)  accesses the result of a specific symbol                |
    |                (corresponds to the $1, $2, $i in yacc)                 |
    |                                                                        |
    | yy_psr_rslt()  passes data from one production to another at runtime   |
    |                (corresponds to $$ in yacc)                             |
    |                                                                        |
    | yy_psr_type(i) returns the type of the symbol for entry "i" in         |
    |                the parse stack                                         |
    |                                                                        |
    +------------------------------------------------------------------------+
    |                        LEXER MEMBER FUNCTIONS                          |
    +------------------------------------------------------------------------+
    |                                                                        |
    | yy_lex_char(i)  returns the character indexed by "i"                   |
    |                                                                        |
    | yy_lex_discard() suppresses the passing of the token to the parser     |
    |                                                                        |
    | yy_lex_len()    returns the number of characters shifted in the token  |
    |                                                                        |
    | yy_lex_rdc()    provides for the checking or setting of the token type |
    |                                                                        |
    | yy_lex_rslt()   passes auxiliary data from the lexer to the parser     |
    |                                                                        |
    | yy_lex_token()  returns the pointer to the start of the current token  |
    |                                                                        |
    +------------------------------------------------------------------------+

                Figure 1:  Semantic Value Member Functions

                                                                 Page 9
    +--------------------+
    | 3.3. LR(1) Parsing |
    +--------------------+   

    Yacc++  supports  minimal  state  LR(1)  rather  than  LALR   table
    generation.  This means Yacc++ accepts a wider class of definitions
    than  yacc.  Yacc++ can also be directed to restrict itself to LALR
    table generation.

    Minimal  state LR tables are the same size as LALR tables for  LALR
    languages.  This means Yacc++ tables have no more states than  yacc
    tables for languages yacc can process.

    Example  6 shows a grammar which is LR(1) but not LALR(1).   Yacc++
    will  correctly  process  this language  definition.   LALR  parser
    generators  like  yacc  will give an error  and  produce  incorrect
    tables.

      +----------------------------------------------------------------+  
      |                                                                |     
      |  class example;  // LR(1) grammar                              |
      |                                                                |     
      |  lexer                                                         |
      |                                                                |     
      |  token       proc_name  macro_name  var_name ;                 |
      |                                                                |     
      |  parser                                                        |
      |                                                                |      
      |  sentence    :  proc_name  argument  "."                       |
      |              |  proc_name  parameter  ";"                      |
      |              |  macro_name  argument  ";"                      |
      |              |  macro_name  parameter  "."                     |
      |              ;                                                 |
      |                                                                |      
      |  argument    :  var_name ;                                     |
      |                                                                |      
      |  parameter   :  var_name ;                                     |
      |                                                                |     
      +----------------------------------------------------------------+   

           Example 6:  Yacc++ LR(1) Grammar Which is Not LALR(1)

    +----------------------------------------------------+
    | 3.4. INCLUDE Search-Rules and #INCLUDE Declaration |
    +----------------------------------------------------+

    Yacc++ supports the modularization of grammars by allowing grammars
    to  be  included via the #INCLUDE declaration.  As with modern  day
    compilers,  Yacc++ accepts include search-rules  which  specify  an
    ordered list of directories in which to search for the includes.

    +---------------------------+
    | 3.5 Large Grammar Support |
    +---------------------------+   

    Yacc++  imposes no artificial constraints on the size of a  grammar
    it  can  process.  Yacc++ uses allocated memory for any data  which
    depends  on  the input grammar.  As long as your system has  enough
    memory, Yacc++ will continue to allocate space as needed.  Grammars
    which  are  too large for certain yacc implementations  will  build
    with Yacc++.

                                                                 Page 10
    +--------------------------------------------------+
    |  4. The Yacc++ Table Generator -- Lexer Features |
    +--------------------------------------------------+

    The  following  sections provide an overview of  the  new  features
    specific to generating lexers in Yacc++ as compared with lex.

    +--------------------------+
    | 4.1. KEYWORD Declaration |
    +--------------------------+

    Yacc++  supports  the  KEYWORD  declaration in the lexer for  auto-
    matically  defining  case sensitive or  case  insensitive keywords.  
    The  SUBSTR  KEYWORD  declaration   provides  support  for  minimal
    substring  matching of keywords.  Example 7 declares  the  keywords
    char,  int,  and float.  The keywords are referenced as char,  int,
    and float in the parser rule for type.  Any unique substring in the
    input  will  match  the keyword (for example "c"  for  char).   The
    CONSTRUCT  declaration for the identifier token  causes  Yacc++  to
    generate code which does a keyword lookup whenever an identifier is
    recognized.

      +----------------------------------------------------------------+   
      |                                                                |
      |  class example;  // KEYWORD declaration                        |
      |                                                                |     
      |  lexer                                                         |
      |                                                                |     
      |  sensitive keyword;                                            |
      |                                                                |     
      |  substr keyword  char  int  float;                             |
      |  token           identifier  comma;                            |
      |  discard token   white_space;                                  |
      |                                                                |     
      |  construct       identifier ::  keyword;                       |
      |                                                                |     
      |  identifier  :  'a' .. 'z' + ;                                 |
      |                                                                |      
      |  comma       :  ',' ;                                          |
      |                                                                |      
      |  white_space :  (' ' | '\t' | '\n')+ ;                         |
      |                                                                |      
      |  parser                                                        |
      |                                                                |      
      |  declaration :  type  var_list ;                               |
      |                                                                |      
      |  type        :  char  |  int  |  float ;                       |
      |                                                                | 
      |  var_list    :  identifier  (comma  identifier)* ;             |
      |                                                                |
      +----------------------------------------------------------------+   

                           Example 7:  Keywords

    +-----------------------------------------------------+
    | 4.2. CHARSET ASCII7 and CHARSET ASCII8 Declarations |
    +-----------------------------------------------------+

    Yacc++  supports lexing of American or European character sets  via
    the CHARSET declaration in the lexer.  The default for Yacc++ is to
    generate  a lexer which processes the characters from 0 to  127  in
    the   ASCII  character  set.   By  specifying  the  CHARSET  ASCII8
    declaration,  Yacc++  will  generate a lexer  which  processes  the
    characters from 0 to 255.

                                                                 Page 11
    +----------------------+
    | 4.3. DISCARD Symbols |
    +----------------------+

    Yacc++  supports  DISCARD TOKEN declarations  and  DISCARD  KEYWORD
    declarations  in  the  lexer  for  symbols  which  the  lexer  will
    recognize, but not pass to the parser.  Discard declarations  allow
    the  lexer  to conveniently process text which is easily recognized
    and syntactically irrelevant such as comments.

    +--------------------------+
    | 4.4. Lexer Non-Terminals |
    +--------------------------+

    Yacc++  supports non-terminals and intermediate productions in  the
    lexer  as well as the parser.  Lexer non-terminals are intermediate
    groupings  of characters in the definition of a token.  Lexer  non-
    terminals  are  not visible to the parser.  They are  visible  only
    within   the   lexer.   Lexer  non-terminals  can  have   recursive
    definitions  as is shown in Example 8 which defines  comments  that
    can nest.

      +-------------------------------------------------------------------+   
      |                                                                   |
      |  class example;  // nested comment definition                     |
      |                  // with lexer non-terminal                       |
      |  lexer                                                            |
      |                                                                   |   
      |  discard token   comment;                                         |
      |                                                                   |   
      |  comment         :  nested_comment ;                              |
      |                                                                   |   
      |  nested_comment  : "/*" ( ( @  |  nested_comment )* "*" )+ "/" ;  |
      |                                                                   |
      +-------------------------------------------------------------------+

                  Example 8:  Yacc++ Lexer Non-terminals

    +--------------------------------+
    | 4.5. State Specific Defaulting |
    +--------------------------------+

    Yacc++ supports state specific defaulting represented by the at "@"
    character.   This is a generalization of the dot "."  character  in
    lex  which  matches any character.  The "@" character  matches  any
    character  which  is otherwise not matched in the current  context.
    The  meaning  of the "@" character is re-evaluated  in  each  lexer
    state  where  it is used.  Example 9 is a comment definition  which
    matches  ANSI  C comments.  Without the state specific  defaulting,
    the rule would be more complicated.

      +----------------------------------------------------------------+   
      |                                                                |     
      |  class example;  // ANSI C comment definition with @           |
      |                                                                |     
      |  lexer                                                         |
      |                                                                |     
      |  discard token   comment;                                      |
      |                                                                |     
      |  comment         : "/*" ( ( @ )* "*" )+  "/" ;                 |
      |                                                                |     
      +----------------------------------------------------------------+   

               Example 9:  Yacc++ State Specific Defaulting

                                                                 Page 12

       The Yacc++ Table Generator -- Parser Features

    The  following  sections provide an overview of  the  new  features
    specific to generating parsers in Yacc++ as compared with yacc.

    +-------------------------+
    | 5.1. PUBLIC Declaration |
    +-------------------------+   

    Yacc++  supports  multiple  entry  point  parsing  via  the  PUBLIC
    declaration.   Example 10 shows the use of a PUBLIC declaration  to
    make  the  symbols  declaration, statement, expression,  and  block
    entry points to the parser tables in the class for the grammar  for
    a  translation_unit.  Parser tables are generated which  can  parse
    only  a  declaration, statement, expression, block as  well  as  an
    entire translation_unit.  At execution time the desired sequence is
    selected  by  passing either declaration_, statement_, expression_,
    block_,  or translation_unit_ as the entry point parameter  to  the
    constructor  when creating the parser object.  If  a  zero  (0)  is
    passed, the start symbol is parsed.

      +----------------------------------------------------------------+   
      |                                                                |
      |  class example;    // PUBLIC declaration                       |
      |                                                                |     
      |  lexer                                                         |
      |                                                                |     
      |  . . .                                                         |
      |                                                                |     
      |  parser                                                        |
      |                                                                |     
      |  start   translation_unit;                                     |
      |                                                                |     
      |  public  declaration, statement, expression, block;            |
      |                                                                |     
      |  translation_unit :  program name parameters block ;           |
      |                                                                |     
      |  block            :  begin declaration* statement* end ;       |
      |                                                                |     
      |  declaration      :  type name equals type_definition ;        |
      |                                                                |     
      +----------------------------------------------------------------+   

                      Example 10:  PUBLIC Declaration

                                                                 Page 13
    +-------------------------+
    | 5.2. IGNORE Declaration |
    +-------------------------+

    Yacc++  provides the IGNORE declaration for allowing the parser  to
    discard  text  which is syntactically irrelevant but too  difficult
    for  the  lexer  to  recognize  such as  pre-processor  statements.
    Ignore  items are recognized and shifted, but are not added to  the
    parse stack and the parser state remains unchanged.

    Ignore  processing can also be context dependent.  An ignored  item
    can  be  referenced in specific contexts.  This allows items  which
    may  appear  anywhere  in the input text but are  required  in  the
    mentioned contexts.  A typical example is the whitespace which must
    appear  after an identifier in a #define statement.  In example  11
    the  define_stmt  is  a  pre-processor statement  which  can  occur
    anywhere  in the text.  Whitespace can also occur anywhere  in  the
    input  text,  but  whitespace  must separate  the  first  id  of  a
    define_stmt from the rest.

      +----------------------------------------------------------------+      
      |                                                                |     
      |  class example;  // IGNORE declaration                         |
      |                                                                |      
      |  lexer                                                         |
      |                                                                | 
      |  token       equal  id  whitespace ;                           |
      |                                                                |      
      |  keyword     char  define  int ;                               |
      |                                                                |      
      |  equal       :  "="  ;                                         |
      |                                                                |      
      |  id          :  ("a" .. "z")+  ;                               |
      |                                                                |      
      |  whitespace  :  (" " | "\n")+  ;                               |
      |                                                                |      
      |  parser                                                        |
      |                                                                |      
      |  ignore      define_stmt  whitespace ;                         |
      |                                                                |      
      |  language    :  dcl_stmt+  exec_stmt* ;                        |
      |                                                                |      
      |  dcl_stmt    :  (char | int)  id ;                             |
      |                                                                |      
      |  exec_stmt   :  id  equal  id ;                                |
      |                                                                |      
      |  define_stmt :  "#"  define  id  whitespace  id* ;             |
      |                                                                |     
      +----------------------------------------------------------------+     

                      Example 11:  IGNORE Declaration


                                                                 Page 14
    +-------------------------+
    | 5.4. REMOVE Declaration |
    +-------------------------+

    Yacc++  provides the REMOVE declaration for declaring  items  which
    are  shifted,  but not placed on the parse stack.  In  contrast  to
    ignore  items,  the  parser  state  is  changed.   This  simplifies
    semantic  processing by eliminating tokens which  are  semantically
    (but not syntactically) irrelevant.

    The  example below shows the use of the REMOVE declaration for  the
    top  level  parser non-terminals cmd and replace_cmd.   Example  12
    also shows the use of the REMOVE declaration for the keywords:  IN,
    REPLACE,  OR, and WITH.  Removing these tokens allows the  embedded
    code to refer to only the file_name and string tokens.

      +----------------------------------------------------------------+   
      |                                                                |     
      |  class example;  // REMOVE declaration                         |
      |                                                                |      
      |  lexer                                                         |
      |                                                                |      
      |  keyword         IN  OR  REPLACE  WITH ;                       |
      |  token           file_name  string ;                           |
      |                                                                |  
      |  parser                                                        |
      |                                                                |      
      |  local     { int  i, replacement; }                            |
      |  global    {#include "yy_sym.h"}                               |
      |  union     {  yy_sym_ptr   as_sym_ptr;                         |
      |               char         *as_char_ptr; }                     |
      |                                                                |      
      |  remove       cmd_stream  replace_cmd ;                        |
      |  remove       IN  OR  REPLACE  WITH ;                          |
      |                                                                |      
      |  cmd_stream   :  replace_cmd+;                                 |
      |                                                                |      
      |  replace_cmd  :  REPLACE  string  (OR?  string)*               |
      |                  WITH  string  (IN?  file_name)?  ;            |
      |                                                                |     
      |  { if (yy_psr_type(yy_psr_last()) == file_name_) {             |
      |        set_file(yy_psr_ref(yy_psr_last()).as_sym_ptr);         |
      |        replacement = yy_psr_last() - 1;                        |
      |        }                                                       |
      |    else {                                                      |
      |        replacement = yy_psr_last();                            |
      |        }                                                       |
      |    for (i = 1; i < replacement; ++i) {                         |
      |        replace(yy_psr_ref(i).as_char_ptr,                      |
      |                yy_psr_ref(replacement).as_char_ptr);           |
      |        }                                                       |
      |  }                                                             |
      |                                                                |     
      +----------------------------------------------------------------+   

                      Example 12:  REMOVE Declaration

                                                                 Page 15

    +---------------------------------+
    | 5.4. State Based Syntax Assists |
    +---------------------------------+

    Yacc++ optionally generates parser state based syntax assist tables
    for  error  diagnostics.  With syntax assists, at the  time  of  an
    error,  the  legal  expected values and one or more  syntax  assist
    messages will be displayed.

    Figure 2 shows the various components of Yacc++ syntax assists.

       - The  top box shows the use of the  prefix  in  the
         input  grammar.   The application built  from  this  input
         grammar will display syntax assist 11 if there is a syntax
         error while parsing the start_stmt.

       - The  second box shows the syntax assist file which is  the
         input to the syntax assist builder tool yy_stbl.

       - The  third box shows an illegal start statement which will
         cause  the  application to report the syntax  error  along
         with  the expected value and syntax assist message  11  as
         shown in the bottom box.

      +----------------------------------------------------------------------+
      |                                                                      |
      |  parser       // <11> is the syntax assist prefix number             |
      |                                                                      |
      |  start_stmt   :  <11>  START  identifier  ";" ;                      |
      |                                                                      |
      +----------------------------------------------------------------------+
      |                                                                      |
      |  // yy_synas: syntax assists                                         |
      |                                                                      |
      |  11 START identifier ; where identifier is a parser non-terminal     |
      |                                                                      |
      +----------------------------------------------------------------------+
      |                                                                      |
      |  // example -- erroneous start statement                             |
      |                                                                      |
      |  start 10 ;                                                          |
      |                                                                      |
      +----------------------------------------------------------------------+
      |                                                                      |
      |  "example", line 3 : error 100 : SYNTAX ERROR while processing "10"  |
      |                                                                      |
      |  Expected... identifier                                              |
      |                                                                      |
      |    -->  START identifier ; where identifier is a parser non-terminal |
      |                                                                      |
      +----------------------------------------------------------------------+

                         Figure 2:  Syntax Assist

                                                                 Page 16   

    +------------------------+
    | 5.5. Shift Action Code |
    +------------------------+

    Yacc++ supports shift action code in addition to reduce action code
    for  semantic processing.  Shift action code is embedded  within  a
    production.  Yacc++ shift action code is executed after the  shift.
    This  differs from yacc which creates an artificial production  and
    attaches  the  actions to the reduce of the artificial  production.
    Eliminating these artificial productions decreases the size of  the
    parser tables.

    Example  13  shows placement of shift action code  in  relation  to
    regular expression operators.  The action code in list1 is executed
    after  the  last name in the list of one or more names is  shifted.
    The action code in list2 is executed after each name in the list of
    one or more names is shifted.

      +----------------------------------------------------------------+   
      |                                                                |     
      |  class example;  // shift action code                          |
      |                                                                |     
      |  lexer                                                         |
      |                                                                |     
      |  token    name  comma;                                         |
      |                                                                |     
      |  parser                                                        |
      |                                                                |      
      |  grammar  :  list1  comma  list2 ;                             |
      |                                                                |      
      |  list1    :  name + { cout << "At end" << endl; } ;            |
      |                                                                |      
      |  list2    :  (name { cout << "Each time" << endl; } )+ ;       |
      |                                                                |    
      +----------------------------------------------------------------+     

          Example 13:  Shift Semantic Action Code in Parser Rules

                                                             Page 17   

+------------------------------------------+                                 
| 6. The Language Objects Library Features |
+------------------------------------------+                                 
   
The  Language Objects Library is a C++ class library with syntactic
and  semantic  support for your application.  The library  provides
classes which define the following types of objects:

   - Lexer   and   parser  objects  provide  the  engines   for
     processing  your language classes.  Each lexer and  parser
     object  acts  as a reentrant coroutine for processing  one
     input  stream.  Multiple lexer and parser objects  can  be
     concurrently active.
     
   - Input   objects  supports  several  I/O  models  including
     reading from C++ streams, UNIX files, strings, and C I/O.
     
   - Symbol   table  objects  allow  parser  objects  to   have
     independent  (or shared) symbol tables.  Member  functions
     include   hashing  and  symbol  lookup.   Symbol   objects
     encapsulate  meanings of individual  tokens  and  includes
     built in keyword support.
     
   - AST  objects  allow  construction of an (abstract  syntax)
     tree   which  represents  the  input  which  was   parsed.
     Application  specific  sub-classes of  these  objects  are
     automatically derived via the CONSTRUCT declaration in the
     grammar.
     
   - Error  objects  support customizable error  reporting  and
     context sensitive syntax assists.
     
Figure  3  shows the inter-connection of the various objects  in  a
typical Yacc++ application.

       +------------+
       |   input    |
       |   object   |
       +------------+
             |    +------------+
             +----|   lexer    |
                  |   object   |
                  +------------+
                        |    +------------+
                        +----|   symbol   |
                        |    |   table    |
                        |    |   object   |
                        |    +------------+
                        |    |   symbol   |
                        |    |   objects  |
                        |    +------------+
                        |
                        |    +------------+
                        +----|   parser   |
                        |    |   object   |
                        |    +------------+
                        |          |
                        |          |    +------------+
                        |          +----|    AST     |
                        |          |    |  objects   |
                        |          |    +------------+
                        +----------+
                        |
                  +------------+
                  |   error    |
                  |   object   |
                  +------------+
                                 
               Figure 3:  Runtime Object Connections
                                 
                                                             Page 18   
+--------------------+
| 6.1. Lexer Objects |
+--------------------+
   
Lexer  objects implement the lexers described in the grammar.   The
lexer  classes  are  generated by Yacc++ from your  grammars.   The
generated  classes  are  derived from  the  lexer  classes  in  the
library.   All  of  the grammar specific code is generated  in  the
derived lexer classes.  The lexing engine and other common code  is
contained  in  the library base classes and is shared  between  all
lexers in an application.

Different  lexer  base  classes  provide  different  table  packing
mechanisms.

                            +------------------+
                            |   buffer class   |
                            +------------------+
                                     |
                                     | derives
                                     |
                          +-----------------------+
                          |        lexer          |
                          |  abstract base class  |
                          +-----------------------+
                                     |
                                     | derives
                                     |
        +-------------------------------------------------------+
        |                 |                  |                  |
+---------------+ +-----------------+ +----------------+ +---------------+
|  lexer class  | |   lexer class   | |  lexer class   | |  lexer class  |
|  fast tables  | | readable tables | |  small tables  | |   lex lexer   |
+---------------+ +-----------------+ +----------------+ +---------------+
        |                 |                  |                  |
        +-------------------------------------------------------+
                                     |
                                     | one of them derives
                                     |
                      +-----------------------------+
                      |  generated lexer class(es)  |
                      |      from your grammar      |
                      +-----------------------------+
                                 
                      Figure 4:  Lexer Class Hierarchy
                                 
+------------------------+
| 6.1.1. Dynamic Binding |
+------------------------+

The  grammar  class for lexer and parser objects built with  Yacc++
can be changed at execution time.  The entry point into the grammar
can  also be changed at execution time.  This allows an application
to  dynamically  determine the rules for the language  or  language
fragment to be used for the parse.

Another  common use of dynamic binding is to switch  lexer  classes
during  the parse.  This provides the functionality of lexer states
in lex.

+----------------------------------------------------+
| 6.1.2. Multiple Reentrant Lexer and Parser Objects |
+----------------------------------------------------+

Yacc++ supports multiple reentrant lexer and parser objects  via  a
coroutine model.  Multiple lexer and parser objects may be created.
The  objects  can  either  lex  and parse  the  same  or  different
languages.   Each  object is independent and  the  objects  can  be
executed  concurrently.   The member functions  yy_lex_pause()  and
yy_lex_resume()  allow  processing  to  be  suspended  per   object
allowing the parsing from different sources to be interleaved  even
within a single process or task.

                                                             Page 19   
+---------------------+
| 6.2. Parser Objects |
+---------------------+
   
Parser objects implement the parsers described in the grammar.  The
parser  classes  are generated by Yacc++ from your  grammars.   The
generated  classes  are  derived from the  parser  classes  in  the
library.   All  of  the grammar specific code is generated  in  the
derived  parser classes.  The parsing engine and other common  code
is  contained in the library base classes and is shared between all
parsers in an application.

Different  parser  base  classes provide  different  table  packing
mechanisms.

                      +------------------------+
                      |        parser          |
                      |  abstract base class   |
                      +------------------------+
                                  |
                                  | derives
                                  |
        +-------------------------------------------------+
        |                         |                       |
+----------------+      +------------------+      +----------------+
|  parser class  |      |   parser class   |      |  parser class  |
|  fast tables   |      |  readable tables |      |  small tables  |
+----------------+      +------------------+      +----------------+
        |                         |                        |
        +--------------------------------------------------+
                                  |
                                  | one of them derives
                                  |
                    +------------------------------+
                    |  generated parser class(es)  |
                    |      from your grammar       |
                    +------------------------------+

                   Figure 5:  Parser Class Hierarchy
                                 
+-----------------------+
| 6.2.1. Call-Back Mode |
+-----------------------+

Lexers  and  parsers built with Yacc++ operate in  call-back  mode.
The  lexers  and parsers process only the data passed to  them  and
retain their state between calls.  When a lexer or parser runs  out
of  data to process, it returns to its caller with its entire state
safely retained in its object.  When called again with more data to
process,  the lexer and parser objects resume operation  as  if  no
interruption  had occurred.  Call-back mode simplifies  interfacing
to event driven systems such as GUI window managers.
                                 
                                                             Page 20
+--------------------+
| 6.3. Input Objects |
+--------------------+ 
   
Input  objects  supply  the  text to be  lexed  and  parsed.   Each
distinct  input class obtains the text from a different source  and
uses different interfaces to the underlying I/O system.

   - Input  Stream uses the C++ stream library and has built-in
     support  for  opening and reading from  files  (istreams),
     standard input (cin), and strings (istrstreams).
     
   - Input  String  uses  the string itself  as  a  buffer  and
     minimizes calling overhead.
     
   - Input  File  uses  the  UNIX  read  function  for  maximum
     performance when reading from a file.

   - Input  Getc uses the getc function for compatibility  with
     existing C code.
     
                          +----------------------+
                          |        input         |
                          | generic base class   |
                          +----------------------+
                                     |
                                     | derives
                                     |
        +--------------------------------------------------------+
        |                  |                  |                  |
+----------------+ +----------------+ +----------------+ +----------------+
|  input stream  | |  input string  | |   input file   | |   input getc   |
|      class     | |     class      | |     class      | |      class     |
+----------------+ +----------------+ +----------------+ +----------------+

                     Figure 6:  Input Class Hierarchy
                                 
+---------------------------+
| 6.4. Symbol Table Objects |
+---------------------------+
   
Symbol table objects provide an efficient way of saving information
related  to  strings  of text for subsequent retrieval.   CONSTRUCT
declarations in the lexer can automatically associate  tokens  with
symbols  in  the symbol table or the symbol table can  be  manually
managed.


    +------------------------+       +------------------------+
    |      symbol table      |  -->  |        symbol          |
    |  abstract base class   |       |  abstract base class   |
    +------------------------+       +------------------------+
               |                                |
               | derives                        | derives
               |                                |
    +------------------------+       +------------------------+
    |     symbol table       |  -->  |        symbol          |
    | default implementation |       | default implementation |
    +------------------------+       +------------------------+
                                 
              Figure 7:  Symbol Table Class Hierarchy
                                 
                                                             Page 21
+-----------------------------------------+
| 6.5. AST (Abstract Syntax Tree) Objects |
+-----------------------------------------+

AST  objects support the construction of an internal representation
of the parsed input.  Typically, this takes the form of an abstract
syntax  tree.   The construction can be done manually  with  action
code  in  traditional  yacc  fashion  or  automatically  using  the
CONSTRUCT and BASE CONSTRUCT declarations in the grammar.

Yacc++  generates  classes derived from  the  AST  base  class  for
CONSTRUCT and BASE CONSTRUCT declarations specified in the grammar.
Yacc++  also  generates the code which constructs the  AST  objects
during lexing and parsing.

                    +------------------------+
                    |          AST           |
                    |  abstract base class   |
                    +------------------------+
                                |
                                | derives
                                |
                    +------------------------+
                    |     BASE CONSTRUCT     |
                    |   from your grammar    |
                    +------------------------+
                                |
                                | derives
                                |
                    +------------------------+
                    | per token, parser non- |
                    | terminal, alternative  |
                    | as specified in your   |
                    |        grammar         |
                    +------------------------+

AST classes provide support for many common types of objects needed
in  an  abstract syntax tree.  This includes strings, symbols,  and
keywords for use in a lexer.  General lists, leaves, infix, prefix,
and suffix operators are provided for use in the parser.
                                 
                  Figure 8:  AST Class Hierarchy
                                 
+--------------------+
| 6.6. Error Objects |
+--------------------+
   
Error  objects  provide customizable error  reporting.   There  are
three related hierarchies of error object classes.

   - Error  reporting determines where the error  messages  are
     displayed and how it is formatted.
     
   - Error  message determines the exact text and  severity  of
     each error message.
     
   - Error  location  determines  the  place  where  the  error
     occurred.   The  input classes are in the  error  location
     hierarchy  and  supply the position  of  the  error.   For
     example, the line number in a file.

                                                             Page 22
     
                     +------------------------+
                     |    error reporting     |
                     |  abstract base class   |
                     +------------------------+
                                 |
                                 | derives
                                 |
                     +------------------------+
                     |    error reporting     |
                     | generic implementation |
                     +------------------------+
                                 |
                                 | derives
                                 |
                 +---------------+----------------+
                 |               |                |
                 |   +------------------------+   |
                 |   |    error reporting     |   |
                 |   |  stream implementation |   |
                 |   +------------------------+   |
                 |               |                |
     +-----------------------+   |   +------------------------+
     |   error reporting     |   |   |    error reporting     |
     |  MFC implementation   |   |   |   OWL implementation   |
     +-----------------------+   |   +------------------------+
                                 |
                                 | derives
                                 |
                     +------------------------+
                     |    error reporting     |
                     | default implementation |
                     +------------------------+
                                 
            Figure 9:  Error Reporting Class Hierarchy


                     +------------------------+
                     |     error message      |
                     |  abstract base class   |
                     +------------------------+
                                |
                                | derives
                                |
                     +------------------------+
                     |     error message      |
                     | default implementation |
                     +------------------------+
                                |
                                | derives
                                |
                     +------------------------+
                     |     error message      |
                     |  cache implementation  |
                     +------------------------+
                                 
             Figure 10:  Error Message Class Hierarchy


                     +------------------------+
                     |     error location     |
                     |  abstract base class   |
                     +------------------------+
                                 |
                                 | derives
                                 |
                 +---------------+----------------+
                 |                                |
                 |                                |
    +------------------------+        +------------------------+
    |     error location     |        |         input          |
    | generic implementation |        |   generic base class   |
    +------------------------+        +------------------------+
                                 
             Figure 11:  Error Location Class Hierarchy

                                                             Page 23

+------------------+
| 7. Documentation |
+------------------+
   
Yacc++  and  the Language Objects Library includes  500+  pages  of
printed  documentation  and  100+ small  on-line  examples  showing
actual use of the features.

+--------------------------------------------------+
| 7.1. The Reference Guide and Sample Applications |
+--------------------------------------------------+

The  Yacc++  Reference  Guide  specifies the nuts and bolts of each 
feature  in the  Yacc++ and the Language Objects Library along with 
some sample applications and practical tips on getting started. The
sample  applications are shipped with the sources and makefiles  to
compile   and  execute  them.   The  sample  applications   include
SIMPLISH, CALC, and PARA:

SIMPLISH  lexes and parses simplified English text and  provides  a
non-intimidating  introduction to first  time  users  of  automatic
lexer and parser generators.

CALC  is  the  Yacc++  version of everyone's  favorite  lexing  and
parsing  example  -- a desk top calculator.  It is an  interpretive
calculator  in  the  style of BASIC including  typed  declarations,
assignments, FOR/NEXT and WHILE loops, LIST, and RUN commands.  The
new twist is in how it is built.  The CONSTRUCT declaration is used
to  automatically derive the C++ tree building classes at the token
and  non-terminal level and the member functions of  these  classes
implement the commands.

PARA is an event driven GUI application which paraphrases C and C++
to  English or parse tree form.  It was given as a demonstration at
OOPSLA  '91  in Phoenix.  It provides an example of inheritance  of
grammars by deriving C++ from a C grammar and shows multiple  lexer
and parser objects in the same application.  Other features include
multiple  entry  points, dynamic binding, and incremental  parsing.
(Although  there  is  a full length C++ grammar  included  in  this
application, please be aware it is not up to date and will  require
additional work for production use).

----------------
List of Chapters
----------------

The  following is an overview of the chapters in the last  revision
of Yacc++ Reference Guide.

     TABLE OF CONTENTS
     CHAPTER 0:     INTRODUCTION TO THE YACC++ MANUAL
     CHAPTER 1:     INSTALLING YACC++
     CHAPTER 2:     BUILDING YOUR APPLICATION
     CHAPTER 3:     INTRODUCTION TO YACC++ AND THE LANGUAGE OBJECTS LIBRARY
     CHAPTER 4:     THE SIMPLISH APPLICATION
     CHAPTER 5:     THE CALC APPLICATION
     CHAPTER 6:     THE PARA APPLICATION
     CHAPTER 7:     YACC++ SYNTAX AND SEMANTICS
     CHAPTER 8:     GENERATING YACC++ TABLES
     CHAPTER 9:     THE LANGUAGE OBJECTS LIBRARY
     CHAPTER 10:    MIGRATING FROM YACC
     APPENDICES
     FURTHER READING
     INDEX

                                                             Page 24

+----------------------------------------------+
| 7.2. The Tutorial Guide and On-line Examples |
+----------------------------------------------+
   
The  Yacc++  Tutorial Guide provides more detailed explanations  of
the  features and explains each on-line example.  The examples  are
grouped  according to Tutorial topic.  Sources to on-line  examples
and  the  makefiles  to build them accompany  the  tutorials.   The
following  is the list of Tutorial topics provided at  the  current
time.

-----------------
List of Tutorials
-----------------

     AST       The ABC's of AST's
     AT        Using the "@" Default
     CHARSET   Lexing Extended Character Sets
     DEBUG     Debugging Your Grammar with the Trace Mechanism
     DECLS     Embedding Local, Global, and Member Variables
     EMBED     Embedding String Tokens in Parser Rules
     EOF       Using yy_eof and EOF
     ERROR     Using yy_error for Error Synchronization
     IDENTS    Identifiers, Keywords, and Reserved Words
     IGNORE    Declaring Ignore Symbols
     INPUT     Choosing and Using the Various Input Classes
     KEYWORDS  Declaring Keywords and Substr Keywords
     LARGE     Generating Tables for Large Grammars under DOS
     LCLASS    Using Lexer Classes
     LEXCODE   Writing Lexer Semantic Action Code
     LEXNTERM  Defining Lexer Non-terminals
     LPROG     Using a Lex Lexer with a Yacc++ Parser
     MULTIPLE  Combining Multiple Lexers and Parsers
     OBJECS    Creating and Accessing Objects in the Language Objects Library
     OWLDLL    Using Yacc++ Lexer and Parser Objects as a Windows DLL
     PREC      Using Precedence and Associativity
     PRECMFC   Test Driving Yacc++ With Microsoft MFC Visual C++
     PSRCODE   Writing Parser Semantic Action Code
     PUBLIC    Declaring Multiple Entry Points
     RANGES    Defining Ranges in Lexer Rules
     REDUCE    Writing Reduce Action Code
     REENTER   Reentrant Parsing
     REGEXPR   Using the ?, *, and + Operators
     REMOVE    Declaring Remove Symbols
     REUSE     Inheriting Grammars
     RULES     Defining Rules
     SHIFT     Writing Shift Action Code
     SPROG     Building Lexers and Parsers Separately
     START     Declaring the Start Symbol
     STRINGS   Defining Character Strings
     TOKENS    Declaring Tokens and Discard Tokens
     UNION     Declaring the Parser Stack Union


                                                             Page 25

+-------------------------+
| 8. Ordering Information |
+-------------------------+   

+-----------------------+
| 8.1. Placing an Order |
+-----------------------+
   
Please  read  the Yacc++ Software License Agreement,  Section  8.6,
before  placing  an  order.   If  the  conditions  and  terms   are
acceptable, complete the Customer Contact Sheet, Section  8.7,  and
return it to us along with your payment information.

-------
Payment
-------

We  accept  purchase orders on approved accounts only.   All  other
purchases  must  be  accompanied by either a Visa  or  Master  Card
number, a check in US dollars on a US bank, or a bank wire transfer
in  US dollars.  For Visa or Master Card orders, please specify the
type of credit card, the credit card number, the name as it appears
on  the  card, the expiration date, and the signature of the person
whose  name  appears on the credit card.  For bank wire  transfers,
please contact us for the Bank ACH number and account.

+--------------------------+
| 8.2. Contact Information |
+--------------------------+
   
You  can place an order for Yacc++ and the Language Objects Library
by fax, US mail or phone.

  +---------------------------------------------------------------+
  |                                                               |
  |                   Compiler Resources, Inc.                    |
  |                       3 Proctor Street                        |
  |                  Hopkinton, MA  01748  USA                    |
  |                                                               |       
  |                (508) 435-5016                                 |
  |                (978) 838-0263  (24 hour fax)                  |
  |                                                               |
  |               internet:  compres@world.std.com                |
  |                                                               |
  +---------------------------------------------------------------+

Compiler  Resources  is located on the East  Coast  of  the  United
States  (Boston area).  We are Eastern Standard Time.  For example,
if  it is 9:00 AM  in California, it is 12:00 noon here and at 9:00
AM  in  London  it  is 4:00 AM here.  Our fax and  phone  answering
system are available 24 hours per day.

-----------
Bug Reports
-----------

Bug  reports  for  Yacc++  and  the Language  Objects  Library  are
accepted via electronic mail.  Send your bug reports to one of  the
e-mail  addresses above.  You will get a confirmation reply  and  a
workaround if one is known.

                                                             Page 26
+--------------+
| 8.3. Pricing |
+--------------+   

+----------------------------------------------------------------------------+
|                                                                            |
|                       Pricing for All Platforms                            |
|                                                                            |
|                 HP-UX (PARISC or Itanium) HP TRU64 (Alpha),                |
|                 IBM AIX (PPC),                                             |
|		  Linux (x86 or PPC),                                        |
|		  SGI IRIX,                                                  |
|		  Solaris (Sparc),                                           |
|		  Windows XP/2K/NT/98/95 (x86)                               |
|                                                                            |
|                             Revision 2.x                                   |
|                                                                            |
+----------------------------------------------------------------------------+
|                                                                            |
|                                     Professional     Academic or Personal  |
|                                                                            |
| Single User License                   $995.             $500.              |
|                                                                            |
| Additional Licenses                   $750. each        $500. each         |
|                                                                            |
| Site License                         $5000. per site   $5000. per site     |
|                                                                            |
| Printed Manuals                       $200. per user    $200. per user     |
| (Software comes with online HTML/MS Word Manuals)                          |
|                                                                            |
| Shipping charges are additional.  (Shipping via e-mail is free)            |
| All prices are given in US dollars.                                        |
| Price and availability is subject to change without notice.                |
|                                                                            |
+----------------------------------------------------------------------------+

--------
Shipping
--------

Unless we receive specific instructions otherwise, orders ship via email.

Orders for printed manuals ship via Federal Express Two Day service
for orders within the United States and Federal Express International
Priority service for orders outside the United States.

Orders shipped via Federal Express usually ship within 48 hours.  The
cost for a single user shipment within the United States is $100.
International shipments vary by country and range approximately $200 -
$300.

Orders within the United States can be shipped via UPS ground at your
request.  UPS requires us to arrange a pick up in advance so they
typically don't ship for 72+ hours.  The cost for a single user
shipment within the United States is $100.

+-----------------------+
| 8.4. Current Revision |
+-----------------------+   

The latest revision of Yacc++ and the Language Objects Library is
Revision 2.4.  Revision 2.5 is expected to be released in 2003.

New manuals for Revision 2.x were made available in 1995.

                                                             Page 27
----------------------------------------------
Professional vs. Academic or Personal Licenses
----------------------------------------------

The  same  software  is shipped for professional  vs.  academic  or
personal  licenses.  The difference is solely in the  cost  of  the
license.  The cost is determined by how the software will be used:

   If  you  will be using Yacc++ and the Language Objects  in  a
   commercial setting, you must purchase a professional license.
   
   If  you will be using Yacc++ and the Language Objects Library
   in  an academic institution solely for academic purposes, you
   qualify for the academic discount pricing.  If you are  using
   Yacc++  for  teaching a course, a single user license  covers
   both the instructor and the students in the class.
   
   If  you will be using Yacc++ and the Language Objects Library
   for  your  own  private  use, you qualify  for  the  personal
   discount pricing.  Please note the personal license gives you
   no  rights  to  sell  or distribute applications  built  with
   Yacc++ and the Language Objects Library.

-------------------
Individual Licenses
-------------------

Yacc++  is  licensed per developer.  Each person using Yacc++  must
have his or her own license.  An individual license comes with  the
Yacc++  table  generator in executable form,  the  sources  to  the
Language  Objects Library, makefiles and sources  for  all  on-line
examples, and a documentation set for one user.

------------------------
Additional User Licenses
------------------------

Additional  user  licenses are available  at  a  discounted  price.
Additional users must be located at the same geographic site as the
initial  licensee  to  receive  this  discount.   Additional  users
receive  documentation  sets, but share the  software  distribution
media with the initial licensee.

-------------
Site Licenses
-------------

A  site  license gives all developers at a given geographic site  a
license to use the software.  A site license comes with the  Yacc++
table  generator  in executable form, the sources to  the  Language
Objects  Library,  makefiles and sources for all on-line  examples,
and documentation sets for five users.  Additional  manuals can  be
ordered for $100. for each user.

-----------------------------------------
Site License with Table Generator Sources
-----------------------------------------

A site license with table generator sources gives all developers at
a  given  geographic site a license to use the  software.   A  site
license  comes with the Yacc++ table generator in both  source  and
executable  form,  the  sources to the  Language  Objects  Library,
makefiles  and  sources for all on-line examples, and documentation
sets  for five users.  Additional manuals can be  ordered for $100.
for each user.

--------------------
Money Back Guarantee
--------------------

Individual  licenses  are  all  covered  by  a  30  day  money back 
guarantee.

Site licenses are not covered by a 30 day money back guarantee.  If
you are in doubt about ordering a site license, order an individual
license  first.   After 30 days, either return the license  on  the
money  back  guarantee  or place the site  license  order  and  the
individual  license fee will be credited toward  the  site  license
fee.   

Site  with sources to the  table generator must always  be pre-paid 
and there is no money back guarantee.

                                                             Page 28
+------------------------------+
| 8.5. Platforms and Compilers |
+------------------------------+
   
Yacc++  and  the  Language Objects Library ships on  a  variety  of
platforms.   Makefiles  are  provided for  compiling  the  Language
Objects Library and for each of the sample applications and on-line
examples for:

        +--------------------------------------------------+
        |                                                  |          
        |   DEC/Alpha       DEC C++                        |          
        |                                                  |
        |   DOS/Windows     Borland C++                    |
        |                   Microsoft Visual C++           |
        |                   WATCOM C++                     |
        |                                                  |          
        |   HP              HP aC++ and HP C++             |
        |                                                  |          
        |   OS/2            Borland C++ for OS/2           |
        |                   IBM C Set++ for OS/2           |
        |                                                  |          
        |   SGI IRIX        SGI (Edison Design Group) C++  |
        |                                                  |          
        |   SPARC SunOS     Gnu C++                        |
        |                   SPARCCompiler C++              |
        |                                                  |          
        |   SPARC Solaris   SPARCompiler C++               |
        |                                                  |          
        |   Windows NT/95   Microsoft Visual C++           |       
        |                                                  |
        +--------------------------------------------------+          

----------------------------------
Cross-compiling to Other Platforms
----------------------------------

Other  platforms  are supported by cross-compiling  Yacc++  output.
Yacc++ and the Language Objects Library comes in two parts:

   - yxx  is  the table generator which processes grammars  and
     automatically  generates  C++  classes.    It   ships   in
     executable form.
     
   - The  Language Objects Library is a C++ class library which
     ships in source form.
     
The  output of yxx and the Language Objects Library source code  is
"vanilla" C++ purposely coded for portability.  The code  uses  the
subset of C++ which tends to be fairly uniform across compilers and
purposely  avoids using the newer features of C++ such as templates
and exceptions which tend to vary by compiler.

If  you  work  in  a heterogeneous computing environment,  you  can
generate  your  tables on one of the supported platforms  and  then
compile your application on your native platform.

Yacc++  customers currently  cross-compile  to  DEC VAX,  POWER  PC
IBM RS/6000, and Apple Macintosh.  In addition to the compilers for
which  makefiles  are  shipped, many  Yacc++  customers  use  other
compilers such as ObjectCenter.

----------------
Future Platforms
----------------

If  you  are interested in a native Yacc++ version for a  different
platform,  please send e-mail and let us know.  We are  considering
adding  native  Yacc++  versions to those  platforms  being  cross-
compiled  today. 


                                                             Page 29
                                 
                YACC++(r) SOFTWARE LICENSE AGREEMENT
                                 
                                 
                     COMPILER RESOURCES, INC.
                         3 Proctor Street
                     Hopkinton, MA  01748 USA
                  1 (508) 435-4847 (24 hour fax)
                     1 (508) 435-5016 (voice)
                                 
                                 
     PLEASE CAREFULLY READ THIS YACC++ SOFTWARE LICENSE AGREEMENT
BEFORE OPENING THIS PACKAGE.  RIGHTS IN THE SOFTWARE ARE OFFERED
ONLY ON CONDITION THAT THE CUSTOMER AGREES TO ALL TERMS AND
CONDITIONS OF THIS YACC++ SOFTWARE LICENSE AGREEMENT.  BREAKING OR
REMOVING THE SEAL INDICATES YOUR ACCEPTANCE OF THESE TERMS AND
CONDITIONS.  IF YOU DO NOT AGREE TO THE TERMS OF THIS YACC++
SOFTWARE LICENSE AGREEMENT, YOU MAY RETURN THE UNOPENED PACKAGE FOR
A FULL REFUND OF THE YACC++ SOFTWARE LICENSE FEE WITHIN FIVE DAYS
OF RECEIPT BY YOU OF THE PACKAGE.

     The following terms and conditions shall govern the license by
Compiler Resources, Inc. ("CRI") to you of CRI's Yacc++ and
Language Objects Library (collectively, the "Software") and related
documentation.

  1. LICENSE GRANT.  CRI grants to you a personal, non-exclusive,
non-transferable license to use (i) the Software solely for your
internal business purposes only on the system set forth in your
customer contact sheet (the "CPU") and at the location/installation
site set forth in such customer contact sheet (the "Address") and
(ii) the related documentation solely in support of your permitted
use of the software.  CRI acknowledges that the Software will be
used to create a product developed by you (the "Customer Product"),
which you may sell, license, lease, loan, give away, or otherwise
transfer subject to the provisions of this Agreement.

  2. CONDITIONS TO LICENSE.  The grant of license in Section 1 is
explicitly conditioned upon compliance by you with all of the
following conditions: (i) You shall not distribute any portion of
the Language Objects Library in a human readable form, nor in any
form which can be used to recreate a human readable copy; (ii) You
shall not sell, license, lease, loan, give away, or otherwise
transfer any source code which is supplied by CRI to you under this
Agreement, and (iii) Customer Product is not a parser generator or
lexer generator nor does it contain a parser generator or lexer
generator as one of its parts.

  3. USE AND COPYING OF SOFTWARE.  CRI shall provide you with (i)
one (1) copy of the executable object code of Yacc++, (ii) one (1)
copy of the Language Objects Library in source code form and (iii)
one (1) copy of the user's manual and related documentation for the
Software.  You may make one (1) additional copy of the Software and
related documentation for internal archive or emergency backup
purposes, but for no other purpose.

  4. TITLE TO SOFTWARE; PROTECTION OF CRI'S PROPRIETARY RIGHTS.
All right, title and interest to the Software and related
documentation shall at all times remain vested in CRI.  You
acknowledge that the Software, related documentation and other
materials and information furnished hereunder are the exclusive
property of CRI and contain valuable proprietary information and
trade secrets of CRI developed at a great cost and expense.  You
agree (i) not to translate, compile, disassemble, reverse engineer,
create derivative works or take any other steps intended to produce
a source language statement of the Software;  (ii) to limit access
to the Software to your employees, agents or consultants who are
required to use the Software in your business; (iii) not to copy,
reproduce, distribute, transfer or disclose the Software or related
documentation to others except as set forth in Section 3; (iv) to
include on all copies of the Software and related documentation the
copyright, trademark and other proprietary rights notices of CRI;
and (v) to ensure that your employees, consultants or agents who
are permitted access to the Software or related documentation
comply with the provisions of this Section.

  5. EXPORT LAW COMPLIANCE.  You shall not transfer or export the
Software, directly or indirectly, into any country prohibited by
the United States Export Administration Act and the regulations
thereunder and shall otherwise comply with such Act and
regulations.
                                                             Page 30
  
  6. WARRANTY.  CRI warrants that it has title to or the right to
grant the license of the Software and related documentation to you.
CRI warrants the magnetic media (tape or diskettes) to be free from
defects in materials and workmanship for a period of ninety (90)
days from the date of purchase.  In the event of notification to
CRI within the warranty period of defects in materials and
workmanship, CRI's sole and exclusive obligation to you is, at
CRI's option, to refund the license fee paid hereunder or replace
the magnetic media which does not meet the foregoing limited
warranty.  The Software itself is licensed "as is" without warranty
of any kind.  In particular, CRI makes no warranty that the
Software will work in combination with any hardware or applications
software products provided by third parties or that the operation
of the Software will be uninterrupted or error-free.  THE FOREGOING
LIMITED WARRANTY IS IN LIEU OF, AND YOU HEREBY WAIVE, ANY AND ALL
OTHER WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.

  7. LIMITATIONS OF LIABILITY.  CRI SHALL NOT BE LIABLE FOR ANY
LOSS, DAMAGE OR EXPENSE OF ANY KIND OR NATURE CAUSED DIRECTLY OR
INDIRECTLY BY THE SOFTWARE OR CUSTOMER PRODUCT, THE USE OR LOSS OF
USE THEREOF, AND YOU SHALL INDEMNIFY AND HOLD CRI HARMLESS FROM ANY
LOSS, DAMAGE OR EXPENSE ARISING FROM ANY SUCH CLAIM MADE BY YOU OR
A THIRD PARTY.  IN NO EVENT SHALL CRI BE LIABLE TO YOU FOR ANY LOSS
OF REVENUE OR PROFIT OR ANY OTHER ECONOMIC LOSS OR FOR INDIRECT,
INCIDENTAL, SPECIAL, CONSEQUENTIAL, PUNITIVE OR OTHER SIMILAR
DAMAGES, WHETHER BASED ON TORT (INCLUDING WITHOUT LIMITATION
NEGLIGENCE OR STRICT LIABILITY), CONTRACT OR OTHER LEGAL OR
EQUITABLE GROUNDS, EVEN IF CRI HAS BEEN ADVISED OR HAD REASON TO
KNOW OF THE POSSIBILITY OF SUCH DAMAGES.  IF CRI IS FOUND LIABLE TO
YOU FOR THE PAYMENT OF ANY AMOUNTS FOR ANY REASON, BASED ON ANY
THEORY OF LIABILITY, CRI'S ENTIRE LIABILITY THEREFOR SHALL NOT
EXCEED THE TOTAL LICENSE FEE RECEIVED BY CRI.

  8. PATENT AND COPYRIGHT INDEMNITY.  CRI shall indemnify, defend
and hold you harmless from any claims and damages finally awarded
that the Software infringes any United States patent, copyright or
trade secret of a third party.  You shall give CRI prompt notice of
any claim and reasonable assistance and information, at CRI's
expense, to defend or settle the claim.  CRI shall have sole
authority to defend or settle the claim.  In the event any Software
constitutes an infringement and the use of the Software is
enjoined, CRI may, at its option, substitute or modify the Software
so as to make the Software non-infringing, or obtain for you the
right to continue using the Software.  If such remedies are not
available, CRI may, at its option, remove the Software and refund
the license fee.  CRI shall not be liable if the alleged
infringement involves a modification of the Software by anyone
other than CRI or the use of the Software other than in accordance
with the terms of this Agreement or with CRI's published
specifications of documentation.  THE FOREGOING STATES THE SOLE AND
EXCLUSIVE LIABILITY OF CRI FOR INFRINGEMENT.

  9. TERMINATION.  This Agreement will terminate automatically
without notice from CRI in the event you breach any of the terms
specified herein.  Upon termination, all software and supporting
materials will be returned to CRI and you shall not be entitled to
any refunds or credits.

  10.GENERAL.  You acknowledge that you have read this Agreement
and understand it and that this Agreement constitutes the entire
agreement between the parties relative to the Software and related
documentation and supersedes all other proposals, understandings or
agreements, whether written or oral.  Unless this Agreement is
replaced by a separate written agreement signed by both parties,
you agree to be bound by its terms and conditions.  In the event of
any conflict between the terms of this Agreement and any of your
purchase orders, this Agreement shall govern and take precedence.
No waiver by either party of a breach of this Agreement shall
operate or be construed as a waiver of any subsequent breach.  The
invalidity, illegality or unenforceability of any provision of this
Agreement shall not affect the remainder of the Agreement, and this
Agreement shall be construed and reformed without such provision.
You may not assign this Agreement or sublicense the Software
without CRI's written consent, and any such assignment shall be
null and void.  All obligations of confidentiality survives the
termination of the Agreement.  This Agreement shall be governed by
the internal laws of, and enforced in the courts located in, the
Commonwealth of Massachusetts.

                                                             Page 31

COMPILER RESOURCES, INC.           (24 hour fax) 1 (508) 435-4847
3 Proctor Street                         (voice) 1 (508) 435-5016
Hopkinton, MA  01748  USA
                                 
                   YACC++ CUSTOMER CONTACT SHEET

Please circle which platform:
                                 
       DEC Alpha      DOS/Windows       HP UX       IBM OS/2 

  SGI IRIX     SPARC SunOS     SPARC Solaris     Windows NT/95

I have read the Yacc++ Software License Agreement and accept the
terms and conditions:

(print or type name):

(signature):

     Please sign below for an academic discount if this is an
     academic institution and the software will be used solely
     for academic purposes:
     
     (signature/title):
     
     Please sign below for a personal discount if you are a
     non-commercial user and you will not distribute any
     applications built with Yacc++:
     
     (signature):

Contact Person for Technical Updates:
        Specify Name(s), Address, Phone, Fax, and E-mail address:














Compiler(s) Used:  (specify revision)






Operating System Used:  (specify revision)




CPU (hostid):







Last updated on October 14, 1997. To send email to Compiler Resources, Inc.

Return to Yacc++ Home Page