Skip to content
Snippets Groups Projects
Commit db1fc26c authored by Sven M. Hallberg's avatar Sven M. Hallberg
Browse files

add examples/ttuser - show custom tokens/pprint

parent 8fc72361
No related branches found
No related tags found
No related merge requests found
Pipeline #19 canceled with stages
...@@ -6,8 +6,9 @@ example = env.Clone() ...@@ -6,8 +6,9 @@ example = env.Clone()
example.Append(LIBS="hammer", LIBPATH="../src") example.Append(LIBS="hammer", LIBPATH="../src")
dns = example.Program('dns', ['dns.c', 'rr.c', 'dns_common.c']) dns = example.Program('dns', ['dns.c', 'rr.c', 'dns_common.c'])
ttuser = example.Program('ttuser', 'ttuser.c')
base64 = example.Program('base64', 'base64.c') base64 = example.Program('base64', 'base64.c')
base64_sem1 = example.Program('base64_sem1', 'base64_sem1.c') base64_sem1 = example.Program('base64_sem1', 'base64_sem1.c')
base64_sem2 = example.Program('base64_sem2', 'base64_sem2.c') base64_sem2 = example.Program('base64_sem2', 'base64_sem2.c')
ties = example.Program('ties', ['ties.c', 'grammar.c']) ties = example.Program('ties', ['ties.c', 'grammar.c'])
env.Alias("examples", [dns, base64, base64_sem1, base64_sem2, ties]) env.Alias("examples", [dns, ttuser, base64, base64_sem1, base64_sem2, ties])
\ No newline at end of file
/*
* Example parser that demonstrates the use of user-defined token types.
*
* Note the custom printer function that hooks into h_pprint().
*/
#include "../src/hammer.h"
#include "../src/glue.h"
/*
* custom tokens
*/
HTokenType TT_SUBJ, TT_PRED, TT_OBJ, TT_ADJ, TT_ADVC;
void
pprint(FILE *stream, const HParsedToken *tok, int indent, int delta)
{
/*
* Pretty-printer rules:
*
* - Output 'indent' spaces after every newline you produce.
* - Do not add indent on the first line of output.
* - Do not add a trailing newline.
* - Indent sub-objects by adding 'delta' to 'indent'.
*/
if (((HParsedToken *)tok->user)->token_type == TT_SEQUENCE)
fprintf(stream, "\n%*s", indent, "");
h_pprint(stream, tok->user, indent, delta);
}
/* XXX define umamb_sub as well */
void
init(void)
{
TT_SUBJ = h_allocate_token_new("subject", NULL, pprint);
TT_PRED = h_allocate_token_new("predicate", NULL, pprint);
TT_OBJ = h_allocate_token_new("object", NULL, pprint);
TT_ADJ = h_allocate_token_new("adjective", NULL, pprint);
TT_ADVC = h_allocate_token_new("adverbial clause", NULL, pprint);
}
/*
* semantic actions
*
* Normally these would be more interesting, but for this example, we just wrap
* our tokens in their intended types.
*/
HParsedToken *act_subj(const HParseResult *p, void *u) {
return H_MAKE(SUBJ, (void *)p->ast);
}
HParsedToken *act_pred(const HParseResult *p, void *u) {
return H_MAKE(PRED, (void *)p->ast);
}
HParsedToken *act_obj(const HParseResult *p, void *u) {
return H_MAKE(OBJ, (void *)p->ast);
}
HParsedToken *act_adj(const HParseResult *p, void *u) {
return H_MAKE(ADJ, (void *)p->ast);
}
HParsedToken *act_advc(const HParseResult *p, void *u) {
return H_MAKE(ADVC, (void *)p->ast);
}
/*
* grammar
*/
HParser *
build_parser(void)
{
/* words */
#define W(X) h_whitespace(h_literal(#X))
H_RULE(art, h_choice(W(a), W(the), NULL));
H_RULE(noun, h_choice(W(cat), W(dog), W(fox), W(tiger), W(lion),
W(bear), W(fence), W(tree), W(car), W(cow), NULL));
H_RULE(verb, h_choice(W(eats), W(jumps), W(falls), NULL));
H_ARULE(adj, h_choice(W(quick), W(slow), W(happy), W(lazy), W(cyan),
W(magenta), W(yellow), W(black), W(brown), NULL));
H_RULE(adverb, h_choice(W(with), W(over), W(after), NULL));
#undef W
/* phrases */
H_RULE(nphrase, h_sequence(art, h_many(adj), noun, NULL));
/* sentence structure */
H_ARULE(subj, nphrase);
H_ARULE(pred, verb);
H_ARULE(obj, nphrase);
H_ARULE(advc, h_sequence(adverb, nphrase, NULL));
H_RULE(sentnc, h_sequence(subj, pred,
h_optional(obj), h_optional(advc), NULL));
return sentnc;
}
/*
* main routine: read, parse, print
*
* input e.g.:
* "the quick brown fox jumps the fence with a cyan lion"
*/
#include <stdio.h>
#include <inttypes.h>
int
main(int argc, char **argv)
{
uint8_t input[1024];
size_t sz;
const HParser *parser;
const HParseResult *result;
init();
parser = build_parser();
sz = fread(input, 1, sizeof(input), stdin);
if (!feof(stdin)) {
fprintf(stderr, "too much input\n");
return 1;
}
result = h_parse(parser, input, sz);
if (!result) {
fprintf(stderr, "no parse\n");
return 1;
}
h_pprintln(stdout, result->ast);
fprintf(stderr, "consumed %" PRId64 "/%zu bytes.\n",
result->bit_length / 8, sz);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment