Rizin
unix-like reverse engineering framework and cli tools
stack.h File Reference
#include "./array.h"
#include "./subtree.h"
#include "./error_costs.h"
#include <stdio.h>

Go to the source code of this file.

Classes

struct  StackSlice
 
struct  StackSummaryEntry
 

Macros

#define STACK_VERSION_NONE   ((StackVersion)-1)
 

Typedefs

typedef struct Stack Stack
 
typedef unsigned StackVersion
 
typedef void(* StackIterateCallback) (void *, TSStateId, uint32_t)
 

Functions

typedef Array (StackSlice) StackSliceArray
 
typedef Array (StackSummaryEntry) StackSummary
 
Stackts_stack_new (SubtreePool *)
 
void ts_stack_delete (Stack *)
 
uint32_t ts_stack_version_count (const Stack *)
 
TSStateId ts_stack_state (const Stack *, StackVersion)
 
Subtree ts_stack_last_external_token (const Stack *, StackVersion)
 
void ts_stack_set_last_external_token (Stack *, StackVersion, Subtree)
 
Length ts_stack_position (const Stack *, StackVersion)
 
void ts_stack_push (Stack *, StackVersion, Subtree, bool, TSStateId)
 
StackSliceArray ts_stack_pop_count (Stack *, StackVersion, uint32_t count)
 
SubtreeArray ts_stack_pop_error (Stack *, StackVersion)
 
StackSliceArray ts_stack_pop_pending (Stack *, StackVersion)
 
StackSliceArray ts_stack_pop_all (Stack *, StackVersion)
 
unsigned ts_stack_node_count_since_error (const Stack *, StackVersion)
 
int ts_stack_dynamic_precedence (Stack *, StackVersion)
 
bool ts_stack_has_advanced_since_error (const Stack *, StackVersion)
 
void ts_stack_record_summary (Stack *, StackVersion, unsigned max_depth)
 
StackSummary * ts_stack_get_summary (Stack *, StackVersion)
 
unsigned ts_stack_error_cost (const Stack *, StackVersion version)
 
bool ts_stack_merge (Stack *, StackVersion, StackVersion)
 
bool ts_stack_can_merge (Stack *, StackVersion, StackVersion)
 
Subtree ts_stack_resume (Stack *, StackVersion)
 
void ts_stack_pause (Stack *, StackVersion, Subtree)
 
void ts_stack_halt (Stack *, StackVersion)
 
bool ts_stack_is_active (const Stack *, StackVersion)
 
bool ts_stack_is_paused (const Stack *, StackVersion)
 
bool ts_stack_is_halted (const Stack *, StackVersion)
 
void ts_stack_renumber_version (Stack *, StackVersion, StackVersion)
 
void ts_stack_swap_versions (Stack *, StackVersion, StackVersion)
 
StackVersion ts_stack_copy_version (Stack *, StackVersion)
 
void ts_stack_remove_version (Stack *, StackVersion)
 
void ts_stack_clear (Stack *)
 
bool ts_stack_print_dot_graph (Stack *, const TSLanguage *, FILE *)
 

Macro Definition Documentation

◆ STACK_VERSION_NONE

#define STACK_VERSION_NONE   ((StackVersion)-1)

Definition at line 16 of file stack.h.

Typedef Documentation

◆ Stack

typedef struct Stack Stack

Definition at line 1 of file stack.h.

◆ StackIterateCallback

typedef void(* StackIterateCallback) (void *, TSStateId, uint32_t)

Definition at line 127 of file stack.h.

◆ StackVersion

Definition at line 15 of file stack.h.

Function Documentation

◆ Array() [1/2]

typedef Array ( StackSlice  )

◆ Array() [2/2]

typedef Array ( StackSummaryEntry  )

◆ ts_stack_can_merge()

bool ts_stack_can_merge ( Stack self,
StackVersion  version1,
StackVersion  version2 
)

Definition at line 693 of file stack.c.

