Skip to content

Commit

Permalink
Use heap for getting unshared pnodes.
Browse files Browse the repository at this point in the history
Signed-off-by: John Plevyak <jplevyak@gmail.com>
  • Loading branch information
jplevyak committed Mar 14, 2022
1 parent 41a22fc commit f34b0b7
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 33 deletions.
4 changes: 2 additions & 2 deletions Makefile
@@ -1,7 +1,7 @@
# Makefile for D_Parser

#D_DEBUG=1
D_OPTIMIZE=1
D_DEBUG=1
#D_OPTIMIZE=1
#D_PROFILE=1
#D_USE_GC=1
#D_LEAK_DETECT=1
Expand Down
82 changes: 64 additions & 18 deletions parse.c
Expand Up @@ -811,32 +811,79 @@ static int cmp_priorities(Parser *p, PNode *x, PNode *y) {
return r;
}

static void get_all(Parser *p, PNode *x, VecPNode *vx) {
void heapify(VecPNode *a, uint i) {
if (a->n <= 1) {
uint largest = i;
uint l = 2 * i + 1;
uint r = 2 * i + 2;
if (l < a->n && a->v[l]->height > a->v[largest]->height)
largest = l;
if (r < a->n && a->v[r]->height > a->v[largest]->height)
largest = r;
if (largest != i) {
PNode *temp = a->v[largest];
a->v[largest] = a->v[i];
a->v[i] = temp;
heapify(a, largest);
}
}
}

void heap_insert(VecPNode *a, PNode *pn) {
vec_add(a, pn);
for (int i = a->n / 2 - 1; i >= 0; i--) {
heapify(a, (uint)i);
}
}

PNode *heap_pop(VecPNode *a) {
if (a->n == 0) return NULL;
PNode *pn = a->v[0];
a->v[0] = a->v[a->n -1];
a->n--;
for (int i = a->n / 2 - 1; i >= 0; i--)
heapify(a, i);
return pn;
}

static void get_children(Parser *p, PNode *pn, VecPNode *ps, VecPNode *ps2, VecPNode *ph) {
uint i;
if (set_add(vx, x)) {
for (i = 0; i < x->children.n; i++) {
PNode *pn = x->children.v[i];
LATEST(p, pn);
get_all(p, pn, vx);
if (set_add(ps, pn) && !set_find(ps2, pn)) {
for (i = 0; i < pn->children.n; i++) {
PNode *c = pn->children.v[i];
LATEST(p, c);
heap_insert(ph, c);
}
}
}

static void get_unshared_pnodes(Parser *p, PNode *x, PNode *y, VecPNode *pvx, VecPNode *pvy) {
uint i;
VecPNode vx, vy;
vec_clear(&vx);
vec_clear(&vy);
VecPNode hx, hy, sx, sy;
vec_clear(&hx);
vec_clear(&hy);
vec_clear(&sx);
vec_clear(&sy);
LATEST(p, x);
LATEST(p, y);
get_all(p, x, &vx);
get_all(p, y, &vy);
for (i = 0; i < vx.n; i++)
if (vx.v[i] && !set_find(&vy, vx.v[i])) vec_add(pvx, vx.v[i]);
for (i = 0; i < vy.n; i++)
if (vy.v[i] && !set_find(&vx, vy.v[i])) vec_add(pvy, vy.v[i]);
vec_free(&vx);
vec_free(&vy);
while (1) {
if (!x && !y) break;
if (!y || (x && x->height > y->height)) {
get_children(p, x, &sx, &sy, &hx);
x = heap_pop(&hx);
} else {
get_children(p, y, &sy, &sx, &hy);
y = heap_pop(&hy);
}
}
for (i = 0; i < sx.n; i++)
if (sx.v[i] && !set_find(&sy, sx.v[i])) vec_add(pvx, sx.v[i]);
for (i = 0; i < sy.n; i++)
if (sy.v[i] && !set_find(&sx, sy.v[i])) vec_add(pvy, sy.v[i]);
vec_free(&hx);
vec_free(&hy);
vec_free(&sx);
vec_free(&sy);
}

static int greedycmp(const void *ax, const void *ay) {
Expand Down Expand Up @@ -868,7 +915,6 @@ static int cmp_greediness(Parser *p, PNode *x, PNode *y) {
vec_clear(&pvx);
vec_clear(&pvy);
get_unshared_pnodes(p, x, y, &pvx, &pvy);
/* set_to_vec(&pvx); set_to_vec(&pvy); */
if (pvx.v != NULL) qsort(pvx.v, pvx.n, sizeof(PNode *), greedycmp);
if (pvy.v != NULL) qsort(pvy.v, pvy.n, sizeof(PNode *), greedycmp);
while (1) {
Expand Down
26 changes: 13 additions & 13 deletions tests/python.test.g.1.check
@@ -1,4 +1,4 @@
7920 states 3502 scans 534 shifts 6999 reductions 457 compares 0 ambiguities
7920 states 3502 scans 534 shifts 6103 reductions 393 compares 0 ambiguities
((( import (( pydparser ))(( , (( sys )))( , (( types )))( , (( dl )))( , (( os )))))
)( class Parser : (
( def __init__ ( ( ( self ( , modules ( = (((((((((( None ))))))))))))) ) ) : (
Expand All @@ -16,35 +16,35 @@
( if (((((((((( type ( ( (((((((((((( modules )))))))))))) ) ))))))))( == ((((((( list ))))))))))) : (
((((((((((((( dicts )))))))))))( = (((((((((((( [ ((((((((((( module ( . __dict__ )))))))))))( for (((((((( module )))))))) in ((((((((((( modules ))))))))))))) ] ))))))))))))))
))( else : (
(((((((((((((( dicts )))))))))))( = ((((((((((( modules )))))))))))))
)((((((((((((( functions )))))))))))( = (((((((((((( [ ((((((((((( val ))))))))))( for (((((((( dict )))))))) in ((((((((((( dicts )))))))))))( for (((((((( name )))))))( , ((((((( val ))))))))) in ((((((((((( dict (( . items )( ( ) )))))))))))))( if ((((((((((( ( ((((((((((( isinstance ( ( ((((((((((((( val ))))))))))) , )((((((((((( types ( . FunctionType ))))))))))))) ) )))))))))))) ) )))))))))( and (((((((( name ( [ (((((((((((( 0 )))))))))) : (((((((((( 2 )))))))))))) ] ))))))))( == ((((((( 'd_' )))))))))))))))) ] ))))))))))))))
((((((((((((( dicts )))))))))))( = ((((((((((( modules )))))))))))))
))))))))))))))((((((((((((( functions )))))))))))( = (((((((((((( [ ((((((((((( val ))))))))))( for (((((((( dict )))))))) in ((((((((((( dicts )))))))))))( for (((((((( name )))))))( , ((((((( val ))))))))) in ((((((((((( dict (( . items )( ( ) )))))))))))))( if ((((((((((( ( ((((((((((( isinstance ( ( ((((((((((((( val ))))))))))) , )((((((((((( types ( . FunctionType ))))))))))))) ) )))))))))))) ) )))))))))( and (((((((( name ( [ (((((((((((( 0 )))))))))) : (((((((((( 2 )))))))))))) ] ))))))))( == ((((((( 'd_' )))))))))))))))) ] ))))))))))))))
)((((((((((((( functions (( . sort )( ( ((( lambda ( x ( , y )) : (((((((((( cmp ( ( ((((((((((((( x (( . func_code )( . co_filename ))))))))))))) , )((((((((((( y (( . func_code )( . co_filename )))))))))))))) ) ))))))))))( or ((((((((( cmp ( ( ((((((((((((( x (( . func_code )( . co_firstlineno ))))))))))))) , )((((((((((( y (( . func_code )( . co_firstlineno )))))))))))))) ) ))))))))))))))) ) ))))))))))))))
)((((((((((((( self ( . filename ))))))))))))( = ((((((((((( self ( . file_prefix )))( + (( ".g" ))))))))))))))
)((((((((((((( g_file )))))))))))( = ((((((((((( open ( ( ((((((((((((( self ( . filename )))))))))))) , )((((((((((( "w" )))))))))))) ) ))))))))))))))
)( for (((((((( f )))))))) in ((((((((((( functions ))))))))))) : (
(((((((((((((( g_file (( . write )( ( (((((((((((( f ( . __doc__ ))))))))))))) ) ))))))))))))))
)((((((((((((( g_file (( . write )( ( (((((((((((( ";\n${action}\n" )))))))))))) ) )))))))))))))) ;
)((((((((((((( self (( . actions )( . append )( ( (((((((((((( f )))))))))))) ) ))))))))))))))
)((((((((((((( g_file (( . close )( ( ) ))))))))))))))
))))((((((((((((( g_file (( . close )( ( ) ))))))))))))))
)( def action ( ( ( self (( , i )( , speculative )( , args ))) ) ) : (
( if (((((((((( speculative )))))))))) : (
((( return )
)( if (((((((((( i )))))))( >= ((((((( 0 )))))))))( and (((((((( i )))))))( < ((((((( len ( ( (((((((((((( self ( . actions ))))))))))))) ) ))))))))))))) : (
(( return )
)))))( if (((((((((( i )))))))( >= ((((((( 0 )))))))))( and (((((((( i )))))))( < ((((((( len ( ( (((((((((((( self ( . actions ))))))))))))) ) ))))))))))))) : (
(((((((((((((( f )))))))))))( = ((((((((((( self (( . actions )( [ ((((((((((( i ))))))))))) ] )))))))))))))))
)((((((((((((( ac )))))))))))( = ((((((((((( f (( . func_code )( . co_argcount )))))))))))))))
)( if (((((((((( ac )))))))( == ((((((( 1 ))))))))))) : (
((( return ((((((((((( f ( ( (((((((((((( args )))))))))))) ) )))))))))))))
)(( raise (((((((((( "where's the action?" ))( + (( str ( ( (((((((((((( i )))))))))))) ) )))))))))))))
(( return ((((((((((( f ( ( (((((((((((( args )))))))))))) ) )))))))))))))
))))))(( raise (((((((((( "where's the action?" ))( + (( str ( ( (((((((((((( i )))))))))))) ) )))))))))))))
)(( return ((((((((((( None ))))))))))))
)( def parse ( ( ( self ( , input )) ) ) : (
(((((((((((((( parser )))))))))))( = ((((((((((( self ( . parser ))))))))))))))
)((((((((((((( filename )))))))))))( = ((((((((((( self ( . filename ))))))))))))))
)( if ((( not (((((((( parser ))))))))))) : (
( if (((((((((( os (( . system )( ( (((((((((((( "make_dparser " ))( + (( filename ))))))))))))) ) )))))))))))) : (
((( raise (((((((((( "make_dparser error" )))))))))))
)( if (((((((((( os (( . system )( ( (((((((((((( "cc -I/usr/local/include -shared -fPIC -o " ))(( + (( filename )))( + (( ".so " )))( + (( filename )))( + (( ".d_parser.c" )))))))))))))) ) )))))))))))) : (
((( raise (((((((((( "cc -static XX.d_parser.o error" )))))))))))
)((((((((((((( self ( . dl_parser ))))))))))))( = ((((((((((( dl (( . open )( ( (((((((((((( "./" ))(( + (( filename )))( + (( ".so" )))))))))))))) ) )))))))))))))))
(( raise (((((((((( "make_dparser error" )))))))))))
))))))))( if (((((((((( os (( . system )( ( (((((((((((( "cc -I/usr/local/include -shared -fPIC -o " ))(( + (( filename )))( + (( ".so " )))( + (( filename )))( + (( ".d_parser.c" )))))))))))))) ) )))))))))))) : (
(( raise (((((((((( "cc -static XX.d_parser.o error" )))))))))))
)))((((((((((((( self ( . dl_parser ))))))))))))( = ((((((((((( dl (( . open )( ( (((((((((((( "./" ))(( + (( filename )))( + (( ".so" )))))))))))))) ) )))))))))))))))
)((((((((((((( self ( . parser ))))))))))))( = ((((((((((( self (( . dl_parser )( . sym )( ( (((((((((((( "parser_tables_gram" )))))))))))) ) ))))))))))))))) ;
)(( return ((((((((((( pydparser (( . run_parser )( ( (((((((((((((( self ( . parser )))))))))))) , )(((((((((((( self ( . action )))))))))))) , ))((((((((((( input )))))))))))) ) ))))))))))))))
)))))))))))))))))))))))))))))))))))))))))
))

0 comments on commit f34b0b7

Please sign in to comment.