Example #1
0
File: ast.c Project: dylanmm/basicd
void dump_ast(FILE *dotfile, node* start_node, int index) {
    switch(start_node->type) {
    case T_ADD :
        fprintf(dotfile, "node%i [label=\"+\"];\n", index);
        break;
    case T_MUL :
        fprintf(dotfile, "node%i [label=\"*\"];\n", index);
        break;
    case T_VAL :
        fprintf(dotfile, "node%i [label=\"%i\"];\n", index,start_node->value);
        break;
    default :
        fprintf(dotfile, "node%i;\n", index);
    }
    if (start_node->value > 0) {
        fprintf(dotfile, "node%i [label=\"%i\"];\n", index,start_node->value);
    }
    if (start_node->left > 0) {
        fprintf(dotfile, "node%i->node%i;\n", index, 2*index);
        dump_ast(dotfile, start_node->left,2*index);
    }
    if (start_node->right > 0) {
        fprintf(dotfile, "node%i->node%i;\n", index, 2*index+1);
        dump_ast(dotfile, start_node->right,2*index+1);
    }
}
Example #2
0
void test3(void) {
  int last = -42;
  struct ast * ast;
  struct gram * gram;
  // gram = int !.;
  gram = new_gram_cat(NULL,
      new_gram_int(NULL),
      new_gram_negla(NULL,
	new_gram_dot(NULL)),
      NULL);
  const char * text = "42";
  // debug:
  ast = parse(text, gram, &last);
  printf("matching \"42\"\nast=%p, last = %d\n", ast, last);
  dump_ast(ast, 0, NULL);
  // assertions:
  assert(ast);
  assert(ast->children[0]);
  assert(ast->children[0]->from == 0);
  assert(ast->children[0]->len == 2);
  assert(strtol(text + ast->children[0]->from, NULL, 0) == 42);
  assert(ast->children[1]);
  assert(last == strlen(text));
  // debug:
  last = -42;
  text = " 0xfoo";
  ast = parse(text, gram, &last);
  printf("matching \" 0xfoo\"\nast=%p, last = %d\n", ast, last);
  dump_ast(ast, 0, NULL);
  // assertions:
  assert(!ast);
  assert(last == 4);
  printf("test3 passed!\n\n");
}
Example #3
0
void test4(void) {
  int last = -42;
  struct ast * ast;
  struct gram * gram;
  // gram == ('a'/'b')+!.
  gram = new_gram_cat(NULL,
      new_gram_aster(NULL,
	  new_gram_alt(NULL, 
	      new_gram_string((void*)0xa, "a"),
	      new_gram_string((void*)0xb, "b"),
	      NULL)),
      new_gram_negla(NULL,
	  new_gram_dot(NULL)),
      NULL);
  const char * text = "baba";
  ast = parse(text, gram, &last);
  // debug:
  dump_ast(ast, 0, NULL);
  assert(ast);
  ast = purge_ast(ast);
  printf("after cleanup:\n");
  dump_ast(ast, 0, NULL);
  // assertions:
  assert(ast);
  assert(ast->children[0] && ast->children[1]
      && ast->children[2] && ast->children[3]);
  assert(!ast->children[4]);
  printf("test4 passed!\n\n");
}
Example #4
0
void test1(void) {
  // gram = 'a'*!.;
  struct gram * gram;
  gram = new_gram_cat(NULL,
      new_gram_aster(NULL,
	  new_gram_string(NULL, "a")),
      new_gram_negla(NULL,
	  new_gram_dot(NULL)),
      NULL);
  assert(gram);
  int i, last = -42;
  struct ast * ast = parse("aaa", gram, &last);
  // debug
  printf("matching \"aaa\"\nast=%p, last = %d\n", ast, last);
  dump_ast(ast, 0, NULL);
  // assertions
  assert(last == 3);
  assert(ast);
  assert(ast->children[0] && ast->children[1] && !ast->children[2]);
  assert(ast->children[0]->from == 0 && ast->children[0]->len == 3);
  assert(ast->children[1]->from == 3 && ast->children[1]->len == 0);
  for (i = 0; i < 3; i++)
    assert(ast->children[0]->children[i]->from == i
	&& ast->children[0]->children[i]->len == 1
	&& !ast->children[0]->children[i]->children[0]);
  // debug
  last = -42;
  ast = parse("aaa!", gram, &last);
  printf("matching \"aaa!\"\nast=%p, last = %d\n", ast, last);
  dump_ast(ast, 0, NULL);
  // assertions
  assert(last == 3);
  assert(!ast);
  printf("test1 passed!\n\n");
}
Example #5
0
/* ------------------------------------------------------------------------
@NAME       : bt_parse_entry_s()
@INPUT      : entry_text - string containing the entire entry to parse,
                           or NULL meaning we're done, please cleanup
              options    - standard btparse options bitmap
              line       - current line number (if that makes any sense)
                           -- passed to the parser to set zzline, so that
                           lexical and syntax errors are properly localized
@OUTPUT     : *top       - newly-allocated AST for the entry
                           (or NULL if entry_text was NULL, ie. at EOF)
@RETURNS    : 1 with *top set to AST for entry on successful read/parse
              1 with *top==NULL if entry_text was NULL, ie. at EOF
              0 if any serious errors seen in input (*top is still 
                set to the AST, but only for as much of the input as we
                were able to parse)
              (A "serious" error is a lexical or syntax error; "trivial"
              errors such as warnings and notifications count as "success"
              for the purposes of this function's return value.)
@DESCRIPTION: Parses a BibTeX entry contained in a string.
@GLOBALS    : 
@CALLS      : ANTLR
@CREATED    : 1997/01/18, GPW (from code in bt_parse_entry())
@MODIFIED   : 
-------------------------------------------------------------------------- */
AST * bt_parse_entry_s (char *    entry_text,
                        char *    filename,
                        int       line,
                        ushort    options,
                        boolean * status)
{
   AST *        entry_ast = NULL;
   static int * err_counts = NULL;

   if (options & BTO_STRINGMASK)        /* any string options set? */
   {
      usage_error ("bt_parse_entry_s: illegal options "
                   "(string options not allowed");
   }

   InputFilename = filename;
   err_counts = bt_get_error_counts (err_counts);

   if (entry_text == NULL)              /* signal to clean up */
   {
      finish_parse (&err_counts);
      if (status) *status = TRUE;
      return NULL;
   }

   zzast_sp = ZZAST_STACKSIZE;          /* workaround apparent pccts bug */
   start_parse (NULL, entry_text, line);

   entry (&entry_ast);                  /* enter the parser */
   ++zzasp;                             /* why is this done? */

   if (entry_ast == NULL)               /* can happen with very bad input */
   {
      if (status) *status = FALSE;
      return entry_ast;
   }

#if DEBUG
   dump_ast ("bt_parse_entry_s: single entry, after parsing:\n", 
             entry_ast);
#endif
   bt_postprocess_entry (entry_ast,
                         StringOptions[entry_ast->metatype] | options);
#if DEBUG
   dump_ast ("bt_parse_entry_s: single entry, after post-processing:\n",
             entry_ast);
#endif

   if (status) *status = parse_status (err_counts);
   return entry_ast;

} /* bt_parse_entry_s () */
Example #6
0
void test2(void) {
  struct gram * gram, * tmp;
  struct ast * ast;
  int last = -42;
  // gram = ('[' gram ']')+ / "";
  gram = new_gram_alt((void*)0xa,
      new_gram_plus((void*)0x35,
	tmp = new_gram_cat((void*)0xc,
	  new_gram_string(NULL, "["),
	  (struct gram *)(-1),
	  new_gram_string(NULL, "]"),
	  NULL)),
      new_gram_string((void*)0x1337, ""),
      NULL);
  assert(gram);
  // add cyclic reference by setting child:
  gram_set_child(tmp, gram, 1);
  // debug
  ast = parse("[[][]x]", gram, &last);
  printf("matching \"[[][]x]\"\nast=%p, last = %d\n", ast, last);
  dump_ast(ast, 0, NULL);
  // assertions
  assert(ast);
  assert("[[][]x]"[last] == 'x');
  assert(ast->children[0]);
  assert(ast->children[0]->user_data == (void*)0x1337);
  assert(!ast->children[1]);
  printf("test2 passed!\n\n");
}
Example #7
0
static void branch(const struct ast_node *ast)
{
	if (ast) {
		putchar(' ');
		dump_ast(ast);
	}
}
Example #8
0
static void runPass(const char *passName, void (*pass)(void), void (*check)(), char log_tag) {
  static struct timeval startTimeBetweenPasses;
  static struct timeval stopTimeBetweenPasses;
  static double timeBetweenPasses = -1.0;
  static double totalTime = 0.0;
  struct timeval startTime;
  struct timeval stopTime;
  struct timezone timezone;
  static bool performTiming = printPasses || (printPassesFile != NULL);

  if (performTiming) {
    gettimeofday(&stopTimeBetweenPasses, &timezone);
    if (timeBetweenPasses < 0.0)
      timeBetweenPasses = 0.0;
    else
      timeBetweenPasses += 
        ((double)((stopTimeBetweenPasses.tv_sec*1e6+
                   stopTimeBetweenPasses.tv_usec) - 
                  (startTimeBetweenPasses.tv_sec*1e6+
                   startTimeBetweenPasses.tv_usec))) / 1e6;
  }
  if (strlen(fPrintStatistics) && strcmp(passName, "parse"))
    printStatistics("clean");
  if (performTiming) {
    printPassTiming("%32s :", passName);
    gettimeofday(&startTime, &timezone);
  }
  (*pass)();
  if (performTiming) {
    gettimeofday(&stopTime, &timezone);
    printPassTiming("%8.3f seconds",
            ((double)((stopTime.tv_sec*1e6+stopTime.tv_usec) - 
                      (startTime.tv_sec*1e6+startTime.tv_usec))) / 1e6);
    if (developer && printPasses) fprintf(stderr, "  [%d]", lastNodeIDUsed());
    printPassTiming("\n");
    totalTime += ((double)((stopTime.tv_sec*1e6+stopTime.tv_usec) - 
                           (startTime.tv_sec*1e6+startTime.tv_usec))) / 1e6;
    if (!strcmp(passName, "makeBinary")) {
      printPassTiming("%32s :%8.3f seconds\n", "time between passes",
              timeBetweenPasses);
      printPassTiming("%32s :%8.3f seconds\n", "total time",
              totalTime+timeBetweenPasses);
    }
  }
  if (strlen(fPrintStatistics))
    printStatistics(passName);
  if (fdump_html) {
    html_view(passName);
  }
  if (logging(log_tag))
    dump_ast(passName, currentPassNo);
  if (performTiming) {
    gettimeofday(&startTimeBetweenPasses, &timezone);
  }
  considerExitingEndOfPass();
  cleanAst();
  (*check)(); // Run per-pass check function.
  //printPrimitiveCounts(passName);
}
Example #9
0
static const char *assign_per_vertex(struct parser_comm *comm,
    struct sym *sym, struct ast_node *node)
{
	if (!quiet) {
		printf("per_vertex = %s = ", sym->fpvm_sym.name);
		dump_ast(node);
		putchar('\n');
	}
	return NULL;
}
Example #10
0
File: main.c Project: arnognulf/v7
int main(int argc, char *argv[]) {
  struct v7 *v7;
  int i, show_ast = 0;

  v7 = v7_create();

  /* Execute inline code */
  for (i = 1; i < argc && argv[i][0] == '-'; i++) {
    if (strcmp(argv[i], "-e") == 0 && i + 1 < argc) {
      if (show_ast) {
        dump_ast(argv[i + 1]);
      } else if (!v7_exec(v7, argv[i + 1])) {
        fprintf(stderr, "Error executing [%s]: %s\n", argv[i + 1],
                v7_get_error_string(v7));
      }
      i++;
    } else if (strcmp(argv[i], static_show_ast_flag) == 0) {
      show_ast = 1;
    } else if (strcmp(argv[i], "-h") == 0) {
      show_usage(argv);
    }
  }

  /* Execute files */
  for (; i < argc; i++) {
    if (show_ast) {
      size_t size;
      char *source_code;
      if ((source_code = read_file(argv[i], &size)) == NULL) {
        fprintf(stderr, "Cannot read [%s]\n", argv[i]);
      } else {
        dump_ast(source_code);
        free(source_code);
      }
    } else if (!v7_exec_file(v7, argv[i])) {
      fprintf(stderr, "%s\n", v7_get_error_string(v7));
    }
  }

  v7_destroy(&v7);
  return EXIT_SUCCESS;
}
Example #11
0
void
dump_typedefs()
{
  Dict *defs = init_typedefs();
  for (int i = 0; i < defs->entries->length; i++) {
    DictEntry *entry = vector_get(defs->entries, i);
    printf("'%s':\n", entry->key);
    Node *type = entry->data;
    dump_ast(type);
  }
}
Example #12
0
static const char *assign_default(struct parser_comm *comm,
    struct sym *sym, struct ast_node *node)
{
	if (fail)
		return strdup(fail);
	if (!quiet) {
		printf("%s = ", sym->fpvm_sym.name);
		dump_ast(node);
		putchar('\n');
	}
	return NULL;
}
Example #13
0
File: ast.c Project: dylanmm/basicd
void graphviz(node* start_node) {
    FILE *dotfile = fopen("ast.dot", "w");
    fprintf(dotfile, "digraph tree {\n");
    dump_ast(dotfile, start_node, 1);
    fprintf(dotfile, "}\n");
    fclose(dotfile);

    // OS X
    //system("dot -Tpng ast.dot > ast.png && open ast.png");

    // Linux
    system("dot -Tpng ast.dot > ast.png && xdg-open ast.png");
}
Example #14
0
static void dump_ast(SpnAST *ast, int indent)
{
	static const char *const nodnam[] = {
		"program",
		"block-statement",
		"function-statement",

		"while",
		"do-while",
		"for",
		"foreach",
		"if",

		"break",
		"continue",
		"return",
		"empty-statement",
		"vardecl",
		"global-constant",

		"assign",
		"assign-add",
		"assign-subtract",
		"assign-multiply",
		"assign-divide",
		"assign-modulo",
		"assign-and",
		"assign-or",
		"assign-xor",
		"assign-left-shift",
		"assign-right-shift",
		"assign-concat",

		"concatenate",
		"conditional-ternary",

		"add",
		"subtract",
		"multiply",
		"divide",
		"modulo",

		"logical-and",
		"logical-or",
		"bitwise-and",
		"bitwise-or",
		"bitwise-xor",
		"left-shift",
		"right-shift",

		"equals",
		"not-equal",
		"less-than",
		"less-than-or-equal",
		"greater-than",
		"greater-than-or-equal",

		"unary-plus",
		"unary-minus",
		"preincrement",
		"predecrement",
		"sizeof",
		"typeof",
		"logical-not",
		"bitwise-not",
		"nth-arg",

		"postincrement",
		"postdecrement",
		"array-subscript",
		"memberof",
		"function-call",

		"identifier",
		"literal",
		"function-expr",
		"argc",

		"decl-argument",
		"call-argument",
		"branches",
		"for-header",
		"generic-compound"
	};

	dump_indent(indent);
	printf("(%s", nodnam[ast->node]);

	/* print name, if any */
	if (ast->name != NULL) {
		printf(" name = \"%s\"", ast->name->cstr);
	}

	/* print formatted value */
	if ((ast->value.t == SPN_TYPE_NIL && ast->node == SPN_NODE_LITERAL)
	  || ast->value.t != SPN_TYPE_NIL) {
		printf(" value = ");
		spn_value_print(&ast->value);
	}

	if (ast->left != NULL || ast->right != NULL) {
		fputc('\n', stdout);
	}

	/* dump subtrees, if any */
	if (ast->left != NULL) {
		dump_ast(ast->left, indent + 1);
	}

	if (ast->right != NULL) {
		dump_ast(ast->right, indent + 1);
	}

	if (ast->left != NULL || ast->right != NULL) {
		dump_indent(indent);
	}

	puts(")");
}
Example #15
0
void spn_ast_dump(SpnAST *ast)
{
	dump_ast(ast, 0);
}
Example #16
0
/* ------------------------------------------------------------------------
@NAME       : bt_parse_entry()
@INPUT      : infile  - file to read next entry from
              options - standard btparse options bitmap
@OUTPUT     : *top    - AST for the entry, or NULL if no entries left in file
@RETURNS    : same as bt_parse_entry_s()
@DESCRIPTION: Starts (or continues) parsing from a file.
@GLOBALS    : 
@CALLS      : 
@CREATED    : Jan 1997, GPW
@MODIFIED   : 
-------------------------------------------------------------------------- */
AST * bt_parse_entry (FILE *    infile,
                      char *    filename,
                      ushort    options,
                      boolean * status)
{
   AST *         entry_ast = NULL;
   static int *  err_counts = NULL;
   static FILE * prev_file = NULL;

   if (prev_file != NULL && infile != prev_file)
   {
      usage_error ("bt_parse_entry: you can't interleave calls "
                   "across different files");
   }

   if (options & BTO_STRINGMASK)        /* any string options set? */
   {
      usage_error ("bt_parse_entry: illegal options "
                   "(string options not allowed)");
   }

   InputFilename = filename;
   err_counts = bt_get_error_counts (err_counts);

   if (feof (infile))
   {
      if (prev_file != NULL)            /* haven't already done the cleanup */
      {
         prev_file = NULL;
         finish_parse (&err_counts);
      }
      else
      {
         usage_warning ("bt_parse_entry: second attempt to read past eof");
      }

      if (status) *status = TRUE;
      return NULL;
   }

   /* 
    * Here we do some nasty poking about the innards of PCCTS in order to
    * enter the parser multiple times on the same input stream.  This code
    * comes from expanding the macro invokation:
    * 
    *    ANTLR (entry (top), infile);  
    * 
    * When LL_K, ZZINF_LOOK, and DEMAND_LOOK are all undefined, this
    * ultimately expands to
    * 
    *    zzbufsize = ZZLEXBUFSIZE;
    *    {
    *       static char zztoktext[ZZLEXBUFSIZE];
    *       zzlextext = zztoktext; 
    *       zzrdstream (f);
    *       zzgettok();
    *    }
    *    entry (top);
    *    ++zzasp;
    * 
    * (I'm expanding hte zzenterANTLR, zzleaveANTLR, and zzPrimateLookAhead
    * macros, but leaving ZZLEXBUFSIZE -- a simple constant -- alone.)
    * 
    * There are two problems with this: 1) zztoktext is a statically
    * allocated buffer, and when it overflows we just ignore further
    * characters that should belong to that lexeme; and 2) zzrdstream() and
    * zzgettok() are called every time we enter the parser, which means the
    * token left over from the previous entry will be discarded when we
    * parse entries 2 .. N.
    * 
    * I handle the static buffer problem with alloc_lex_buffer() and
    * realloc_lex_buffer() (in lex_auxiliary.c), and by rewriting the ZZCOPY
    * macro to call realloc_lex_buffer() when overflow is detected.
    * 
    * I handle the extra token-read by hanging on to a static file
    * pointer, prev_file, between calls to bt_parse_entry() -- when
    * the program starts it is NULL, and we reset it to NULL on
    * finishing a file.  Thus, any call that is the first on a given
    * file will allocate the lexical buffer and read the first token;
    * thereafter, we skip those steps, and free the buffer on reaching
    * end-of-file.  Currently, this method precludes interleaving
    * calls to bt_parse_entry() on different files -- perhaps I could
    * fix this with the zz{save,restore}_{antlr,dlg}_state()
    * functions?
    */

   zzast_sp = ZZAST_STACKSIZE;          /* workaround apparent pccts bug */

#if defined(LL_K) || defined(ZZINF_LOOK) || defined(DEMAND_LOOK)
# error One of LL_K, ZZINF_LOOK, or DEMAND_LOOK was defined
#endif
   if (prev_file == NULL)               /* only read from input stream if */
   {                                    /* starting afresh with a file */
      start_parse (infile, NULL, 0);
      prev_file = infile;
   }
   assert (prev_file == infile);

   entry (&entry_ast);                  /* enter the parser */
   ++zzasp;                             /* why is this done? */

   if (entry_ast == NULL)               /* can happen with very bad input */
   {
      if (status) *status = FALSE;
      return entry_ast;
   }

#if DEBUG
   dump_ast ("bt_parse_entry(): single entry, after parsing:\n", 
             entry_ast);
#endif
   bt_postprocess_entry (entry_ast,
                         StringOptions[entry_ast->metatype] | options);
#if DEBUG
   dump_ast ("bt_parse_entry(): single entry, after post-processing:\n", 
             entry_ast);
#endif

   if (status) *status = parse_status (err_counts);
   return entry_ast;

} /* bt_parse_entry() */