xref: /dflybsd-src/contrib/tre/lib/tre-ast.c (revision d5f8dde1e2bae450329b3ee8c25ef109b5713f07)
15f2eab64SJohn Marino /*
25f2eab64SJohn Marino   tre-ast.c - Abstract syntax tree (AST) routines
35f2eab64SJohn Marino 
45f2eab64SJohn Marino   This software is released under a BSD-style license.
55f2eab64SJohn Marino   See the file LICENSE for details and copyright.
65f2eab64SJohn Marino 
75f2eab64SJohn Marino */
85f2eab64SJohn Marino 
95f2eab64SJohn Marino #ifdef HAVE_CONFIG_H
105f2eab64SJohn Marino #include <config.h>
115f2eab64SJohn Marino #endif /* HAVE_CONFIG_H */
125f2eab64SJohn Marino #include <assert.h>
135f2eab64SJohn Marino 
145f2eab64SJohn Marino #include "tre-ast.h"
155f2eab64SJohn Marino #include "tre-mem.h"
165f2eab64SJohn Marino 
175f2eab64SJohn Marino tre_ast_node_t *
tre_ast_new_node(tre_mem_t mem,tre_ast_type_t type,size_t size)185f2eab64SJohn Marino tre_ast_new_node(tre_mem_t mem, tre_ast_type_t type, size_t size)
195f2eab64SJohn Marino {
205f2eab64SJohn Marino   tre_ast_node_t *node;
215f2eab64SJohn Marino 
225f2eab64SJohn Marino   node = tre_mem_calloc(mem, sizeof(*node));
235f2eab64SJohn Marino   if (!node)
245f2eab64SJohn Marino     return NULL;
255f2eab64SJohn Marino   node->obj = tre_mem_calloc(mem, size);
265f2eab64SJohn Marino   if (!node->obj)
275f2eab64SJohn Marino     return NULL;
285f2eab64SJohn Marino   node->type = type;
295f2eab64SJohn Marino   node->nullable = -1;
305f2eab64SJohn Marino   node->submatch_id = -1;
315f2eab64SJohn Marino 
325f2eab64SJohn Marino   return node;
335f2eab64SJohn Marino }
345f2eab64SJohn Marino 
355f2eab64SJohn Marino tre_ast_node_t *
tre_ast_new_literal(tre_mem_t mem,int code_min,int code_max,int position)365f2eab64SJohn Marino tre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position)
375f2eab64SJohn Marino {
385f2eab64SJohn Marino   tre_ast_node_t *node;
395f2eab64SJohn Marino   tre_literal_t *lit;
405f2eab64SJohn Marino 
415f2eab64SJohn Marino   node = tre_ast_new_node(mem, LITERAL, sizeof(tre_literal_t));
425f2eab64SJohn Marino   if (!node)
435f2eab64SJohn Marino     return NULL;
445f2eab64SJohn Marino   lit = node->obj;
455f2eab64SJohn Marino   lit->code_min = code_min;
465f2eab64SJohn Marino   lit->code_max = code_max;
475f2eab64SJohn Marino   lit->position = position;
485f2eab64SJohn Marino 
495f2eab64SJohn Marino   return node;
505f2eab64SJohn Marino }
515f2eab64SJohn Marino 
525f2eab64SJohn Marino tre_ast_node_t *
tre_ast_new_iter(tre_mem_t mem,tre_ast_node_t * arg,int min,int max,int minimal)535f2eab64SJohn Marino tre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max,
545f2eab64SJohn Marino 		 int minimal)
555f2eab64SJohn Marino {
565f2eab64SJohn Marino   tre_ast_node_t *node;
575f2eab64SJohn Marino   tre_iteration_t *iter;
585f2eab64SJohn Marino 
595f2eab64SJohn Marino   node = tre_ast_new_node(mem, ITERATION, sizeof(tre_iteration_t));
605f2eab64SJohn Marino   if (!node)
615f2eab64SJohn Marino     return NULL;
625f2eab64SJohn Marino   iter = node->obj;
635f2eab64SJohn Marino   iter->arg = arg;
645f2eab64SJohn Marino   iter->min = min;
655f2eab64SJohn Marino   iter->max = max;
665f2eab64SJohn Marino   iter->minimal = minimal;
675f2eab64SJohn Marino   node->num_submatches = arg->num_submatches;
685f2eab64SJohn Marino 
695f2eab64SJohn Marino   return node;
705f2eab64SJohn Marino }
715f2eab64SJohn Marino 
725f2eab64SJohn Marino tre_ast_node_t *
tre_ast_new_union(tre_mem_t mem,tre_ast_node_t * left,tre_ast_node_t * right)735f2eab64SJohn Marino tre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
745f2eab64SJohn Marino {
755f2eab64SJohn Marino   tre_ast_node_t *node;
765f2eab64SJohn Marino 
775f2eab64SJohn Marino   node = tre_ast_new_node(mem, UNION, sizeof(tre_union_t));
785f2eab64SJohn Marino   if (node == NULL)
795f2eab64SJohn Marino     return NULL;
805f2eab64SJohn Marino   ((tre_union_t *)node->obj)->left = left;
815f2eab64SJohn Marino   ((tre_union_t *)node->obj)->right = right;
825f2eab64SJohn Marino   node->num_submatches = left->num_submatches + right->num_submatches;
835f2eab64SJohn Marino 
845f2eab64SJohn Marino   return node;
855f2eab64SJohn Marino }
865f2eab64SJohn Marino 
875f2eab64SJohn Marino tre_ast_node_t *
tre_ast_new_catenation(tre_mem_t mem,tre_ast_node_t * left,tre_ast_node_t * right)885f2eab64SJohn Marino tre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left,
895f2eab64SJohn Marino 		       tre_ast_node_t *right)
905f2eab64SJohn Marino {
915f2eab64SJohn Marino   tre_ast_node_t *node;
925f2eab64SJohn Marino 
935f2eab64SJohn Marino   node = tre_ast_new_node(mem, CATENATION, sizeof(tre_catenation_t));
945f2eab64SJohn Marino   if (node == NULL)
955f2eab64SJohn Marino     return NULL;
965f2eab64SJohn Marino   ((tre_catenation_t *)node->obj)->left = left;
975f2eab64SJohn Marino   ((tre_catenation_t *)node->obj)->right = right;
985f2eab64SJohn Marino   node->num_submatches = left->num_submatches + right->num_submatches;
995f2eab64SJohn Marino 
1005f2eab64SJohn Marino   return node;
1015f2eab64SJohn Marino }
1025f2eab64SJohn Marino 
1035f2eab64SJohn Marino #ifdef TRE_DEBUG
1045f2eab64SJohn Marino 
1055f2eab64SJohn Marino static void
tre_findent(FILE * stream,int i)1065f2eab64SJohn Marino tre_findent(FILE *stream, int i)
1075f2eab64SJohn Marino {
1085f2eab64SJohn Marino   while (i-- > 0)
1095f2eab64SJohn Marino     fputc(' ', stream);
1105f2eab64SJohn Marino }
1115f2eab64SJohn Marino 
1125f2eab64SJohn Marino void
tre_print_params(int * params)1135f2eab64SJohn Marino tre_print_params(int *params)
1145f2eab64SJohn Marino {
1155f2eab64SJohn Marino   int i;
1165f2eab64SJohn Marino   if (params)
1175f2eab64SJohn Marino     {
1185f2eab64SJohn Marino       DPRINT(("params ["));
1195f2eab64SJohn Marino       for (i = 0; i < TRE_PARAM_LAST; i++)
1205f2eab64SJohn Marino 	{
1215f2eab64SJohn Marino 	  if (params[i] == TRE_PARAM_UNSET)
1225f2eab64SJohn Marino 	    DPRINT(("unset"));
1235f2eab64SJohn Marino 	  else if (params[i] == TRE_PARAM_DEFAULT)
1245f2eab64SJohn Marino 	    DPRINT(("default"));
1255f2eab64SJohn Marino 	  else
1265f2eab64SJohn Marino 	    DPRINT(("%d", params[i]));
1275f2eab64SJohn Marino 	  if (i < TRE_PARAM_LAST - 1)
1285f2eab64SJohn Marino 	    DPRINT((", "));
1295f2eab64SJohn Marino 	}
1305f2eab64SJohn Marino       DPRINT(("]"));
1315f2eab64SJohn Marino     }
1325f2eab64SJohn Marino }
1335f2eab64SJohn Marino 
1345f2eab64SJohn Marino static void
tre_do_print(FILE * stream,tre_ast_node_t * ast,int indent)1355f2eab64SJohn Marino tre_do_print(FILE *stream, tre_ast_node_t *ast, int indent)
1365f2eab64SJohn Marino {
1375f2eab64SJohn Marino   int code_min, code_max, pos;
1385f2eab64SJohn Marino   int num_tags = ast->num_tags;
1395f2eab64SJohn Marino   tre_literal_t *lit;
1405f2eab64SJohn Marino   tre_iteration_t *iter;
1415f2eab64SJohn Marino 
1425f2eab64SJohn Marino   tre_findent(stream, indent);
1435f2eab64SJohn Marino   switch (ast->type)
1445f2eab64SJohn Marino     {
1455f2eab64SJohn Marino     case LITERAL:
1465f2eab64SJohn Marino       lit = ast->obj;
1475f2eab64SJohn Marino       code_min = lit->code_min;
1485f2eab64SJohn Marino       code_max = lit->code_max;
1495f2eab64SJohn Marino       pos = lit->position;
1505f2eab64SJohn Marino       if (IS_EMPTY(lit))
1515f2eab64SJohn Marino 	{
1525f2eab64SJohn Marino 	  fprintf(stream, "literal empty\n");
1535f2eab64SJohn Marino 	}
1545f2eab64SJohn Marino       else if (IS_ASSERTION(lit))
1555f2eab64SJohn Marino 	{
1565f2eab64SJohn Marino 	  int i;
157*d5f8dde1SJohn Marino 	  char *assertions[] = { "bol", "eol", "bracket",
158*d5f8dde1SJohn Marino 				 "bow", "eow", "wb", "!wb", "backref" };
1595f2eab64SJohn Marino 	  if (code_max >= ASSERT_LAST << 1)
1605f2eab64SJohn Marino 	    assert(0);
1615f2eab64SJohn Marino 	  fprintf(stream, "assertions: ");
1625f2eab64SJohn Marino 	  for (i = 0; (1 << i) <= ASSERT_LAST; i++)
1635f2eab64SJohn Marino 	    if (code_max & (1 << i))
1645f2eab64SJohn Marino 	      fprintf(stream, "%s ", assertions[i]);
1655f2eab64SJohn Marino 	  fprintf(stream, "\n");
1665f2eab64SJohn Marino 	}
1675f2eab64SJohn Marino       else if (IS_TAG(lit))
1685f2eab64SJohn Marino 	{
1695f2eab64SJohn Marino 	  fprintf(stream, "tag %d\n", code_max);
1705f2eab64SJohn Marino 	}
1715f2eab64SJohn Marino       else if (IS_BACKREF(lit))
1725f2eab64SJohn Marino 	{
1735f2eab64SJohn Marino 	  fprintf(stream, "backref %d, pos %d\n", code_max, pos);
1745f2eab64SJohn Marino 	}
1755f2eab64SJohn Marino       else if (IS_PARAMETER(lit))
1765f2eab64SJohn Marino 	{
1775f2eab64SJohn Marino 	  tre_print_params(lit->u.params);
1785f2eab64SJohn Marino 	  fprintf(stream, "\n");
1795f2eab64SJohn Marino 	}
1805f2eab64SJohn Marino       else
1815f2eab64SJohn Marino 	{
1825f2eab64SJohn Marino 	  fprintf(stream, "literal (%c, %c) (%d, %d), pos %d, sub %d, "
1835f2eab64SJohn Marino 		  "%d tags\n", code_min, code_max, code_min, code_max, pos,
1845f2eab64SJohn Marino 		  ast->submatch_id, num_tags);
1855f2eab64SJohn Marino 	}
1865f2eab64SJohn Marino       break;
1875f2eab64SJohn Marino     case ITERATION:
1885f2eab64SJohn Marino       iter = ast->obj;
1895f2eab64SJohn Marino       fprintf(stream, "iteration {%d, %d}, sub %d, %d tags, %s\n",
1905f2eab64SJohn Marino 	      iter->min, iter->max, ast->submatch_id, num_tags,
1915f2eab64SJohn Marino 	      iter->minimal ? "minimal" : "greedy");
1925f2eab64SJohn Marino       tre_do_print(stream, iter->arg, indent + 2);
1935f2eab64SJohn Marino       break;
1945f2eab64SJohn Marino     case UNION:
1955f2eab64SJohn Marino       fprintf(stream, "union, sub %d, %d tags\n", ast->submatch_id, num_tags);
1965f2eab64SJohn Marino       tre_do_print(stream, ((tre_union_t *)ast->obj)->left, indent + 2);
1975f2eab64SJohn Marino       tre_do_print(stream, ((tre_union_t *)ast->obj)->right, indent + 2);
1985f2eab64SJohn Marino       break;
1995f2eab64SJohn Marino     case CATENATION:
2005f2eab64SJohn Marino       fprintf(stream, "catenation, sub %d, %d tags\n", ast->submatch_id,
2015f2eab64SJohn Marino 	      num_tags);
2025f2eab64SJohn Marino       tre_do_print(stream, ((tre_catenation_t *)ast->obj)->left, indent + 2);
2035f2eab64SJohn Marino       tre_do_print(stream, ((tre_catenation_t *)ast->obj)->right, indent + 2);
2045f2eab64SJohn Marino       break;
2055f2eab64SJohn Marino     default:
2065f2eab64SJohn Marino       assert(0);
2075f2eab64SJohn Marino       break;
2085f2eab64SJohn Marino     }
2095f2eab64SJohn Marino }
2105f2eab64SJohn Marino 
2115f2eab64SJohn Marino static void
tre_ast_fprint(FILE * stream,tre_ast_node_t * ast)2125f2eab64SJohn Marino tre_ast_fprint(FILE *stream, tre_ast_node_t *ast)
2135f2eab64SJohn Marino {
2145f2eab64SJohn Marino   tre_do_print(stream, ast, 0);
2155f2eab64SJohn Marino }
2165f2eab64SJohn Marino 
2175f2eab64SJohn Marino void
tre_ast_print(tre_ast_node_t * tree)2185f2eab64SJohn Marino tre_ast_print(tre_ast_node_t *tree)
2195f2eab64SJohn Marino {
2205f2eab64SJohn Marino   printf("AST:\n");
2215f2eab64SJohn Marino   tre_ast_fprint(stdout, tree);
2225f2eab64SJohn Marino }
2235f2eab64SJohn Marino 
2245f2eab64SJohn Marino #endif /* TRE_DEBUG */
2255f2eab64SJohn Marino 
2265f2eab64SJohn Marino /* EOF */
227