693  {
694  StackHead *head1 = &self->heads.contents[version1];
695  StackHead *head2 = &self->heads.contents[version2];
696  return
697  head1->status == StackStatusActive &&
698  head2->status == StackStatusActive &&
699  head1->node->state == head2->node->state &&
700  head1->node->position.bytes == head2->node->position.bytes &&
701  head1->node->error_cost == head2->node->error_cost &&
703 }
uint32_t bytes
Definition: length.h:10
Subtree last_external_token
Definition: stack.c:58
StackNode * node
Definition: stack.c:55
StackStatus status
Definition: stack.c:60
TSStateId state
Definition: stack.c:29
Length position
Definition: stack.c:30
unsigned error_cost
Definition: stack.c:34
bool ts_subtree_external_scanner_state_eq(Subtree self, Subtree other)
Definition: subtree.c:1027

References Length::bytes, StackNode::error_cost, StackHead::last_external_token, StackHead::node, StackNode::position, StackNode::state, StackHead::status, and ts_subtree_external_scanner_state_eq().

Referenced by ts_parser__better_version_exists(), and ts_stack_merge().

◆ ts_stack_clear()

void ts_stack_clear ( Stack self)

Definition at line 737 of file stack.c.

737  {
738  stack_node_retain(self->base_node);
739  for (uint32_t i = 0; i < self->heads.size; i++) {
740  stack_head_delete(&self->heads.contents[i], &self->node_pool, self->subtree_pool);
741  }
742  array_clear(&self->heads);
743  array_push(&self->heads, ((StackHead) {
744  .node = self->base_node,
745  .status = StackStatusActive,
746  .last_external_token = NULL_SUBTREE,
747  .lookahead_when_paused = NULL_SUBTREE,
748  }));
749 }
lzma_index ** i
Definition: index.h:629
#define array_push(self, element)
Definition: array.h:43
#define array_clear(self)
Definition: array.h:35
unsigned int uint32_t
Definition: sftypes.h:29
static void stack_head_delete(StackHead *self, StackNodeArray *pool, SubtreePool *subtree_pool)
Definition: stack.c:250
static void stack_node_retain(StackNode *self)
Definition: stack.c:81

References array_clear, array_push, i, stack_head_delete(), and stack_node_retain().

Referenced by parser__start(), parser_parse(), ts_parser_reset(), and ts_stack_new().

◆ ts_stack_copy_version()

StackVersion ts_stack_copy_version ( Stack self,
StackVersion  version 
)

Definition at line 669 of file stack.c.

669  {
670  assert(version < self->heads.size);
671  array_push(&self->heads, self->heads.contents[version]);
672  StackHead *head = array_back(&self->heads);
673  stack_node_retain(head->node);
674  if (head->last_external_token.ptr) ts_subtree_retain(head->last_external_token);
675  head->summary = NULL;
676  return self->heads.size - 1;
677 }
#define array_back(self)
Definition: array.h:33
#define NULL
Definition: cris-opc.c:27
assert(limit<=UINT32_MAX/2)
void ts_subtree_retain(Subtree self)
Definition: subtree.c:577

References array_back, array_push, assert(), test-lz4-versions::head, NULL, stack_node_retain(), and ts_subtree_retain().

Referenced by parser__recover(), parser__reduce(), and ts_parser__handle_error().

◆ ts_stack_delete()

void ts_stack_delete ( Stack self)

Definition at line 424 of file stack.c.

424  {
425  if (self->slices.contents)
426  array_delete(&self->slices);
427  if (self->iterators.contents)
428  array_delete(&self->iterators);
429  stack_node_release(self->base_node, &self->node_pool, self->subtree_pool);
430  for (uint32_t i = 0; i < self->heads.size; i++) {
431  stack_head_delete(&self->heads.contents[i], &self->node_pool, self->subtree_pool);
432  }
433  array_clear(&self->heads);
434  if (self->node_pool.contents) {
435  for (uint32_t i = 0; i < self->node_pool.size; i++)
436  ts_free(self->node_pool.contents[i]);
437  array_delete(&self->node_pool);
438  }
439  array_delete(&self->heads);
440  ts_free(self);
441 }
#define ts_free
Definition: alloc.h:30
#define array_delete(self)
Definition: array.h:41
static void stack_node_release(StackNode *self, StackNodeArray *pool, SubtreePool *subtree_pool)
Definition: stack.c:89

