2 /* Parser accelerator module */
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. */
13 #include "pgenheaders.h"
19 /* Forward references */
20 static void fixdfa(grammar
*, dfa
*);
21 static void fixstate(grammar
*, state
*);
24 PyGrammar_AddAccelerators(grammar
*g
)
29 for (i
= g
->g_ndfas
; --i
>= 0; d
++)
35 PyGrammar_RemoveAccelerators(grammar
*g
)
41 for (i
= g
->g_ndfas
; --i
>= 0; d
++) {
45 for (j
= 0; j
< d
->d_nstates
; j
++, s
++) {
47 PyObject_FREE(s
->s_accel
);
54 fixdfa(grammar
*g
, dfa
*d
)
59 for (j
= 0; j
< d
->d_nstates
; j
++, s
++)
64 fixstate(grammar
*g
, state
*s
)
69 int nl
= g
->g_ll
.ll_nlabels
;
71 accel
= (int *) PyObject_MALLOC(nl
* sizeof(int));
73 fprintf(stderr
, "no mem to build parser accelerators\n");
76 for (k
= 0; k
< nl
; k
++)
79 for (k
= s
->s_narcs
; --k
>= 0; a
++) {
81 label
*l
= &g
->g_ll
.ll_label
[lbl
];
82 int type
= l
->lb_type
;
83 if (a
->a_arrow
>= (1 << 7)) {
84 printf("XXX too many states!\n");
87 if (ISNONTERMINAL(type
)) {
88 dfa
*d1
= PyGrammar_FindDFA(g
, type
);
90 if (type
- NT_OFFSET
>= (1 << 7)) {
91 printf("XXX too high nonterminal number!\n");
94 for (ibit
= 0; ibit
< g
->g_ll
.ll_nlabels
; ibit
++) {
95 if (testbit(d1
->d_first
, ibit
)) {
96 if (accel
[ibit
] != -1)
97 printf("XXX ambiguity!\n");
98 accel
[ibit
] = a
->a_arrow
| (1 << 7) |
99 ((type
- NT_OFFSET
) << 8);
103 else if (lbl
== EMPTY
)
105 else if (lbl
>= 0 && lbl
< nl
)
106 accel
[lbl
] = a
->a_arrow
;
108 while (nl
> 0 && accel
[nl
-1] == -1)
110 for (k
= 0; k
< nl
&& accel
[k
] == -1;)
114 s
->s_accel
= (int *) PyObject_MALLOC((nl
-k
) * sizeof(int));
115 if (s
->s_accel
== NULL
) {
116 fprintf(stderr
, "no mem to add parser accelerators\n");
121 for (i
= 0; k
< nl
; i
++, k
++)
122 s
->s_accel
[i
] = accel
[k
];
124 PyObject_FREE(accel
);