aboutsummaryrefslogblamecommitdiffstats
path: root/print-syntax.c
blob: 5f2e5e344d215107230d2acd62be49b708f1cfee (plain) (tree)


































































































































                                                                                                                
/* See LICENSE file for copyright and license details. */

/* This file exist to help debugging */

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "libparser.h"


static int
print_sentence(const union libparser_sentence *sentence, int indent)
{
	int len;

	switch (sentence->type) {
	case LIBPARSER_SENTENCE_TYPE_CONCATENATION:
		printf("(");
		indent = print_sentence(sentence->binary.left, indent + 1);
		printf(", ");
		indent = print_sentence(sentence->binary.right, indent + 2);
		printf(")");
		indent + 1;
		break;

	case LIBPARSER_SENTENCE_TYPE_ALTERNATION:
		printf("(");
		print_sentence(sentence->binary.left, indent + 1);
		printf(" | \n%*.s", indent + 1, "");
		indent = print_sentence(sentence->binary.right, indent + 1);
		printf(")");
		indent + 1;
		break;

	case LIBPARSER_SENTENCE_TYPE_REJECTION:
		printf("!(");
		indent = print_sentence(sentence->unary.sentence, indent + 2);
		printf(")");
		indent + 1;
		break;

	case LIBPARSER_SENTENCE_TYPE_OPTIONAL:
		printf("[");
		indent = print_sentence(sentence->unary.sentence, indent + 1);
		printf("]");
		indent + 1;
		break;

	case LIBPARSER_SENTENCE_TYPE_REPEATED:
		printf("{");
		indent = print_sentence(sentence->unary.sentence, indent + 1);
		printf("}");
		indent += 1;
		break;

	case LIBPARSER_SENTENCE_TYPE_STRING:
		printf("\"%.*s\"%n", (int)sentence->string.length, sentence->string.string, &len);
		indent += len;
		break;

	case LIBPARSER_SENTENCE_TYPE_CHAR_RANGE:
		if (isprint(sentence->char_range.low) && isprint(sentence->char_range.high))
			printf("<\"%c\", \"%c\">%n", sentence->char_range.low, sentence->char_range.high, &len);
		else if (isprint(sentence->char_range.low))
			printf("<\"%c\", 0x%02x>%n", sentence->char_range.low, sentence->char_range.high, &len);
		else if (isprint(sentence->char_range.high))
			printf("<0x%02x, \"%c\">%n", sentence->char_range.low, sentence->char_range.high, &len);
		else
			printf("<0x%02x, 0x%02x>%n", sentence->char_range.low, sentence->char_range.high, &len);
		indent += len;
		break;

	case LIBPARSER_SENTENCE_TYPE_RULE:
		printf("%s%n", sentence->rule.rule, &len);
		indent += len;
		break;

	case LIBPARSER_SENTENCE_TYPE_EXCEPTION:
		printf("-");
		indent += 1;
		break;

	case LIBPARSER_SENTENCE_TYPE_EOF:
		printf("%s%n", "(* end of file *)", &len);
		indent += len;
		break;

	default:
		abort();
	}

	return indent;
}


int
main(int argc, char *argv[0])
{
	size_t i;
	int indent, first = 1;

	if (argc != 1) {
		fprintf(stderr, "usage: %s\n", argv[0]);
		return 1;
	}

	for (i = 0; libparser_rule_table[i]; i++) {
		if (libparser_rule_table[i]->name[0] == '@')
			continue;

		if (!first) {
			printf("\n");
		} else {
			first = 0;
		}

		printf("%s = %n", libparser_rule_table[i]->name, &indent);
		print_sentence(libparser_rule_table[i]->sentence, indent);
		printf(";\n");

	}

	if (fflush(stdout) || ferror(stdout) || fclose(stdout)) {
		fprintf(stderr, "%s: printf: %s\n", argv[0], strerror(errno));
		return 1;
	}
	return 0;
}