References array_clear, array_delete, i, stack_head_delete(), stack_node_release(), and ts_free.

Referenced by parser_destroy(), and ts_parser_delete().

◆ ts_stack_dynamic_precedence()

int ts_stack_dynamic_precedence ( Stack self,
StackVersion  version 
)

Definition at line 615 of file stack.c.

615  {
616  return array_get(&self->heads, version)->node->dynamic_precedence;
617 }
#define array_get(self, index)
Definition: array.h:28

References array_get.

Referenced by ts_parser__better_version_exists(), and ts_parser__version_status().

◆ ts_stack_error_cost()

unsigned ts_stack_error_cost ( const Stack self,
StackVersion  version 
)

Definition at line 466 of file stack.c.

466  {
467  StackHead *head = array_get(&self->heads, version);
468  unsigned result = head->node->error_cost;
469  if (
470  head->status == StackStatusPaused ||
471  (head->node->state == ERROR_STATE && !head->node->links[0].subtree.ptr)) {
472  result += ERROR_COST_PER_RECOVERY;
473  }
474  return result;
475 }
#define ERROR_STATE
Definition: error_costs.h:4
#define ERROR_COST_PER_RECOVERY
Definition: error_costs.h:5

References array_get, ERROR_COST_PER_RECOVERY, ERROR_STATE, and test-lz4-versions::head.

Referenced by ts_parser__condense_stack(), ts_parser__recover(), ts_parser__version_status(), and ts_stack_print_dot_graph().

◆ ts_stack_get_summary()

StackSummary* ts_stack_get_summary ( Stack self,
StackVersion  version 
)

Definition at line 611 of file stack.c.

611  {
612  return array_get(&self->heads, version)->summary;
613 }

References array_get.

Referenced by ts_parser__recover().

◆ ts_stack_halt()

void ts_stack_halt ( Stack self,
StackVersion  version 
)

Definition at line 705 of file stack.c.

705  {
706  array_get(&self->heads, version)->status = StackStatusHalted;
707 }

References array_get.

Referenced by parser__accept(), parser__better_version_exists(), parser__handle_error(), parser__repair_error(), ts_parser__accept(), ts_parser__recover(), and ts_parser__recover_to_state().

◆ ts_stack_has_advanced_since_error()

bool ts_stack_has_advanced_since_error ( const Stack self,
StackVersion  version 
)

Definition at line 619 of file stack.c.

619  {
620  const StackHead *head = array_get(&self->heads, version);
621  const StackNode *node = head->node;
622  if (node->error_cost == 0) return true;
623  while (node) {
624  if (node->link_count > 0) {
625  Subtree subtree = node->links[0].subtree;
626  if (subtree.ptr) {
627  if (ts_subtree_total_bytes(subtree) > 0) {
628  return true;
629  } else if (
630  node->node_count > head->node_count_at_last_error &&
631  ts_subtree_error_cost(subtree) == 0
632  ) {
633  node = node->links[0].node;
634  continue;
635  }
636  }
637  }
638  break;
639  }
640  return false;
641 }
unsigned node_count
Definition: stack.c:35
StackLink links[MAX_LINK_COUNT]
Definition: stack.c:31
short unsigned int link_count
Definition: stack.c:32
static uint32_t ts_subtree_total_bytes(Subtree self)
Definition: subtree.h:278
static uint32_t ts_subtree_error_cost(Subtree self)
Definition: subtree.h:302
const SubtreeHeapData * ptr
Definition: subtree.h:158

References array_get, StackNode::error_cost, test-lz4-versions::head, StackNode::link_count, StackNode::links, StackLink::node, StackNode::node_count, Subtree::ptr, StackLink::subtree, ts_subtree_error_cost(), and ts_subtree_total_bytes().

Referenced by ts_parser__lex().

◆ ts_stack_is_active()

bool ts_stack_is_active ( const Stack self,
StackVersion  version 
)

Definition at line 716 of file stack.c.

716  {
717  return array_get(&self->heads, version)->status == StackStatusActive;
718 }

References array_get.

