/****************************************************************************
			     Sesh Nesout
	   Un programme d'aide a` la frappe hieroglyphique
		      utilisant le format glyph.
			   Serge Rosmorduc
****************************************************************************/
%{
#include <malloc.h>
typedef char * YYSTYPE;
char* genere();
extern void initialise_lex();
#include <stdio.h>
#ifndef NULL
#define NULL (char *)0
#endif
%}

%token TEXTE DEBUTHIEROGS FINHIEROGS
%token HIEROGLYPHE LIGAD
%token POINT
%token POINTPOINT  
%token SYMBOLE
%token KERNING  
%token ESPACE CARTO CARTF DEBCARTO MILCARTO FINCARTO
%token DIEZE0 DIEZE1
%token ROMAIN
%token INTERNALSPACE
  
%right '-'
%right ':'  

%%

tout: tout TEXTE
      |tout hierogs
      | /* empty */
      ;

hierogs:
  DEBUTHIEROGS
  {printf("{%%\n\\leavevmode\\makeatletter%%\n");}
               lignes
  FINHIEROGS
  {printf("}%%\n\\end{hieroglyph}");}
  ;

lignes:
  ligne
  |lignes ligne
  ;

ligne:
  '\n'
  | exprs '\n' {printf("%s", $1);}
  ;


 exprs:
  express0
  | exprs express0 {$$= (YYSTYPE)genere($1,$2,NULL); free($1); free($2);}
  ;

 express0:
  express1
  ;

express1:
  quadras ESPACE {$$= (YYSTYPE)genere($1,"\\intermots%\n",NULL);
		  representation($1);} /* On vient de lire l'espace */
  |quadras
  ;

quadras:
  kerning quadra  {$$= (YYSTYPE)genere($1,$2, NULL); free($1); free($2);}
  | quadras '-' kerning quadra {$$= (YYSTYPE)genere( $1, "\\AROBrempl ",
						    $3, $4, NULL);
			       free($1); free($3); free($4);}
  ;

quadra:
  quadra_commun {$$= $1;}
  |HIEROGLYPHE {$$= (YYSTYPE)genere("\\unhieroglyphe{", $1, "}", NULL);
		 free($1);}
  | ROMAIN     {$$= (YYSTYPE)genere("{\\rm ", $1, "}", NULL); free($1);}
  | sousquadra ':' sousquadras      {$$= (YYSTYPE) genere("\\boite{\\hboiteI{",
						      $1, "}",
						      $3, "}", NULL);
			         free($1);free($3);}
  ;

quadra_interne:
  quadra_commun
  |HIEROGLYPHE
  | ROMAIN             {$$= (YYSTYPE)genere("{\\footnotesize \\rm ", $1, "}", NULL);
		        free($1);}
  | sousquadra ':' sousquadras      {$$= (YYSTYPE) genere("\\boiteinter{\\hboiteI{",
							  $1, "}",
							  $3, "}", NULL);
				     free($1);free($3);}
  | '(' quadras1 ')' {$$= $2;}
  ;

quadra_commun:
  POINT              {$$=(YYSTYPE)genere("\\quartespace ",NULL);}
  |CARTO exprs CARTF {$$= (YYSTYPE)genere("\\cartouche{",$2,"}",NULL);}
  |DEBCARTO exprs CARTF {$$= (YYSTYPE)genere("\\debcartouche{",$2,"}",NULL);}
  |MILCARTO exprs CARTF {$$= (YYSTYPE)genere("\\milcartouche{",$2,"}",NULL);}
  |FINCARTO exprs CARTF {$$= (YYSTYPE)genere("\\fincartouche{",$2,"}",NULL);}
  | DIEZE0 exprs DIEZE1 {$$=(YYSTYPE)genere("\\hachure{",$2,"}%\n",NULL);
		       free($2);}
  | POINTPOINT         {$$=(YYSTYPE)genere("\\espace ",NULL);}
  | SYMBOLE
  ;


sousquadras:
	sousquadra {$$= (YYSTYPE)genere("\\hboite{", $1, "}",NULL);
		    free($1);}
	| sousquadras ':' sousquadra {$$= (YYSTYPE)genere($1, "\\hboite{" ,
							  $3, "}",NULL);
				      free($1);free($3);}
;	

sousquadra: sousquadra '*' inhierliste {$$= (YYSTYPE)genere($1, "\\hfil", $3, NULL);
				      free($1); free($3);}
        | inhierliste
	;

inhierliste: quadra_commun
        | HIEROGLYPHE
        | '(' quadras1 ')' {$$= $2;}
        ;

quadras1:
  quadra_interne  
  | quadras1 '-' quadra_interne {$$= (YYSTYPE)genere( $1, "\\hfil", $3, NULL);
		       free($1); free($3);}
  ;

kerning: {$$= (YYSTYPE)genere("",NULL);}
  | kerning KERNING {$$= (YYSTYPE)genere($1, "\\negAROBspace", NULL);
		   free($1);}
  ;
%%

#include <varargs.h>  
#include <malloc.h>
  
char * genere(va_alist)
     va_dcl
{
  char * chaine;
  static char * curr[10];
  int i, j, w, longueur;
  va_list pvar;
  va_start(pvar);

  i=0;
  longueur=0;
  
  while (curr[i]= (va_arg(pvar, char *)))
    longueur+= strlen(curr[i++]);
  
  va_end(pvar);
  
  chaine= (char *)malloc(sizeof(char)* (longueur +1));
  for (j=0, w=0; j< i; j++)
    {
      int k;
      for (k=0; curr[j][k]; k++)
	chaine[w++]= curr[j][k];
    }
  chaine[w]=0;
  return chaine;
}
 

yyerror(s)
     char *s;
{
  extern int yytext;
  printf("\n\n%s, pres de %s\n",s,yytext);
}

main()
{
  int yydebug;
  initialise_lex();  
  yydebug= 1;
  yyparse();
}
