%{

/**********************************************************************
 * cbf.stx -- cbf parser                                              *
 *                                                                    *
 * Version 0.7.4 12 January 2004                                      *
 *                                                                    *
 *            Paul Ellis (ellis@ssrl.slac.stanford.edu) and           *
 *         Herbert J. Bernstein (yaya@bernstein-plus-sons.com)        *
 **********************************************************************/
  
/**********************************************************************
 *                               NOTICE                               *
 * Creative endeavors depend on the lively exchange of ideas. There   *
 * are laws and customs which establish rights and responsibilities   *
 * for authors and the users of what authors create.  This notice     *
 * is not intended to prevent you from using the software and         *
 * documents in this package, but to ensure that there are no         *
 * misunderstandings about terms and conditions of such use.          *
 *                                                                    *
 * Please read the following notice carefully.  If you do not         *
 * understand any portion of this notice, please seek appropriate     *
 * professional legal advice before making use of the software and    *
 * documents included in this software package.  In addition to       *
 * whatever other steps you may be obliged to take to respect the     *
 * intellectual property rights of the various parties involved, if   *
 * you do make use of the software and documents in this package,     *
 * please give credit where credit is due by citing this package,     *
 * its authors and the URL or other source from which you obtained    *
 * it, or equivalent primary references in the literature with the    *
 * same authors.                                                      *
 *                                                                    *
 * Some of the software and documents included within this software   *
 * package are the intellectual property of various parties, and      *
 * placement in this package does not in any way imply that any       *
 * such rights have in any way been waived or diminished.             *
 *                                                                    *
 * With respect to any software or documents for which a copyright    *
 * exists, ALL RIGHTS ARE RESERVED TO THE OWNERS OF SUCH COPYRIGHT.   *
 *                                                                    *
 * Even though the authors of the various documents and software      *
 * found here have made a good faith effort to ensure that the        *
 * documents are correct and that the software performs according     *
 * to its documentation, and we would greatly appreciate hearing of   *
 * any problems you may encounter, the programs and documents any     *
 * files created by the programs are provided **AS IS** without any   *
 * warranty as to correctness, merchantability or fitness for any     *
 * particular or general use.                                         *
 *                                                                    *
 * THE RESPONSIBILITY FOR ANY ADVERSE CONSEQUENCES FROM THE USE OF    *
 * PROGRAMS OR DOCUMENTS OR ANY FILE OR FILES CREATED BY USE OF THE   *
 * PROGRAMS OR DOCUMENTS LIES SOLELY WITH THE USERS OF THE PROGRAMS   *
 * OR DOCUMENTS OR FILE OR FILES AND NOT WITH AUTHORS OF THE          *
 * PROGRAMS OR DOCUMENTS.                                             *
 **********************************************************************/
 
/**********************************************************************
 *                                                                    *
 *                           The IUCr Policy                          *
 *      for the Protection and the Promotion of the STAR File and     *
 *     CIF Standards for Exchanging and Archiving Electronic Data     *
 *                                                                    *
 * Overview                                                           *
 *                                                                    *
 * The Crystallographic Information File (CIF)[1] is a standard for   *
 * information interchange promulgated by the International Union of  *
 * Crystallography (IUCr). CIF (Hall, Allen & Brown, 1991) is the     *
 * recommended method for submitting publications to Acta             *
 * Crystallographica Section C and reports of crystal structure       *
 * determinations to other sections of Acta Crystallographica         *
 * and many other journals. The syntax of a CIF is a subset of the    *
 * more general STAR File[2] format. The CIF and STAR File approaches *
 * are used increasingly in the structural sciences for data exchange *
 * and archiving, and are having a significant influence on these     *
 * activities in other fields.                                        *
 *                                                                    *
 * Statement of intent                                                *
 *                                                                    *
 * The IUCr's interest in the STAR File is as a general data          *
 * interchange standard for science, and its interest in the CIF,     *
 * a conformant derivative of the STAR File, is as a concise data     *
 * exchange and archival standard for crystallography and structural  *
 * science.                                                           *
 *                                                                    *
 * Protection of the standards                                        *
 *                                                                    *
 * To protect the STAR File and the CIF as standards for              * 
 * interchanging and archiving electronic data, the IUCr, on behalf   *
 * of the scientific community,                                       *
 *                                                                    *
 * * holds the copyrights on the standards themselves,                *
 *                                                                    *
 * * owns the associated trademarks and service marks, and            *
 *                                                                    *
 * * holds a patent on the STAR File.                                 *
 *                                                                    *
 * These intellectual property rights relate solely to the            *
 * interchange formats, not to the data contained therein, nor to     *
 * the software used in the generation, access or manipulation of     *
 * the data.                                                          *
 *                                                                    *
 * Promotion of the standards                                         *
 *                                                                    *
 * The sole requirement that the IUCr, in its protective role,        *
 * imposes on software purporting to process STAR File or CIF data    *
 * is that the following conditions be met prior to sale or           *
 * distribution.                                                      *
 *                                                                    *
 * * Software claiming to read files written to either the STAR       *
 * File or the CIF standard must be able to extract the pertinent     *
 * data from a file conformant to the STAR File syntax, or the CIF    *
 * syntax, respectively.                                              *
 *                                                                    *
 * * Software claiming to write files in either the STAR File, or     *
 * the CIF, standard must produce files that are conformant to the    *
 * STAR File syntax, or the CIF syntax, respectively.                 *
 *                                                                    *
 * * Software claiming to read definitions from a specific data       *
 * dictionary approved by the IUCr must be able to extract any        *
 * pertinent definition which is conformant to the dictionary         *
 * definition language (DDL)[3] associated with that dictionary.      *
 *                                                                    *
 * The IUCr, through its Committee on CIF Standards, will assist      *
 * any developer to verify that software meets these conformance      *
 * conditions.                                                        *
 *                                                                    *
 * Glossary of terms                                                  *
 *                                                                    *
 * [1] CIF:  is a data file conformant to the file syntax defined     *
 * at http://www.iucr.org/iucr-top/cif/spec/index.html                *
 *                                                                    *
 * [2] STAR File:  is a data file conformant to the file syntax       *
 * defined at http://www.iucr.org/iucr-top/cif/spec/star/index.html   *
 *                                                                    *
 * [3] DDL:  is a language used in a data dictionary to define data   *
 * items in terms of "attributes". Dictionaries currently approved    *
 * by the IUCr, and the DDL versions used to construct these          *
 * dictionaries, are listed at                                        *
 * http://www.iucr.org/iucr-top/cif/spec/ddl/index.html               *
 *                                                                    *
 * Last modified: 30 September 2000                                   *
 *                                                                    *
 * IUCr Policy Copyright (C) 2000 International Union of              *
 * Crystallography                                                    *
 **********************************************************************/

#ifdef __cplusplus

extern "C" {

#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "cbf.h"
#include "cbf_tree.h"

#define yyparse       cbf_parse
#define yylex         cbf_lex_wrapper
#define yyerror       cbf_syntax_error
#define YYLEX_PARAM   context
#define YYPARSE_PARAM context

#define alloca(x) (NULL)

#define YYINITDEPTH 200
#define YYMAXDEPTH  200

int cbf_lex (void *, void *);

int cbf_lex_wrapper (void *val, void *context)
{
  int token;

  do

    token = cbf_lex (val, ((void **) context) [0]);

  while (token == COMMENT);

  return token;
}

int cbf_syntax_error (const char *message)
{
  return 0;
}

%}

%union
{
  int          errorcode;
  const char  *text;
  cbf_node    *node;
}

%token <text> DATA
%token        LOOP
%token <text> ITEM
%token <text> CATEGORY
%token <text> COLUMN
%token <text> STRING
%token <text> WORD
%token <text> BINARY
%token <text> UNKNOWN
%token <text> COMMENT
%token <errorcode> ERROR

%type  <node> cbf
%type  <node> cbfstart
%type  <node> datablockstart
%type  <node> datablock
%type  <node> category
%type  <node> column
%type  <node> assignment
%type  <node> loopstart
%type  <node> loopcategory
%type  <node> loopcolumn
%type  <node> loopassignment
%type  <text> datablockname
%type  <text> categoryname
%type  <text> columnname
%type  <text> itemname
%type  <text> value

%pure_parser
%no_lines
%expect 0

%%

cbf:              datablock                     {
                                                  cbf_failnez (cbf_find_parent (&($$), $1, CBF_ROOT))
                                                }
                ;

cbfstart:                                       {
                                                  $$ = ((void **) context) [1];
                                                }
                ;

datablockstart:   cbfstart                      {
                                                  cbf_failnez (cbf_make_child (&($$), $1, CBF_DATABLOCK, NULL))
                                                }
                | cbf datablockname             {
                                                  cbf_failnez (cbf_make_child (&($$), $1, CBF_DATABLOCK, $2))
                                                }
                ;

datablock:        datablockstart                {
                                                  $$ = $1;
                                                }
                | assignment                    {
                                                  cbf_failnez (cbf_find_parent (&($$), $1, CBF_DATABLOCK))
                                                }
                | loopassignment                {
                                                  cbf_failnez (cbf_find_parent (&($$), $1, CBF_DATABLOCK))
                                                }
                ;

category:         datablock categoryname        {
                                                  cbf_failnez (cbf_make_child (&($$), $1, CBF_CATEGORY, $2))
                                                }
                ;

column:           category columnname           {
                                                  cbf_failnez (cbf_make_child (&($$), $1, CBF_COLUMN, $2))
                                                }
                | datablock itemname            {
                                                  cbf_failnez (cbf_make_new_child (&($$), $1, CBF_CATEGORY, NULL))
                                                  
                                                  cbf_failnez (cbf_make_child (&($$), $$, CBF_COLUMN, $2))
                                                }
                ;

assignment:       column value                  {
                                                  $$ = $1;

                                                  cbf_failnez (cbf_set_columnrow ($$, 0, $2, 1))
                                                }
                ;

loopstart:        datablock loop                {
                                                  cbf_failnez (cbf_make_node (&($$), CBF_LINK, NULL, NULL))

                                                  cbf_failnez (cbf_set_link ($$, $1))
                                                }
                ;

loopcategory:     loopstart categoryname        {
                                                  cbf_failnez (cbf_make_child (&($$), $1, CBF_CATEGORY, $2))

                                                  cbf_failnez (cbf_set_link ($1, $$))

                                                  $$ = $1;
                                                }
                | loopcolumn categoryname       {
                                                  cbf_failnez (cbf_find_parent (&($$), $1, CBF_DATABLOCK))

                                                  cbf_failnez (cbf_make_child (&($$), $$, CBF_CATEGORY, $2))

                                                  cbf_failnez (cbf_set_link ($1, $$))

                                                  $$ = $1;
                                                }
                ;

loopcolumn:       loopstart itemname            {
                                                  cbf_failnez (cbf_make_new_child (&($$), $1, CBF_CATEGORY, NULL))
                                                  
                                                  cbf_failnez (cbf_make_child (&($$), $$, CBF_COLUMN, $2))

                                                  cbf_failnez (cbf_set_link ($1, $$))

                                                  cbf_failnez (cbf_add_link ($1, $$))

                                                  $$ = $1;
                                                }
                | loopcolumn itemname           {
                                                  cbf_failnez (cbf_find_parent (&($$), $1, CBF_DATABLOCK))

                                                  cbf_failnez (cbf_make_child (&($$), $$, CBF_CATEGORY, NULL))
                                                  
                                                  cbf_failnez (cbf_make_child (&($$), $$, CBF_COLUMN, $2))

                                                  cbf_failnez (cbf_set_link ($1, $$))

                                                  cbf_failnez (cbf_add_link ($1, $$))

                                                  $$ = $1;
                                                }
                | loopcategory columnname       {
                                                  cbf_failnez (cbf_make_child (&($$), $1, CBF_COLUMN, $2))

                                                  cbf_failnez (cbf_set_link ($1, $$))

                                                  cbf_failnez (cbf_add_link ($1, $$))

                                                  $$ = $1;
                                                }
                ;

loopassignment:   loopcolumn value              {
                                                  $$ = $1;

                                                  cbf_failnez (cbf_shift_link ($$))

                                                  cbf_failnez (cbf_add_columnrow ($$, $2))
                                                }
                | loopassignment value          {
                                                  $$ = $1;

                                                  cbf_failnez (cbf_shift_link ($$))

                                                  cbf_failnez (cbf_add_columnrow ($$, $2))
                                                }
                ;
                
loop:             LOOP
                ;

datablockname:    DATA                          {
                                                  $$ = $1;
                                                }
                ;

categoryname:     CATEGORY                      {
                                                  $$ = $1;
                                                }
                ;

columnname:       COLUMN                        {
                                                  $$ = $1;
                                                }
                ;
                
itemname:         ITEM                          {
                                                  $$ = $1;
                                                }
                ;

value:            STRING                        {
                                                  $$ = $1;
                                                }
                | WORD                          {
                                                  $$ = $1;
                                                }
                | BINARY                        {
                                                  $$ = $1;
                                                }
                ;

%%

#ifdef __cplusplus

}

#endif