Referenced by ts_parser__better_version_exists(), ts_parser__recover(), and ts_parser_parse().

◆ ts_stack_is_halted()

bool ts_stack_is_halted ( const Stack self,
StackVersion  version 
)

Definition at line 720 of file stack.c.

720  {
721  return array_get(&self->heads, version)->status == StackStatusHalted;
722 }

References array_get.

Referenced by parser__advance(), parser__better_version_exists(), parser__condense_stack(), parser_parse(), and ts_parser__condense_stack().

◆ ts_stack_is_paused()

bool ts_stack_is_paused ( const Stack self,
StackVersion  version 
)

Definition at line 724 of file stack.c.

724  {
725  return array_get(&self->heads, version)->status == StackStatusPaused;
726 }

References array_get.

Referenced by ts_parser__condense_stack(), and ts_parser__version_status().

◆ ts_stack_last_external_token()

Subtree ts_stack_last_external_token ( const Stack self,
StackVersion  version 
)

Definition at line 455 of file stack.c.

455  {
456  return array_get(&self->heads, version)->last_external_token;
457 }

References array_get.

Referenced by ts_parser__advance(), and ts_parser__lex().

◆ ts_stack_merge()

bool ts_stack_merge ( Stack self,
StackVersion  version1,
StackVersion  version2 
)

Definition at line 679 of file stack.c.

679  {
680  if (!ts_stack_can_merge(self, version1, version2)) return false;
681  StackHead *head1 = &self->heads.contents[version1];
682  StackHead *head2 = &self->heads.contents[version2];
683  for (uint32_t i = 0; i < head2->node->link_count; i++) {
684  stack_node_add_link(head1->node, head2->node->links[i], self->subtree_pool);
685  }
686  if (head1->node->state == ERROR_STATE) {
687  head1->node_count_at_last_error = head1->node->node_count;
688  }
689  ts_stack_remove_version(self, version2);
690  return true;
691 }
unsigned node_count_at_last_error
Definition: stack.c:57
bool ts_stack_can_merge(Stack *self, StackVersion version1, StackVersion version2)
Definition: stack.c:693
static void stack_node_add_link(StackNode *self, StackLink link, SubtreePool *subtree_pool)
Definition: stack.c:185
void ts_stack_remove_version(Stack *self, StackVersion version)
Definition: stack.c:643

References ERROR_STATE, i, StackNode::link_count, StackNode::links, StackHead::node, StackNode::node_count, StackHead::node_count_at_last_error, stack_node_add_link(), StackNode::state, ts_stack_can_merge(), and ts_stack_remove_version().

Referenced by parser__condense_stack(), parser__handle_error(), parser__reduce(), ts_parser__condense_stack(), ts_parser__do_all_potential_reductions(), ts_parser__handle_error(), and ts_parser__reduce().

◆ ts_stack_new()

Stack* ts_stack_new ( SubtreePool subtree_pool)

Definition at line 405 of file stack.c.

405  {
406  Stack *self = ts_calloc(1, sizeof(Stack));
407 
408  array_init(&self->heads);
409  array_init(&self->slices);
410  array_init(&self->iterators);
411  array_init(&self->node_pool);
412  array_reserve(&self->heads, 4);
413  array_reserve(&self->slices, 4);
414  array_reserve(&self->iterators, 4);
415  array_reserve(&self->node_pool, MAX_NODE_POOL_SIZE);
416 
417  self->subtree_pool = subtree_pool;
418  self->base_node = stack_node_new(NULL, NULL_SUBTREE, false, 1, &self->node_pool);
419  ts_stack_clear(self);
420 
421  return self;
422 }
#define ts_calloc
Definition: alloc.h:24
#define array_init(self)
Definition: array.h:22
#define array_reserve(self, new_capacity)
Definition: array.h:37
Definition: stack.c:63
void ts_stack_clear(Stack *self)
Definition: stack.c:737
static StackNode * stack_node_new(StackNode *previous_node, Subtree subtree, bool is_pending, TSStateId state, StackNodeArray *pool)
Definition: stack.c:123
#define MAX_NODE_POOL_SIZE
Definition: stack.c:11
#define NULL_SUBTREE
Definition: subtree.h:19

