@@ -597,12 +597,32 @@ _PyPegen_new_identifier(Parser *p, const char *n)
597597 return NULL ;
598598}
599599
600+ static expr_ty
601+ name_from_identifier (Parser * p , Token * t , PyObject * id )
602+ {
603+ expr_ty result = _PyAST_Name (id , Load , t -> lineno , t -> col_offset ,
604+ t -> end_lineno , t -> end_col_offset , p -> arena );
605+ if (result != NULL && _PyPegen_insert_memo (p , p -> mark - 1 , NAME , result ) < 0 ) {
606+ p -> error_indicator = 1 ;
607+ return NULL ;
608+ }
609+ return result ;
610+ }
611+
600612static expr_ty
601613_PyPegen_name_from_token (Parser * p , Token * t )
602614{
603615 if (t == NULL ) {
604616 return NULL ;
605617 }
618+ // Token kinds can be memo keys: generated grammar rule IDs start at 1000.
619+ int mark = p -> mark - 1 ;
620+ p -> mark = mark ;
621+ expr_ty cached = NULL ;
622+ if (_PyPegen_is_memoized (p , NAME , & cached )) {
623+ return cached ;
624+ }
625+ p -> mark = mark + 1 ;
606626 const char * s = PyBytes_AsString (t -> bytes );
607627 if (!s ) {
608628 p -> error_indicator = 1 ;
@@ -639,8 +659,7 @@ _PyPegen_name_from_token(Parser *p, Token* t)
639659 if (entry -> hash == hash && entry -> len == len &&
640660 memcmp (entry -> key , s , len ) == 0 )
641661 {
642- return _PyAST_Name (entry -> value , Load , t -> lineno , t -> col_offset ,
643- t -> end_lineno , t -> end_col_offset , p -> arena );
662+ return name_from_identifier (p , t , entry -> value );
644663 }
645664 }
646665 PyObject * id = _PyPegen_new_identifier (p , s );
@@ -654,8 +673,7 @@ _PyPegen_name_from_token(Parser *p, Token* t)
654673 free_slot -> hash = hash ;
655674 free_slot -> value = id ;
656675 }
657- return _PyAST_Name (id , Load , t -> lineno , t -> col_offset , t -> end_lineno ,
658- t -> end_col_offset , p -> arena );
676+ return name_from_identifier (p , t , id );
659677}
660678
661679expr_ty
0 commit comments