sxparser.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *                                S Y N T A X
00003  *-----------------------------------------------------------------------------
00004  *   Copyright (C) 1972-2008 INRIA (Institut National de Recherche en
00005  *   Informatique et Automatique)
00006  *-----------------------------------------------------------------------------
00007  *   URL: http://syntax.gforge.inria.fr
00008  *-----------------------------------------------------------------------------
00009  *   The source code of SYNTAX is distributed with two different licenses,
00010  *   depending on the files:
00011  *   - The recursive content of src/ and incl/ and the non-recursive content
00012  *     of SYNTAX's root directory are distributed under the CeCILL-C license
00013  *   - The recursive content of all other repertories is distributed under
00014  *     the CeCILL license
00015  *   All code produced by SYNTAX must be considered as being under the
00016  *   CeCILL-C license. Information about the CeCILL and CeCILL-C licenses
00017  *   can be found at, e.g., http://www.cecill.fr
00018  *****************************************************************************/
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 static char ME [] = "PARSER";
00030 
00031 #include "sxversion.h"
00032 #include "sxunix.h"
00033 #ifndef VARIANT_32
00034 char WHAT_SXPARSER[] = "@(#)SYNTAX - $Id: sxparser.c 1416 2008-06-25 14:42:55Z rlacroix $" WHAT_DEBUG;
00035 #else
00036 char WHAT_SXPARSER32[] = "@(#)SYNTAX - $Id: sxparser.c 1416 2008-06-25 14:42:55Z rlacroix $ SXPARSER_32" WHAT_DEBUG;
00037 #endif
00038 
00039 /*   V A R I A B L E S   */
00040 
00041 /* Variables which must be kept "local" to each recursive invocation of the
00042    parser are in the global variable "sxplocals", of type "struct sxplocals".
00043 */
00044 
00045 static SXINT    lgt1, lgt2;
00046 static SXP_SHORT    *stack /* lgt1 */;
00047 static SXBOOLEAN    bscan;
00048 static struct gstack {
00049     SXINT       top, bot;
00050     SXP_SHORT   *stack /* lgt2 */;
00051     SXP_SHORT   state;
00052 } ga, gb;
00053 
00054 
00055 
00056 SXP_SHORT       sxP_access (struct SXP_bases *abase, SXINT j)
00057 {
00058     struct SXP_item *ajvector, *ajrefvector;
00059     SXP_SHORT   ref = abase->commun;
00060 
00061     if (ref <= sxplocals.SXP_tables.Mref /* codage direct */ ) {
00062     if (abase->propre == j /* checked */ )
00063         return ref;
00064     else
00065         return abase->defaut;
00066     }
00067 
00068     if ((ajrefvector = (ajvector = sxplocals.SXP_tables.vector + j) + ref)->check == j)
00069     /* dans commun */
00070     return ajrefvector->action;
00071 
00072     if ((ref = abase->propre) != 0 /* propre est non vide */  &&
00073     (ajrefvector = ajvector + ref)->check == j)
00074     /* dans propre */
00075     return ajrefvector->action;
00076 
00077     return abase->defaut;
00078 }
00079 
00080 
00081 static SXVOID   execute_actions (struct gstack *s1)
00082 {
00083     /* Caracteristique de s1 :
00084        - elle contient exactement un Scan
00085        - elle ne contient pas de Scan en LookAhead
00086        - elle se termine par un Shift
00087        Apres execution le token du sommet de la parse_stack est donc non significatif */
00088 
00089     SXP_SHORT   x, state, ref;
00090     struct SXP_reductions   *ared;
00091 
00092     for (x = s1->bot /* bottom */  + 1; x <= s1->top; x++) {
00093     if ((ref = s1->stack [x]) > 0) {
00094         /* Scan */
00095         sxpglobals.parse_stack [sxpglobals.xps].token = SXGET_TOKEN (sxplocals.atok_no);
00096         sxplocals.atok_no++;
00097     }
00098     else {
00099         /* NoScan */
00100         ref = -ref;
00101     }
00102 
00103     if ((state = ref - sxplocals.SXP_tables.Mprdct) > 0 /* Shift */ ) {
00104         sxpglobals.parse_stack [++sxpglobals.xps].state = state;
00105     }
00106     else
00107          /* Reduce or Halt */
00108          if ((sxpglobals.reduce =
00109           (ared = sxplocals.SXP_tables.reductions + ref)->reduce) != 0 /* Reduce */ ) {
00110         SXBOOLEAN   is_semact = 
00111         sxpglobals.reduce <= sxplocals.SXP_tables.P_nbpro && ared->action < 10000;
00112 
00113         sxpglobals.pspl = ared->lgth;
00114 
00115         if (ref > sxplocals.SXP_tables.Mrednt && s1->stack [x] <= 0) {
00116         /* Reduce dans les T_tables sans Scan */
00117 
00118         if (sxpglobals.pspl-- == 0)
00119             /* production vide */
00120             sxpglobals.parse_stack [sxpglobals.xps].token.source_index =
00121             SXGET_TOKEN (sxplocals.atok_no).source_index;
00122 
00123         sxpglobals.xps--;
00124         }
00125 
00126         if (is_semact) {
00127         if (sxplocals.mode.with_semact)
00128             (*sxplocals.SXP_tables.semact) (SXACTION, ared->action);
00129         }
00130         else
00131         if (sxplocals.mode.with_parsact)
00132             (*sxplocals.SXP_tables.parsact) (SXACTION, ared->action);
00133 
00134         sxpglobals.xps -= sxpglobals.pspl;
00135         sxpglobals.parse_stack [sxpglobals.xps].token.lahead =
00136         is_semact ? 0 /* nt */  : -1 /* action */ ;
00137     }
00138     }
00139 
00140     if (sxplocals.mode.look_back != 0)
00141     /* Ces tokens deviennent inaccessibles. */
00142     sxplocals.left_border = sxplocals.atok_no - sxplocals.mode.look_back;
00143 
00144     s1->top = s1->bot /* top = bottom, empty the stack */ ;
00145 }
00146 
00147 
00148 static SXINT undo_actions (struct gstack *s1, SXINT xs)
00149 {
00150     /* On doit "defaire" les actions eventuelles de s1, en ordre inverse de
00151        leur execution en assurant la coherence des indices de pile d'analyse. */
00152 
00153     SXP_SHORT   x, ref;
00154     struct SXP_reductions   *ared;
00155 
00156     for (x = s1->top; x > s1->bot; x--) {
00157     if ((ref = s1->stack [x]) != 0) {
00158         if (ref > 0)
00159         /* Scan undo */
00160         /* --sxplocals.ptok_no */;
00161         else
00162         /* NoScan */
00163         ref = -ref;
00164 
00165         if ((ref - sxplocals.SXP_tables.Mprdct) > 0 /* Shift */ )
00166         /* pop */
00167         --xs;
00168         else {
00169         /* Reduce */
00170         ared = sxplocals.SXP_tables.reductions + ref;
00171         xs += ared->lgth;
00172 
00173         if (ared->reduce > sxplocals.SXP_tables.P_nbpro || ared->action >= 10000) {
00174             SXINT old_xps = sxpglobals.xps;
00175 
00176             sxpglobals.reduce = ared->reduce;
00177             sxpglobals.pspl = ared->lgth; /* 0 */
00178             sxpglobals.xps = xs;
00179 
00180             if (ref > sxplocals.SXP_tables.Mrednt && s1->stack [x] <= 0) {
00181             /* Reduce dans les T_tables sans Scan */
00182             sxpglobals.pspl--;
00183             sxpglobals.xps--;
00184             }
00185 
00186             (*sxplocals.SXP_tables.parsact) (SXUNDO, ared->action);
00187 
00188             sxpglobals.xps = old_xps;
00189         }
00190         }
00191     }
00192     }
00193 
00194     s1->top = s1->bot /* top = bottom, empty the stack */ ;
00195 
00196     return xs;
00197 }
00198 
00199 
00200 
00201 static SXVOID   sxpsature (SXINT nbt)
00202 
00203 /* overflow of tables for normal analysis */
00204     
00205 
00206 {
00207     switch (nbt) {
00208     case 1:
00209     lgt1 *= 2;
00210     sxpglobals.parse_stack = (struct sxparstack*) sxrealloc (sxpglobals.parse_stack, lgt1 + 1,
00211                                  sizeof (struct sxparstack));
00212     stack = (SXP_SHORT*) sxrealloc (stack, lgt1 + 1, sizeof (SXP_SHORT));
00213     break;
00214 
00215     case 2:
00216     lgt2 *= 2;
00217     ga.stack = (SXP_SHORT*) sxrealloc (ga.stack, lgt2 + 1, sizeof (SXP_SHORT));
00218     gb.stack = (SXP_SHORT*) sxrealloc (gb.stack, lgt2 + 1, sizeof (SXP_SHORT));
00219     break;
00220     default: /* pour faire taire gcc -Wswitch-default */
00221 #if EBUG
00222     sxtrap(ME,"unknown switch case #1");
00223 #endif
00224       break;
00225     }
00226 }
00227 
00228 SXP_SHORT   ARC_traversal (SXP_SHORT ref, SXINT latok_no)
00229 {
00230     SXP_SHORT   next;
00231     SXP_SHORT       t_state;
00232 
00233     /* First scan in LookAhead */
00234     next = ref + sxplocals.SXP_tables.Mref /* next < 0 */;
00235 
00236     do {
00237     ref = sxP_access (sxplocals.SXP_tables.t_bases + (t_state = -next),
00238             sxget_token (++latok_no)->lahead);
00239 
00240     if (ref < -sxplocals.SXP_tables.Mred && ref >= -sxplocals.SXP_tables.Mprdct) {
00241         /* Execution d'un predicat en look-ahead */
00242         struct SXP_prdct    *aprdct = sxplocals.SXP_tables.prdcts - ref;
00243         SXINT ptok_no;
00244 
00245         ptok_no = sxplocals.ptok_no;
00246         sxplocals.ptok_no = latok_no;
00247 
00248         while (aprdct->prdct >= 0 /* User's predicate */  &&
00249            (!sxplocals.mode.with_parsprdct ||
00250             !(*sxplocals.SXP_tables.parsact) (SXPREDICATE, aprdct->prdct)))
00251         /* returning False */ 
00252         aprdct++;
00253 
00254         ref = aprdct->action;
00255         sxplocals.ptok_no = ptok_no;
00256     }
00257     } while ((next = ref + sxplocals.SXP_tables.Mref) < 0);
00258 
00259     /* LookAhead ends */
00260     if (ref == 0) {
00261     /* Error in LookAhead */
00262     (*sxplocals.SXP_tables.recovery) (SXERROR, &t_state, latok_no);
00263     ref = t_state;
00264     }
00265 
00266     return ref;
00267 }
00268 
00269 
00270 
00271 /*
00272 Afin de permettre des corrections d'erreur sur l'unite' lexicale
00273 (t0) precedent celle (t1) sur laquelle une erreur a ete detectee et
00274 cela sans avoir a defaire le resultat des actions indument executees,
00275 l'execution des actions (syntaxiques et semantiques) est "retardee"
00276 par rapport a l'analyse syntaxique proprement dite.  Cet effet est
00277 obtenu en utilisant deux piles s1 et s2.  s1 est la pile des actions
00278 en retard et s2 est la pile des actions courantes.
00279 
00280 Les actions de s1 sont executees lorsque l'instruction qui vient
00281 d'etre empilee dans s2 est un scan ( t1 * () ...  ou t1 * red p ...).
00282 On est alors certain que le terminal t1, teste par cette instruction,
00283 est correct -- aucune erreur ne sera detectee ici--, le terminal t0 ne
00284 sera donc jamais modifie par une correction d'erreur eventuelle et les
00285 actions associees contenues dans s1 peuvent donc s'executer.
00286 
00287 On echange les piles s1 et s2 (s1 doit etre vide) lorsque la derniere
00288 instruction empilee dans s2 est le premier shift suivant le scan de
00289 s2.  On est sur qu'entre ces deux instructions:
00290   - aucun test explicite du terminal scanne ne s'est produit
00291    - il n'y a aucune parsact
00292 
00293 Apres echange, l'etat atteint par l'instruction shift est stocke en
00294 s2[-1], ce sera l'etat utilise par la recuperation d'erreur.  Une pile
00295 si contient donc exactement une et une seule instruction scan, se
00296 termine par une instruction shift et l'instruction de fond de pile est
00297 une Action de l'etat si[-1].  Le terminal associe a la pile s2 est
00298 celui qui a ete lu par l'instruction scan de la pile s1.
00299 
00300 Cependant, afin de "rapprocher" les parsact eventuelles des predicats
00301 pouvant les utiliser, on execute la pile en retard a la vue d'un
00302 terminal etendu (le terminal associe est le symbol courant du source).
00303 La verification n'etant pas complete, si une erreur est detectee par
00304 les predicats associes, la correction correspondante ne peut toucher a
00305 t0, il faut donc le signaler a l'error_recovery.  Lors de la detection
00306 d'erreur, si la pile en retard s1 "contient" un predicat &i, elle est
00307 egalement executee et aucune correction d'erreur ne sera tentee sur
00308 t0.  La raison en est que nous ne sommes pas sur que l'execution
00309 passee de &i, son execution au cours du rattrapage d'erreur et sa
00310 future execution apres rattrapage donnent le meme resultat.
00311 */
00312 
00313 
00314 static SXBOOLEAN    sxparse_it (void)
00315 {
00316     SXP_SHORT           ref;
00317     SXINT                       lahead;
00318     SXP_SHORT                   state;
00319     SXINT           xs;
00320     struct SXP_reductions   *ared;
00321     struct gstack   *s1 = &ga, *s2 = &gb;
00322 
00323 /*
00324 
00325 !scan (lascan si < -Mref)                                    scan
00326 ------------^-------------\/-----------------------------------^---------------------------------
00327                           0         Mrednt          Mred    Mprdct              Mfe M0ref  Mref
00328 --------------------------|------------|--------------|-------|------------------|----|------|--->
00329                            \___________/
00330                           trans sur nt
00331                            \__________________________/\______/\_________________________________
00332                                     reduction           prdct              shift
00333 
00334 
00335                                                ^
00336                                                | acces vector [ref]
00337                                          Mref  -
00338                            | Shift: goto t_bases[ref-Mprdct]
00339                                                |    empiler 0
00340                                         M0ref  -
00341                            | Shift: acces [n]t_bases[ref-Mprdct]
00342                                                |    (etat!=etq)
00343                                           Mfe  -
00344                                                | Shift: acces [n]t_bases[ref-Mprdct]
00345                                                |    (etat==etq)
00346                                        Mprdct  -
00347                                                | Prdct: acces Predicates [-ref]
00348                                                |
00349                                          Mred  -
00350                                                | Reduce: acces Reductions [ref]
00351                                                |
00352                                        Mrednt  -
00353                                                | Reduce: acces Reductions [ref]
00354                                                | (sur transition non terminale)
00355                                                |
00356                                             0  - Error
00357                                               ref
00358 
00359 
00360 */
00361 
00362 /* ******************************************************************** */
00363 
00364 /* initializations */
00365 
00366     xs = sxpglobals.xps = sxpglobals.stack_bot;
00367     stack [xs] = 0;
00368     sxpglobals.parse_stack [xs].state = 0;
00369     lahead = sxplocals.SXP_tables.P_tmax;
00370     sxplocals.state = sxplocals.SXP_tables.init_state;
00371     state = (SXP_SHORT) sxplocals.state;
00372 
00373 /* (*(sxplocals.SXP_tables.semact)) (SXINIT, lgt1); */
00374 
00375 restart:
00376     ref = sxP_access (sxplocals.SXP_tables.t_bases + (s2->state = state), lahead);
00377     s1->top = s1->bot /* top = bottom, empty the stacks */ ;
00378     s2->top = s2->bot;
00379     bscan = SXFALSE;
00380 
00381 
00382 /* Swap de s1 et s2 : premiere etiquette apres scan
00383    Evaluation de s1 : premier test explicite */
00384 
00385     for (;;) {
00386     if (ref < -sxplocals.SXP_tables.Mref)
00387         ref = ARC_traversal (ref, sxplocals.ptok_no);
00388 
00389     /* memorisation de l'action courante */
00390     if (++s2->top > lgt2) {
00391         sxpsature ((SXINT)2);
00392     }
00393 
00394     s2->stack [s2->top] = ref;
00395 
00396     if (ref > 0 /* scan */ ) {
00397         SXINT n;
00398 
00399         if (s1->bot != s1->top)
00400         execute_actions (s1);
00401 
00402         n = ++sxplocals.ptok_no;
00403 
00404         while (n > sxplocals.Mtok_no)
00405         (*(sxplocals.SXP_tables.scanit)) ();
00406 
00407         lahead = SXGET_TOKEN (n).lahead;
00408         bscan = SXTRUE;
00409     }
00410     else
00411         ref = -ref;
00412 
00413     if ((state = ref - sxplocals.SXP_tables.Mprdct) > 0 /* Shift */ ) {
00414         if (++xs > lgt1)
00415         sxpsature ((SXINT)1);
00416 
00417         if (state <= sxplocals.SXP_tables.M0ref)
00418         stack [xs] = state;
00419         /* else empile 0 */
00420 
00421         if (bscan) {
00422         struct gstack   *pp;
00423 
00424         bscan = SXFALSE;
00425         /* swap s1 <-> s2, s1 doit etre vide */
00426         pp = s1, s1 = s2, s2 = pp;
00427         s2->state = state;
00428         }
00429 
00430         ref = sxP_access (sxplocals.SXP_tables.t_bases + state, (SXINT)lahead);
00431     }
00432     else if (ref <= sxplocals.SXP_tables.Mred /* Reduce, Error or Halt */ ) {
00433         if (ref == 0 /* error recovery */ ) {
00434           if (sxplocals.mode.is_prefixe && state == (SXP_SHORT) sxplocals.SXP_tables.final_state)
00435             return SXTRUE;
00436 
00437         sxplocals.mode.local_errors_nb++;
00438 
00439         if (sxplocals.mode.kind == SXWITHOUT_ERROR)
00440             return SXFALSE;
00441 
00442         if (sxplocals.mode.with_do_undo && sxplocals.mode.with_parsact)
00443         {
00444             /* Ds le cas SXDO/SXUNDO, on essaie une correction sur le token
00445                precedent. */
00446             /* Il faut "defaire" les parsact eventuelles executees ds s2 et s1. */
00447             if (s2->bot != s2->top)
00448             xs = undo_actions (s2, xs);
00449 
00450             if (s1->bot != s1->top)
00451             xs = undo_actions (s1, xs);
00452         }
00453         else
00454         {
00455             if (s1->bot != s1->top && s1->state < 0) /* Predicat dans s1 non vide */
00456             /* On ne touche pas au token precedent */
00457             execute_actions (s1);
00458         }
00459         
00460         sxplocals.state = (SXINT) ((sxplocals.ptok_no == sxplocals.atok_no) ? labs ((long)s2->state) : s1->state);
00461 
00462         if ((*sxplocals.SXP_tables.recovery) (SXACTION)) {
00463             /* Succes */
00464             SXINT   i;
00465             
00466             xs = sxpglobals.xps;
00467             
00468             for (i = sxpglobals.stack_bot + 1; i <= xs; i++) {
00469             /* stack [stack_bot] == 0 */
00470             /* restauration de la pile */
00471             stack [i] = sxpglobals.parse_stack [i].state;
00472             }
00473             
00474             lahead = SXGET_TOKEN (sxplocals.ptok_no).lahead;
00475             state = (SXP_SHORT) sxplocals.state;
00476             goto restart;
00477         }
00478         
00479         /* Failure */
00480         return SXFALSE;
00481         }
00482 
00483 /* Reduce or Halt */
00484 
00485         if ((ared = sxplocals.SXP_tables.reductions + ref)->reduce == 0 /* Halt */ ) {
00486         if (s1->bot != s1->top)
00487             /* On vide s1 */
00488             execute_actions (s1);
00489 
00490         if (s2->bot != s2->top) {
00491             /* puis s2 */
00492             execute_actions (s2);
00493         }
00494 
00495         break;
00496         }
00497 
00498         {
00499         /* Reduce */
00500         SXP_SHORT   nt;
00501 
00502         if ((ared->reduce > sxplocals.SXP_tables.P_nbpro || ared->action >= 10000) &&
00503             sxplocals.mode.with_do_undo &&
00504             sxplocals.mode.with_parsact)
00505         {
00506             /* parsact a executer immediatement */
00507             /* Ca permet aux parsact de manipuler une structure // a stack en
00508                utilisant les macros SXSTACKtop(), SXSTACKnewtop() et SXSTACKreduce(). */
00509             SXINT old_xps = sxpglobals.xps;
00510 
00511             sxpglobals.reduce = ared->reduce;
00512             sxpglobals.pspl = ared->lgth; /* 0 */
00513             sxpglobals.xps = xs;
00514 
00515             if (ref > sxplocals.SXP_tables.Mrednt && s2->stack [s2->top] <= 0) {
00516             /* Reduce dans les T_tables sans Scan */
00517             sxpglobals.pspl--;
00518             sxpglobals.xps--;
00519             }
00520 
00521             (*sxplocals.SXP_tables.parsact) (SXDO, ared->action);
00522 
00523             sxpglobals.xps = old_xps;
00524         }
00525 
00526         xs -= ared->lgth;
00527 
00528         if ((nt = (ref = ared->lhs) - sxplocals.SXP_tables.Mref) > 0) {
00529             /* pas branchement direct */
00530             state = stack [xs];
00531             ref = sxP_access (sxplocals.SXP_tables.nt_bases + state, (SXINT)nt); 
00532         }
00533         }
00534     }
00535     else {
00536         /* Predicates */
00537         struct SXP_prdct    *aprdct = sxplocals.SXP_tables.prdcts + ref;
00538         SXINT old_xps;
00539 
00540         if (!sxplocals.mode.with_do_undo && s1->bot != s1->top)
00541         execute_actions (s1);
00542 
00543         --s2->top /* On ecrase le predicat */ ;
00544 
00545         /* Au cas ou le predicat est associe' a un nt et il veut re'fe'rencer
00546            une structure // a` stack. Il faut utiliser SXSTACKtop () */
00547         old_xps = sxpglobals.xps;
00548         sxpglobals.xps = xs; 
00549 
00550         while (aprdct->prdct >= 0 /* User's predicate */  &&
00551            (!sxplocals.mode.with_parsprdct ||
00552             !(*sxplocals.SXP_tables.parsact) (SXPREDICATE, aprdct->prdct)))
00553         /* returning False */ 
00554         aprdct++;
00555 
00556         sxpglobals.xps = old_xps;
00557 
00558         ref = aprdct->action;
00559 
00560         if (s2->state > 0)
00561         s2->state = -s2->state /* On note la presence de predicats ds s2 */;
00562     }
00563     }
00564 
00565     sxtkn_mngr (SXFINAL, 0);
00566     return SXTRUE;
00567 }
00568 
00569 
00570 
00571 
00572 SXBOOLEAN sxparser (SXINT   what_to_do, struct sxtables *arg)
00573 {
00574     switch (what_to_do) {
00575     case SXBEGIN:
00576 
00577 /* global initialization */
00578 
00579     lgt1 = 200;
00580     lgt2 = 50;
00581 
00582 /* allocate arrays for normal analysis */
00583 
00584     sxpglobals.parse_stack = (struct sxparstack*) sxalloc (lgt1 + 1,
00585                                    sizeof (struct sxparstack));
00586     stack = (SXP_SHORT*) sxalloc (lgt1 + 1, sizeof (SXP_SHORT));
00587     ga.stack = (SXP_SHORT*) sxalloc (lgt2 + 1, sizeof (SXP_SHORT));
00588     gb.stack = (SXP_SHORT*) sxalloc (lgt2 + 1, sizeof (SXP_SHORT));
00589     sxpglobals.xps = 0;
00590     sxpglobals.stack_bot = 0;
00591     ga.top = ga.bot = gb.top = gb.top = 1; /* top, bottom  = 1; */ 
00592     break;
00593 
00594     case SXOPEN:
00595     /* new language: new tables, new local parser variables */
00596     /* the global variable "sxplocals" must have been saved in case */
00597     /* of recursive invocation */
00598 
00599     /* test arg->magic for consistency */
00600     sxcheck_magic_number (arg->magic, SXMAGIC_NUMBER, ME);
00601 
00602 /* prepare new local variables */
00603 
00604     sxplocals.sxtables = arg;
00605     sxplocals.SXP_tables = arg->SXP_tables;
00606     sxtkn_mngr (SXOPEN, 2);
00607     (*sxplocals.SXP_tables.recovery) (SXOPEN);
00608     break;
00609 
00610     case SXINIT:
00611     /* on initialise toks_buf avec "EOF" */
00612 
00613     {
00614     struct sxtoken tok;
00615 
00616     sxtkn_mngr (SXINIT, 0);
00617     /* terminal_token EOF */
00618     tok.lahead = sxplocals.SXP_tables.P_tmax;
00619     tok.string_table_entry = SXEMPTY_STE;
00620     tok.source_index = sxsrcmngr.source_coord;
00621     tok.comment = NULL;
00622     SXGET_TOKEN (0) = tok;
00623     }
00624     
00625     /* analyse normale */
00626     /* valeurs par defaut qui peut etre changee ds les
00627        scan_act ou pars_act. */
00628     sxplocals.mode.look_back = 1; 
00629     sxplocals.mode.mode = SXPARSER;
00630     sxplocals.mode.kind = SXWITH_RECOVERY;
00631     sxplocals.mode.local_errors_nb = 0;
00632     sxplocals.mode.global_errors_nb = 0;
00633     sxplocals.mode.is_prefixe = SXFALSE;
00634     sxplocals.mode.is_silent = SXFALSE;
00635     sxplocals.mode.with_semact = SXTRUE;
00636     sxplocals.mode.with_parsact = SXTRUE;
00637     sxplocals.mode.with_parsprdct = SXTRUE;
00638     sxplocals.mode.with_do_undo = SXFALSE;
00639     break;
00640 
00641     case SXACTION:
00642     {
00643         /* new file or portion of file */
00644         /* arg is pointer to tables, but "sxplocals" should be allright */
00645 
00646         SXINT       old_stack_bot = sxpglobals.stack_bot;
00647         SXP_SHORT   old_ga_state = ga.state, old_gb_state = gb.state;
00648         SXINT       old_ga_bot = ga.bot, old_ga_top = ga.top, old_gb_bot = gb.bot, old_gb_top = gb.top;
00649         SXINT   reduce = sxpglobals.reduce;
00650         SXINT   pspl = sxpglobals.pspl;
00651         SXBOOLEAN   old_bscan = bscan;
00652         SXBOOLEAN   ret_val;
00653 
00654         if ((sxpglobals.stack_bot = sxpglobals.xps + 5) > lgt1)
00655         sxpsature ((SXINT)1);
00656 
00657         ga.bot = ga.top;
00658         gb.bot = gb.top;
00659 
00660         ret_val = sxparse_it ();
00661 
00662         sxpglobals.reduce = reduce;
00663         sxpglobals.pspl = pspl;
00664         sxpglobals.xps = sxpglobals.stack_bot - 5;
00665         sxpglobals.stack_bot = old_stack_bot;
00666         bscan = old_bscan;
00667         ga.bot = old_ga_bot;
00668         ga.top = old_ga_top;
00669         ga.state = old_ga_state;
00670         gb.bot = old_gb_bot;
00671         gb.top = old_gb_top;
00672         gb.state = old_gb_state;
00673         return ret_val;
00674     }
00675 
00676     case SXFINAL:
00677     sxtkn_mngr (SXFINAL, 0);
00678     break;
00679 
00680     case SXCLOSE:
00681     /* end of language: free the local arrays */
00682     sxtkn_mngr (SXCLOSE, 0);
00683     (*sxplocals.SXP_tables.recovery) (SXCLOSE);
00684     break;
00685 
00686     case SXEND:
00687     /* free everything */
00688     sxfree (gb.stack), gb.stack = NULL;
00689     sxfree (ga.stack), ga.stack = NULL;
00690     sxfree (stack), stack = NULL;
00691     sxfree (sxpglobals.parse_stack), sxpglobals.parse_stack = NULL;
00692     break;
00693 
00694     default:
00695     fprintf (sxstderr, "The function \"sxparser\" is out of date with respect to its specification because \"what_to_do\" has value %ld = 0x%lx\n",(long)what_to_do,(long)what_to_do);
00696     sxexit(1);
00697         /*NOTREACHED*/
00698     }
00699 
00700     return SXTRUE;
00701 }
00702 
00703 
00704 SXBOOLEAN sxparse_in_la (SXINT ep_la, SXINT Ttok_no, SXINT *Htok_no, struct sxparse_mode *mode_ptr)
00705 {
00706     /* Appel recursif du parser pour verifier si le sous-langage defini par
00707        le point d'entree ep_la contient un prefixe du source. */
00708     /* Le token caracteristique du point d'entree est memorise en Ttok_no */
00709     /* L'indice du dernier token analyse par cet appel est range en Htok_no */
00710     SXINT       atok_no, ptok_no, old_left_border;
00711     SXBOOLEAN           ret_val;
00712     struct sxtoken      old_tt, *ptt;
00713     struct sxparse_mode     old_mode;
00714 
00715     /* On memorise qq petites choses */
00716     atok_no = sxplocals.atok_no;
00717     ptok_no = sxplocals.ptok_no;
00718     old_mode = sxplocals.mode;
00719     old_left_border = sxplocals.left_border;
00720     sxplocals.mode = *mode_ptr;
00721     /* On ne touche pas a left-border, une recuperation de place peut donc survenir
00722        pendant le look-ahead, mais ds ce cas il recuperera de la place avant l'indice
00723        de depart. */
00724     old_tt = *(ptt = &(SXGET_TOKEN (Ttok_no)));
00725     
00726     /* On change le token courant par le point d'entree */
00727     ptt->lahead = ep_la;
00728     ptt->string_table_entry = SXEMPTY_STE;
00729     /* On pointe sur le token precedent (normalement non acce'de') */
00730     sxplocals.atok_no = sxplocals.ptok_no = Ttok_no - 1;
00731     
00732     /* appel recursif */
00733     ret_val = (*(sxplocals.sxtables->analyzers.parser)) (SXACTION, sxplocals.sxtables);
00734     
00735     /* dernier token lu par l'appel precedent. */
00736     *Htok_no = sxplocals.ptok_no;
00737 
00738     /* On remet en place */
00739     *ptt = old_tt;
00740     sxplocals.atok_no = atok_no;
00741     sxplocals.ptok_no = ptok_no;
00742     mode_ptr->local_errors_nb = sxplocals.mode.local_errors_nb;
00743     mode_ptr->global_errors_nb = sxplocals.mode.global_errors_nb;
00744     /* L'appelant decide (et le fait) si le nombre d'erreur doit
00745        etre cumule'. */
00746     sxplocals.mode = old_mode;
00747     sxplocals.left_border = old_left_border;
00748 
00749     return ret_val;
00750 }

Generated on Wed Apr 21 16:39:34 2010 for syntax-6.0b7 by  doxygen 1.6.1