/src/Python-3.8.3/Parser/acceler.c
Line  | Count  | Source  | 
1  |  |  | 
2  |  | /* Parser accelerator module */  | 
3  |  |  | 
4  |  | /* The parser as originally conceived had disappointing performance.  | 
5  |  |    This module does some precomputation that speeds up the selection  | 
6  |  |    of a DFA based upon a token, turning a search through an array  | 
7  |  |    into a simple indexing operation.  The parser now cannot work  | 
8  |  |    without the accelerators installed.  Note that the accelerators  | 
9  |  |    are installed dynamically when the parser is initialized, they  | 
10  |  |    are not part of the static data structure written on graminit.[ch]  | 
11  |  |    by the parser generator. */  | 
12  |  |  | 
13  |  | #include "Python.h"  | 
14  |  | #include "grammar.h"  | 
15  |  | #include "node.h"  | 
16  |  | #include "token.h"  | 
17  |  | #include "parser.h"  | 
18  |  |  | 
19  |  | /* Forward references */  | 
20  |  | static void fixdfa(grammar *, const dfa *);  | 
21  |  | static void fixstate(grammar *, state *);  | 
22  |  |  | 
23  |  | void  | 
24  |  | PyGrammar_AddAccelerators(grammar *g)  | 
25  | 14  | { | 
26  | 14  |     int i;  | 
27  | 14  |     const dfa *d = g->g_dfa;  | 
28  | 1.30k  |     for (i = g->g_ndfas; --i >= 0; d++)  | 
29  | 1.28k  |         fixdfa(g, d);  | 
30  | 14  |     g->g_accel = 1;  | 
31  | 14  | }  | 
32  |  |  | 
33  |  | void  | 
34  |  | PyGrammar_RemoveAccelerators(grammar *g)  | 
35  | 0  | { | 
36  | 0  |     int i;  | 
37  | 0  |     g->g_accel = 0;  | 
38  | 0  |     const dfa *d = g->g_dfa;  | 
39  | 0  |     for (i = g->g_ndfas; --i >= 0; d++) { | 
40  | 0  |         state *s;  | 
41  | 0  |         int j;  | 
42  | 0  |         s = d->d_state;  | 
43  | 0  |         for (j = 0; j < d->d_nstates; j++, s++) { | 
44  | 0  |             if (s->s_accel)  | 
45  | 0  |                 PyObject_FREE(s->s_accel);  | 
46  | 0  |             s->s_accel = NULL;  | 
47  | 0  |         }  | 
48  | 0  |     }  | 
49  | 0  | }  | 
50  |  |  | 
51  |  | static void  | 
52  |  | fixdfa(grammar *g, const dfa *d)  | 
53  | 1.28k  | { | 
54  | 1.28k  |     state *s;  | 
55  | 1.28k  |     int j;  | 
56  | 1.28k  |     s = d->d_state;  | 
57  | 7.50k  |     for (j = 0; j < d->d_nstates; j++, s++)  | 
58  | 6.21k  |         fixstate(g, s);  | 
59  | 1.28k  | }  | 
60  |  |  | 
61  |  | static void  | 
62  |  | fixstate(grammar *g, state *s)  | 
63  | 6.21k  | { | 
64  | 6.21k  |     const arc *a;  | 
65  | 6.21k  |     int k;  | 
66  | 6.21k  |     int *accel;  | 
67  | 6.21k  |     int nl = g->g_ll.ll_nlabels;  | 
68  | 6.21k  |     s->s_accept = 0;  | 
69  | 6.21k  |     accel = (int *) PyObject_MALLOC(nl * sizeof(int));  | 
70  | 6.21k  |     if (accel == NULL) { | 
71  | 0  |         fprintf(stderr, "no mem to build parser accelerators\n");  | 
72  | 0  |         exit(1);  | 
73  | 0  |     }  | 
74  | 1.14M  |     for (k = 0; k < nl; k++)  | 
75  | 1.13M  |         accel[k] = -1;  | 
76  | 6.21k  |     a = s->s_arc;  | 
77  | 17.4k  |     for (k = s->s_narcs; --k >= 0; a++) { | 
78  | 11.2k  |         int lbl = a->a_lbl;  | 
79  | 11.2k  |         const label *l = &g->g_ll.ll_label[lbl];  | 
80  | 11.2k  |         int type = l->lb_type;  | 
81  | 11.2k  |         if (a->a_arrow >= (1 << 7)) { | 
82  | 0  |             printf("XXX too many states!\n"); | 
83  | 0  |             continue;  | 
84  | 0  |         }  | 
85  | 11.2k  |         if (ISNONTERMINAL(type)) { | 
86  | 3.51k  |             const dfa *d1 = PyGrammar_FindDFA(g, type);  | 
87  | 3.51k  |             int ibit;  | 
88  | 3.51k  |             if (type - NT_OFFSET >= (1 << 7)) { | 
89  | 0  |                 printf("XXX too high nonterminal number!\n"); | 
90  | 0  |                 continue;  | 
91  | 0  |             }  | 
92  | 646k  |             for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) { | 
93  | 643k  |                 if (testbit(d1->d_first, ibit)) { | 
94  | 37.7k  |                     if (accel[ibit] != -1)  | 
95  | 0  |                         printf("XXX ambiguity!\n"); | 
96  | 37.7k  |                     accel[ibit] = a->a_arrow | (1 << 7) |  | 
97  | 37.7k  |                         ((type - NT_OFFSET) << 8);  | 
98  | 37.7k  |                 }  | 
99  | 643k  |             }  | 
100  | 3.51k  |         }  | 
101  | 7.74k  |         else if (lbl == EMPTY)  | 
102  | 2.82k  |             s->s_accept = 1;  | 
103  | 4.91k  |         else if (lbl >= 0 && lbl < nl)  | 
104  | 4.91k  |             accel[lbl] = a->a_arrow;  | 
105  | 11.2k  |     }  | 
106  | 839k  |     while (nl > 0 && accel[nl-1] == -1)  | 
107  | 833k  |         nl--;  | 
108  | 180k  |     for (k = 0; k < nl && accel[k] == -1;)  | 
109  | 173k  |         k++;  | 
110  | 6.21k  |     if (k < nl) { | 
111  | 5.22k  |         int i;  | 
112  | 5.22k  |         s->s_accel = (int *) PyObject_MALLOC((nl-k) * sizeof(int));  | 
113  | 5.22k  |         if (s->s_accel == NULL) { | 
114  | 0  |             fprintf(stderr, "no mem to add parser accelerators\n");  | 
115  | 0  |             exit(1);  | 
116  | 0  |         }  | 
117  | 5.22k  |         s->s_lower = k;  | 
118  | 5.22k  |         s->s_upper = nl;  | 
119  | 135k  |         for (i = 0; k < nl; i++, k++)  | 
120  | 130k  |             s->s_accel[i] = accel[k];  | 
121  | 5.22k  |     }  | 
122  | 6.21k  |     PyObject_FREE(accel);  | 
123  | 6.21k  | }  |