References array_init, array_reserve, MAX_NODE_POOL_SIZE, NULL, NULL_SUBTREE, stack_node_new(), ts_calloc, and ts_stack_clear().

Referenced by parser_init(), and ts_parser_new().

◆ ts_stack_node_count_since_error()

unsigned ts_stack_node_count_since_error ( const Stack self,
StackVersion  version 
)

Definition at line 477 of file stack.c.

477  {
478  StackHead *head = array_get(&self->heads, version);
479  if (head->node->node_count < head->node_count_at_last_error) {
480  head->node_count_at_last_error = head->node->node_count;
481  }
482  return head->node->node_count - head->node_count_at_last_error;
483 }

References array_get, and test-lz4-versions::head.

Referenced by ts_parser__better_version_exists(), ts_parser__recover(), ts_parser__version_status(), ts_parser_has_outstanding_parse(), and ts_stack_print_dot_graph().

◆ ts_stack_pause()

void ts_stack_pause ( Stack self,
StackVersion  version,
Subtree  lookahead 
)

Definition at line 709 of file stack.c.

709  {
710  StackHead *head = array_get(&self->heads, version);
711  head->status = StackStatusPaused;
712  head->lookahead_when_paused = lookahead;
713  head->node_count_at_last_error = head->node->node_count;
714 }

References array_get, and test-lz4-versions::head.

Referenced by ts_parser__advance().

◆ ts_stack_pop_all()

StackSliceArray ts_stack_pop_all ( Stack self,
StackVersion  version 
)

Definition at line 569 of file stack.c.

569  {
570  return stack__iter(self, version, pop_all_callback, NULL, 0);
571 }
StackSliceArray stack__iter(Stack *self, StackVersion version, StackCallback callback, void *payload, int goal_subtree_count)
Definition: stack.c:308
StackAction pop_all_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:564

References NULL, pop_all_callback(), and stack__iter().

Referenced by parser__accept(), and ts_parser__accept().

◆ ts_stack_pop_count()

StackSliceArray ts_stack_pop_count ( Stack self,
StackVersion  version,
uint32_t  count 
)

Definition at line 507 of file stack.c.

