%{ /* grammar used to build the parser, Copyright (C) 1991 Raphael Cerf (e-mail: cerf@ens.ens.fr) This file is part of xetal. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "proto.h" #include "glbl.h" #include "str.h" #include "stack.h" /* output macros */ /* flag for output */ #define out (mode!=-1 || d_macrodef) && (mode!=1 || d_math) && d_ok /* deleted text */ #define noprint(x) { int i; char *p=S; \ sprintf x ; \ c_skipped+=strlen(S); \ if (do_fill) { \ while ((*p!=(char)NULL)) { \ if (*p=='\n') ; \ else if (*p=='\t') ; \ else { \ *p=c_fill; \ } \ p++; \ } \ fprintf(stdout, "%s", S); \ } \ } /* displayed text */ #define doprint(x) { sprintf x; fprintf(stdout, "%s", S); } /* general output macro */ #define print(x, v) { if (out && v) doprint(x) \ else noprint(x) } %} /* * shift-reduces expected */ /*%expect 108*/ /* * stack type */ %union { char *y_str; /* string */ char y_chr; /* character */ int y_int; /* integer */ } /* * terminal symbols */ %token SLASH %token NULL_COMMAND %token FFEED OTHER %token '{' '}' '[' ']' %token BLS BLSNL %token LETTER DIGIT %token SLASHED %token BGIN END INCLUSION COMMAND UNKNOWN COMMENT %token VERB VERBATIM %token DEF CTLSEQ0 CTLSEQ1 CTLSEQ2 CTLSEQ3 CATCODE %token LATEX_DEF LATEX_DEFENV %token READ SETBOX FONT %token ASSIGN %token LATEX_PAR %token INT_PAR DIMEN_PAR GLUE_PAR MUGLUE_PAR TOKEN_PAR %token REGISTER %token OPERATION %token BOX %token DOLLAR DDOLLAR OPARE CPARE OBRAC CBRAC %token ANYTHING ANY_NOT_SLASH %token NOMBRE LETTRES CARACTERES REEL FILENAME %token ACCENT %token H1O1O_COMMAND %token H1O1_COMMAND H1O2_COMMAND %token H1OO1_COMMAND %token H1O_COMMAND H2O_COMMAND %token H2_COMMAND H3_COMMAND %token HO1_COMMAND HO2_COMMAND %token HOO1_COMMAND %token HO_COMMAND %token INCLUDEONLY %token INDENV SLOPENV MINIENV PICTENV %token K1_COMMAND H1_COMMAND %token KO1_COMMAND %token K_COMMAND H_COMMAND %token LISTENV FIGENV TABBENV TABUENV BIBLENV %token MATHENV TEXTENV /* * non terminal symbols */ %type r_accent %type def_mode %type environnement %type environnement_name %type lettres, fln %type filename %type math_environnement %type math_mode %type operator %type signe_ponctuation %type special %type text_mode %% tex : start lignes nl | start lignes end start_END lignes start_N ; start : { start_file(); } ; lignes : | entites ; entites : entite | entites entite ; entite : anything | any_not_slash | mot | phrase | lettre | ponctuation | macro | assignment | catcode_def | commande | commentaire | groupe | separateur | reste | error { empty_S_stack(); mode=0; start_N(); } ; anything : ANYTHING { print((S, "%s", $1), d_anything); } ; any_not_slash : ANY_NOT_SLASH { print_seq($1, d_mot && (mode!=0 || d_text)); } ; mot : LETTRES { print((S, "%s", $1), d_mot && (mode!=0 || d_text)) } ; phrase : CARACTERES { print((S, "%s", $1), d_mot && (mode!=0 || d_text)) } ; lettre : LETTER { print((S, "%c", $1), d_mot && (mode!=0 || d_text)) } ; ponctuation : signe_ponctuation { print((S, "%c", $1), d_punct && (mode!=0 || d_text)) } ; signe_ponctuation : '.' { $$='.'; } | ',' { $$=','; } | ';' { $$=';'; } | ':' { $$=':'; } | '!' { $$='!'; } | '?' { $$='?'; } | '`' { $$='`'; } | '\'' { $$='\''; } | SLASH { $$='\\'; } | '\"' { $$='\"'; } ; macro : start_SQ2 def o_spnl ctlseq o_spnl start_N def_mode oa lignes ca { mode=$7; } | latex_def start_ARG o_spnl hg_argument def_mode ho_argument hg_argument start_N { mode=$5; } | latex_defenv start_ARG o_spnl hg_argument def_mode ho_argument hg_argument o_spnl hg_argument start_N { mode=$5; } ; start_SQ2 : { start_SQ2(); } ; def : DEF { print((S, "%s", $1), d_command) } ; o_spnl : | spaces | spaces_newline ; spaces : BLS { if (d_bls) print((S, "%s", $1), d_bl) else print((S, "%s", " "), d_bl) } ; spaces_newline : BLSNL { print_blnl($1); } ; ctlseq : CTLSEQ0 { print_seq($1, d_command); } | CTLSEQ1 { print_seq($1, d_command); } | CTLSEQ2 { print_seq($1, d_command); } | CTLSEQ3 { print_seq($1, d_command); } | slashed o_ctlseq ; slashed : SLASHED { if (!do_fill_slash) print((S, "%c", $1), d_slashed) else print((S, "%c%c", '\\', $1), d_slashed) } ; o_ctlseq : | ctlseq ; start_N : { start_N(); } ; def_mode : { $$=mode; mode=-1; } oa : '{' { if (do_fill_acco) print((S, "%c", $1), d_command) } ; ca : '}' { if (do_fill_acco) print((S, "%c", $1), d_command) } ; latex_def : LATEX_DEF { print((S, "%s", $1), d_command) } ; start_ARG : { start_ARG(); } ; hg_argument : d_no entite d_yes ; ho_argument : o_spnl | o_spnl ob start_O_ARG d_no lignes d_yes cbrac start_N o_spnl ; start_O_ARG : { start_O_ARG(); } ; ob : '[' { print((S, "%c", '['), d_command) } ; d_no : { d_ok=0; } ; d_yes : { d_ok=1; } ; cbrac : CBRAC { print((S, "%c", ']'), d_command) } ; latex_defenv : LATEX_DEFENV { print((S, "%s", $1), d_command) } ; assignment : variable start_CAR def_mode o_spnl equal o_spnl value start_N { mode=$3; } | variable start_CAR def_mode o_spnl start_N { mode=$3; } | operation o_spnl variable start_CAR def_mode o_by value start_N { mode=$5; } | start_SQ1 read o_spnl ctlseq start_N | start_SQ1 setbox o_spnl ctlseq start_N o_spnl o_equal o_spnl entite | start_SQ1 font o_spnl ctlseq start_N o_spnl equal o_spnl filename { str_destroy($9); } | start_SQ3 assign o_spnl o_ctlseq start_N o_spnl def_mode o_equal entite { mode=$7; } ; variable : LATEX_PAR { print((S, "%s", $1), d_command) } | INT_PAR { print((S, "%s", $1), d_command) } | DIMEN_PAR { print((S, "%s", $1), d_command) } | GLUE_PAR { print((S, "%s", $1), d_command) } | MUGLUE_PAR { print((S, "%s", $1), d_command) } | TOKEN_PAR { print((S, "%s", $1), d_command) } | start_NB register nombre_unknown start_N ; start_NB : { start_NB(); } ; register : REGISTER { print((S, "%s", $1), d_command) } ; nombre_unknown : nombre | unknown_command ; nombre : NOMBRE { print((S, "%s", $1), d_command) } ; unknown_command : UNKNOWN { print((S, "%s", $1), d_command) } ; start_CAR : { start_CAR(); } ; equal : '=' { print((S, "%s", "="), d_command) } ; value : entite ; operation : OPERATION { print((S, "%s", $1), d_command) } ; o_by : o_spnl | o_spnl by o_spnl ; by : LETTRES { if (strcmp($1, "by")!=0) { fprintf(stderr, "by expected\n"); } print((S, "%s", $1), d_command) } ; start_SQ1 : { start_SQ1(); } ; read : READ { print((S, "%s", $1), d_command) } ; setbox : SETBOX { print((S, "%s", $1), d_command) } ; font : FONT { print((S, "%s", $1), d_command) } ; start_SQ3 : { start_SQ3(); } ; assign : ASSIGN { print((S, "%s", $1), d_command) } ; o_equal : o_spnl | o_spnl equal o_spnl ; catcode_def : start_SQ0 catcode ctlseq start_N def_mode o_spnl equal o_spnl value { mode=$5; } ; start_SQ0 : { start_SQ0(); } ; catcode : CATCODE { print((S, "%s", $1), d_command) } ; commande : begin_end_section | verb | math | box | accent | s_command | k_command | h_command | ho_command start_ARG ho_argument start_N | k1_command start_ARG o_spnl kg_argument start_N | ko1_command start_ARG ho_argument kg_argument start_N | h1_command start_ARG o_spnl hg_argument start_N | h2_command start_ARG o_spnl hg_argument o_spnl hg_argument start_N | h3_command start_ARG o_spnl hg_argument o_spnl hg_argument o_spnl hg_argument start_N | ho1_command start_ARG ho_argument hg_argument start_N | ho2_command start_ARG ho_argument hg_argument o_spnl hg_argument start_N | h1o1_command start_ARG o_spnl hg_argument ho_argument hg_argument start_N | h1o2_command start_ARG o_spnl hg_argument ho_argument hg_argument o_spnl hg_argument start_N | h1o_command start_ARG o_spnl hg_argument ho_argument start_N | h2o_command start_ARG o_spnl hg_argument o_spnl hg_argument ho_argument start_N | hoo1_command start_ARG ho_argument ho_argument hg_argument start_N | h1oo1_command start_ARG o_spnl hg_argument ho_argument ho_argument hg_argument start_N | h1o1o_command start_ARG o_spnl hg_argument ho_argument hg_argument ho_argument start_N | inclusion | unknown_command ; begin_end_section : bgin start_BE_ARG o_spnl oa environnement ca lignes end start_BE_ARG o_spnl oa environnement ca { if (strcmp($5, $12)!=0) { fprintf(stderr, "%s | %s not matching in begin_end\n", $5, $12); exit(2); } str_destroy($5); str_destroy($12); } ; bgin : BGIN { print((S, "%s", $1), d_command) } ; start_BE_ARG : { start_BE_ARG(); } ; environnement : environnement_name { $$=strdup($1); print((S, "%s", $1), d_command) } ; environnement_name : TEXTENV | LISTENV | FIGENV | TABBENV | TABUENV | BIBLENV | INDENV | SLOPENV | MINIENV | PICTENV | VERBATIM | UNKNOWN ; end : END { print((S, "%s", $1), d_command) } ; verb : VERB { char *p, sch, o; int l; p=$1+5;/* suppress \verb in string p */ if (*p=='*') p++; sch=*p;p++;o=*p;*p=(char)NULL; print((S, "%s", $1), d_command) *p=o;l=strlen(p); *(p+l-1)=(char)NULL; print_seq(p, d_mot && (mode!=0 || d_text)); print((S, "%c", sch), d_command) } ; math : bgin start_BE_ARG o_spnl oa math_environnement ca math_mode entites end start_BE_ARG o_spnl oa math_environnement ca { mode=$7; if (strcmp($5, $13)!=0) { fprintf(stderr, "%s | %s not matching in begin_end\n", $5, $13); exit(2); } str_destroy($5); str_destroy($13); } | math_mode dollar entites dollar { mode=$1; } | math_mode ddollar entites ddollar { mode=$1; } | math_mode opare entites cpare { mode=$1; } | math_mode obrac entites cbrac { mode=$1; } ; math_environnement : MATHENV { $$=strdup($1); print((S, "%s", $1), d_command) } ; math_mode : { $$=mode; mode=1; n_formule++; } ; dollar : DOLLAR { print((S, "%c", '$'), d_command) } ; ddollar : DDOLLAR { print((S, "%c%c", '$', '$'), d_command) } ; opare : OPARE { print((S, "%c", '('), d_command) } ; cpare : CPARE { print((S, "%c", ')'), d_command) } ; obrac : OBRAC { print((S, "%c", '['), d_command) } ; box : start_SQ1 box_name text_mode start_N groupe { mode=$3; } | start_SQ1 box_name o_spnl ctlseq start_N text_mode groupe { mode=$6; } ; box_name : BOX { print((S, "%s", $1), d_command) } ; text_mode : o_spnl { $$=mode; if (mode!=-1) mode=0; } ; groupe : oa lignes ca ; accent : r_accent o_spnl { if (d_accent) { if (s_accent==(char)NULL) { print((S, "%c", $1), (mode!=0 || d_text)) } else { print((S, "%c%c", s_accent, $1), (mode!=0 || d_text)) } } } ; r_accent : ACCENT { $$=$1[1]; } s_command : COMMAND { print((S, "%s", $1), d_command) } ; k_command : K_COMMAND { print((S, "%s", $1), d_command) } ; h_command : H_COMMAND { print((S, "%s", $1), d_command) } ; ho_command : HO_COMMAND { print((S, "%s", $1), d_command) } ; k1_command : K1_COMMAND { print((S, "%s", $1), d_command) } ; kg_argument : entite ; ko1_command : KO1_COMMAND { print((S, "%s", $1), d_command) } ; h1_command : H1_COMMAND { print((S, "%s", $1), d_command) } ; h2_command : H2_COMMAND { print((S, "%s", $1), d_command) } ; h3_command : H3_COMMAND { print((S, "%s", $1), d_command) } ; ho1_command : HO1_COMMAND { print((S, "%s", $1), d_command) } ; ho2_command : HO2_COMMAND { print((S, "%s", $1), d_command) } ; h1o1_command : H1O1_COMMAND { print((S, "%s", $1), d_command) } ; h1o2_command : H1O2_COMMAND { print((S, "%s", $1), d_command) } ; h1o_command : H1O_COMMAND { print((S, "%s", $1), d_command) } h2o_command : H2O_COMMAND { print((S, "%s", $1), d_command) } ; hoo1_command : HOO1_COMMAND { print((S, "%s", $1), d_command) } ; h1oo1_command : H1OO1_COMMAND { print((S, "%s", $1), d_command) } ; h1o1o_command : H1O1O_COMMAND { print((S, "%s", $1), d_command) } ; inclusion : INCLUDEONLY start_FLN filename start_N { char *p=$3;int i, old_n_ionly; if (n_ionly==-1) n_ionly=0; old_n_ionly=n_ionly; if ((if_name[n_ionly++]=strtok(p, ","))!=(char *)NULL) { p=(char *)NULL; while ((if_name[n_ionly++]=strtok(p, ","))!=(char *)NULL); n_ionly--; for (i=old_n_ionly; i' { $$='>'; } | '(' { $$='('; } | ')' { $$=')'; } | '@' { $$='@'; } | '[' { $$='['; } | ']' { $$=']'; } ; special : '#' { $$='#'; } | '%' { $$='%'; } | '&' { $$='&'; } | '\\' { $$='\\'; } | '^' { $$='^'; } | '_' { $$='_'; } | '~' { $$='~'; } ; other : OTHER { print((S, "\\ASCII:%d ", yylval.y_chr), d_warning) } | FFEED { print((S, "%c", 12), d_mot && (mode!=0 || d_text)) } ; nl : { if (d_nl) doprint((S, "%s", "\n")) } ; start_END : { start_END(); } ; %% /* * yyerror function for LEX */ yyerror(s) char *s; { if (d_error) { if ((strcmp("", f_name)!=0)) fprintf(stderr, "[%s:%d] %s\n", f_name, lineno+1, s); else fprintf(stderr, "[%d] %s", lineno+1, s); } } /* * display new file name */ int start_file() { if (n_nl && ((lineno+1) % N == 0)) { if ((strcmp("", f_name)==0) || (d_fname==0)) doprint((S, "[%d] ", lineno+1)) else { if (d_fname==-1) d_fname=0; doprint((S, "[%s:%d] ", f_name, lineno+1)) } } else if (n_nl) { if (d_fname==-1) d_fname=0; if (strcmp("", f_name)!=0) doprint((S, "[%s] ", f_name)) } } /* * ouput a \n with line number if necessary */ print_nl() { if (d_nl) doprint((S, "%s", "\n")) if (n_nl && ((lineno+2) % N == 0)) { if ((strcmp("", f_name)==0) || (d_fname==0)) doprint((S, "[%d] ", lineno+2)) else { if (d_fname==-1) d_fname=0; doprint((S, "[%s:%d] ", f_name, lineno+2)) } } lineno++; } /* * output a sequence containing blanks * and possibly a \n */ print_blnl(s) char *s; { char *p=strchr(s, '\n'); *p=(char)NULL; if (strlen(s)>0) if (d_bls) print((S, "%s", s), d_bl) else print((S, "%s", " "), d_bl) *p='\n'; if (d_nl) doprint((S, "%s", "\n")) if (n_nl && ((lineno+2) % N == 0)) { if ((strcmp("", f_name)==0) || (d_fname==0)) { doprint((S, "[%d] ", lineno+2)) } else { if (d_fname==-1) d_fname=0; doprint((S, "[%s:%d] ", f_name, lineno+2)) } } if (*(p+1)!=(char)NULL) if (d_bls) print((S, "%s", p+1), d_bl) else print((S, "%s", " "), d_bl) lineno++; } /* * output a sequence of characters * eventually containing several \n */ print_seq(p, flg) char *p; int flg; { char *q; q=p; while (*q!=(char)NULL) { while (*q!='\n' && *q!=(char)NULL) q++; if (*q=='\n') { *q=(char)NULL; if (strlen(p)>0) print((S, "%s", p), flg) print_nl(); p=++q; } else { if (strlen(p)>0) print((S, "%s", p), flg) } } }