507  {
509 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
StackAction pop_count_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:498

References count, pop_count_callback(), and stack__iter().

Referenced by parser__reduce(), ts_parser__recover(), ts_parser__recover_to_state(), and ts_parser__reduce().

◆ ts_stack_pop_error()

SubtreeArray ts_stack_pop_error ( Stack self,
StackVersion  version 
)

Definition at line 547 of file stack.c.

547  {
548  StackNode *node = array_get(&self->heads, version)->node;
549  for (unsigned i = 0; i < node->link_count; i++) {
550  if (node->links[i].subtree.ptr && ts_subtree_is_error(node->links[i].subtree)) {
551  bool found_error = false;
552  StackSliceArray pop = stack__iter(self, version, pop_error_callback, &found_error, 1);
553  if (pop.size > 0) {
554  assert(pop.size == 1);
555  ts_stack_renumber_version(self, pop.contents[0].version, version);
556  return pop.contents[0].subtrees;
557  }
558  break;
559  }
560  }
561  return (SubtreeArray) {.size = 0};
562 }
void ts_stack_renumber_version(Stack *self, StackVersion v1, StackVersion v2)
Definition: stack.c:648
StackAction pop_error_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:533
static bool ts_subtree_is_error(Subtree self)
Definition: subtree.h:342

References array_get, assert(), i, StackNode::link_count, StackNode::links, pop_error_callback(), Subtree::ptr, stack__iter(), StackLink::subtree, ts_stack_renumber_version(), and ts_subtree_is_error().

Referenced by ts_parser__recover_to_state().

◆ ts_stack_pop_pending()

StackSliceArray ts_stack_pop_pending ( Stack self,
StackVersion  version 
)

Definition at line 524 of file stack.c.

524  {
525  StackSliceArray pop = stack__iter(self, version, pop_pending_callback, NULL, 0);
526  if (pop.size > 0) {
527  ts_stack_renumber_version(self, pop.contents[0].version, version);
528  pop.contents[0].version = version;
529  }
530  return pop;
531 }
static char * version
Definition: acr.h:4
StackAction pop_pending_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:511

References NULL, pop_pending_callback(), stack__iter(), ts_stack_renumber_version(), and version.

Referenced by parser__breakdown_top_of_stack(), and ts_parser__breakdown_top_of_stack().

◆ ts_stack_position()

Length ts_stack_position ( const Stack self,
StackVersion  version 
)

Definition at line 451 of file stack.c.

451  {
452  return array_get(&self->heads, version)->node->position;
453 }

References array_get.

Referenced by ts_parser__advance(), ts_parser__better_version_exists(), ts_parser__handle_error(), ts_parser__lex(), ts_parser__recover(), and ts_parser_parse().

◆ ts_stack_print_dot_graph()

bool ts_stack_print_dot_graph ( Stack self,
const TSLanguage language,
FILE *  f 
)

Definition at line 751 of file stack.c.

751  {
752  array_reserve(&self->iterators, 32);
753  if (!f) f = stderr;
754 
755  fprintf(f, "digraph stack {\n");
756  fprintf(f, "rankdir=\"RL\";\n");
757  fprintf(f, "edge [arrowhead=none]\n");
758 
759  Array(StackNode *) visited_nodes = array_new();
760 
761  array_clear(&self->iterators);
762  for (uint32_t i = 0; i < self->heads.size; i++) {
763  StackHead *head = &self->heads.contents[i];
764  if (head->status == StackStatusHalted) continue;
765 
766  fprintf(f, "node_head_%u [shape=none, label=\"\"]\n", i);
767  fprintf(f, "node_head_%u -> node_%p [", i, (void *)head->node);
768 
769  if (head->status == StackStatusPaused) {
770  fprintf(f, "color=red ");
771  }
772  fprintf(f,
773  "label=%u, fontcolor=blue, weight=10000, labeltooltip=\"node_count: %u\nerror_cost: %u",
774  i,
776  ts_stack_error_cost(self, i)
777  );
778 
779  if (head->summary) {
780  fprintf(f, "\nsummary_size: %u", head->summary->size);
781  }
782 
783  if (head->last_external_token.ptr) {
784  const ExternalScannerState *state = &head->last_external_token.ptr->external_scanner_state;
785  const char *data = ts_external_scanner_state_data(state);
786  fprintf(f, "\nexternal_scanner_state:");
787  for (uint32_t j = 0; j < state->length; j++) fprintf(f, " %2X", data[j]);
788  }
789 
790  fprintf(f, "\"]\n");
791  array_push(&self->iterators, ((StackIterator) {
792  .node = head->node
793  }));
794  }
795 
796  bool all_iterators_done = false;
797  while (!all_iterators_done) {
798  all_iterators_done = true;
799 
800  for (uint32_t i = 0; i < self->iterators.size; i++) {
801  StackIterator iterator = self->iterators.contents[i];
802  StackNode *node = iterator.node;
803 
804  for (uint32_t j = 0; j < visited_nodes.size; j++) {
805  if (visited_nodes.contents[j] == node) {
806  node = NULL;
807  break;
808  }
809  }
810 
811  if (!node) continue;
812  all_iterators_done = false;
813 
814  fprintf(f, "node_%p [", (void *)node);
815  if (node->state == ERROR_STATE) {
816  fprintf(f, "label=\"?\"");
817  } else if (
818  node->link_count == 1 &&
819  node->links[0].subtree.ptr &&
820  ts_subtree_extra(node->links[0].subtree)
821  ) {
822  fprintf(f, "shape=point margin=0 label=\"\"");
823  } else {
824  fprintf(f, "label=\"%d\"", node->state);
825  }
826 
827  fprintf(
828  f,
829  " tooltip=\"position: %u,%u\nnode_count:%u\nerror_cost: %u\ndynamic_precedence: %d\"];\n",
830  node->position.extent.row + 1,
831  node->position.extent.column,
832  node->node_count,
833  node->error_cost,
834  node->dynamic_precedence
835  );
836 
837  for (int j = 0; j < node->link_count; j++) {
838  StackLink link = node->links[j];
839  fprintf(f, "node_%p -> node_%p [", (void *)node, (void *)link.node);
840  if (link.is_pending) fprintf(f, "style=dashed ");
841  if (link.subtree.ptr && ts_subtree_extra(link.subtree)) fprintf(f, "fontcolor=gray ");
842 
843  if (!link.subtree.ptr) {
844  fprintf(f, "color=red");
845  } else {
846  fprintf(f, "label=\"");
847  bool quoted = ts_subtree_visible(link.subtree) && !ts_subtree_named(link.subtree);
848  if (quoted) fprintf(f, "'");
849  const char *name = ts_language_symbol_name(language, ts_subtree_symbol(link.subtree));
850  for (const char *c = name; *c; c++) {
851  if (*c == '\"' || *c == '\\') fprintf(f, "\\");
852  fprintf(f, "%c", *c);
853  }
854  if (quoted) fprintf(f, "'");
855  fprintf(f, "\"");
856  fprintf(
857  f,
858  "labeltooltip=\"error_cost: %u\ndynamic_precedence: %u\"",
859  ts_subtree_error_cost(link.subtree),
861  );
862  }
863 
864  fprintf(f, "];\n");
865 
866  StackIterator *next_iterator;
867  if (j == 0) {
868  next_iterator = &self->iterators.contents[i];
869  } else {
870  array_push(&self->iterators, iterator);
871  next_iterator = array_back(&self->iterators);
872  }
873  next_iterator->node = link.node;
874  }
875 
876  array_push(&visited_nodes, node);
877  }
878  }
879 
880  fprintf(f, "}\n");
881 
882  array_delete(&visited_nodes);
883  return true;
884 }
const MCPhysReg * iterator
const char * ts_language_symbol_name(const TSLanguage *, TSSymbol)
Definition: language.c:59
#define array_new()
Definition: array.h:25
static static fork const void static count static fd link
Definition: sflib.h:33
#define f(i)
Definition: sha256.c:46
#define c(i)
Definition: sha256.c:43
TSPoint extent
Definition: length.h:11
StackNode * node
Definition: stack.c:40
int dynamic_precedence
Definition: stack.c:36
uint32_t row
Definition: api.h:56
uint32_t column
Definition: api.h:57
Definition: z80asm.h:102
Definition: dis.h:43
unsigned ts_stack_node_count_since_error(const Stack *self, StackVersion version)
Definition: stack.c:477
unsigned ts_stack_error_cost(const Stack *self, StackVersion version)
Definition: stack.c:466
typedef Array(StackNode *)
Definition: stack.c:46
const char * ts_external_scanner_state_data(const ExternalScannerState *self)
Definition: subtree.c:53
static bool ts_subtree_visible(Subtree self)
Definition: subtree.h:214
static int32_t ts_subtree_dynamic_precedence(Subtree self)
Definition: subtree.h:310
static bool ts_subtree_extra(Subtree self)
Definition: subtree.h:216
static bool ts_subtree_named(Subtree self)
Definition: subtree.h:215
static TSSymbol ts_subtree_symbol(Subtree self)
Definition: subtree.h:213

References Array(), array_back, array_clear, array_delete, array_new, array_push, array_reserve, c, TSPoint::column, StackNode::dynamic_precedence, StackNode::error_cost, ERROR_STATE, Length::extent, f, test-lz4-versions::head, i, link, StackNode::link_count, StackNode::links, StackIterator::node, StackNode::node_count, NULL, StackNode::position, Subtree::ptr, TSPoint::row, StackNode::state, StackLink::subtree, ts_external_scanner_state_data(), ts_language_symbol_name(), ts_stack_error_cost(), ts_stack_node_count_since_error(), ts_subtree_dynamic_precedence(), ts_subtree_error_cost(), ts_subtree_extra(), ts_subtree_named(), ts_subtree_symbol(), and ts_subtree_visible().

◆ ts_stack_push()

void ts_stack_push ( Stack self,
StackVersion  version,
Subtree  subtree,
bool  pending,
TSStateId  state 
)

◆ ts_stack_record_summary()

void ts_stack_record_summary ( Stack self,
StackVersion  version,
unsigned  max_depth 
)

Definition at line 596 of file stack.c.

596  {
597  SummarizeStackSession session = {
598  .summary = ts_malloc(sizeof(StackSummary)),
599  .max_depth = max_depth
600  };
601  array_init(session.summary);
602  stack__iter(self, version, summarize_stack_callback, &session, -1);
603  StackHead *head = &self->heads.contents[version];
604  if (head->summary) {
605  array_delete(head->summary);
606  ts_free(head->summary);
607  }
608  head->summary = session.summary;
609 }
#define ts_malloc
Definition: alloc.h:21
StackSummary * summary
Definition: stack.c:574
StackAction summarize_stack_callback(void *payload, const StackIterator *iterator)
Definition: stack.c:578

References array_delete, array_init, test-lz4-versions::head, stack__iter(), summarize_stack_callback(), SummarizeStackSession::summary, ts_free, ts_malloc, and version.

Referenced by ts_parser__handle_error().

◆ ts_stack_remove_version()

void ts_stack_remove_version ( Stack self,
StackVersion  version 
)

◆ ts_stack_renumber_version()

void ts_stack_renumber_version ( Stack self,
StackVersion  v1,
StackVersion  v2 
)

Definition at line 648 of file stack.c.

648  {
649  if (v1 == v2) return;
650  assert(v2 < v1);
651  assert((uint32_t)v1 < self->heads.size);
652  StackHead *source_head = &self->heads.contents[v1];
653  StackHead *target_head = &self->heads.contents[v2];
654  if (target_head->summary && !source_head->summary) {
655  source_head->summary = target_head->summary;
656  target_head->summary = NULL;
657  }
658  stack_head_delete(target_head, &self->node_pool, self->subtree_pool);
659  *target_head = *source_head;
660  array_erase(&self->heads, v1);
661 }
@ v1
Definition: lanai.h:85
StackSummary * summary
Definition: stack.c:56

References array_erase, assert(), NULL, stack_head_delete(), StackHead::summary, and v1.

Referenced by parser__advance(), parser__do_potential_reductions(), parser__repair_error(), ts_parser__advance(), ts_parser__do_all_potential_reductions(), ts_parser__recover(), ts_stack_pop_error(), and ts_stack_pop_pending().

◆ ts_stack_resume()

Subtree ts_stack_resume ( Stack self,
StackVersion  version 
)

Definition at line 728 of file stack.c.

728  {
729  StackHead *head = array_get(&self->heads, version);
730  assert(head->status == StackStatusPaused);
731  Subtree result = head->lookahead_when_paused;
732  head->status = StackStatusActive;
733  head->lookahead_when_paused = NULL_SUBTREE;
734  return result;
735 }

References array_get, assert(), test-lz4-versions::head, and NULL_SUBTREE.

Referenced by ts_parser__condense_stack().

◆ ts_stack_set_last_external_token()

void ts_stack_set_last_external_token ( Stack self,
StackVersion  version,
Subtree  token 
)

Definition at line 459 of file stack.c.

459  {
460  StackHead *head = array_get(&self->heads, version);
461  if (token.ptr) ts_subtree_retain(token);
462  if (head->last_external_token.ptr) ts_subtree_release(self->subtree_pool, head->last_external_token);
463  head->last_external_token = token;
464 }
void ts_subtree_release(SubtreePool *pool, Subtree self)
Definition: subtree.c:584

References array_get, test-lz4-versions::head, Subtree::ptr, ts_subtree_release(), and ts_subtree_retain().

Referenced by ts_parser__recover(), and ts_parser__shift().

◆ ts_stack_state()

◆ ts_stack_swap_versions()

void ts_stack_swap_versions ( Stack self,
StackVersion  v1,
StackVersion  v2 
)

Definition at line 663 of file stack.c.

663  {
664  StackHead temporary_head = self->heads.contents[v1];
665  self->heads.contents[v1] = self->heads.contents[v2];
666  self->heads.contents[v2] = temporary_head;
667 }

References v1.

Referenced by ts_parser__condense_stack().

◆ ts_stack_version_count()