%{ /* * lang.y - BOOM grammar * * Copyright 2012 by Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include "util.h" #include "param.h" #include "chr.h" #include "y.tab.h" %} %union { const char *s; struct equiv *equiv; struct names *names; struct format *format; enum relop relop; }; %token TOK_LE TOK_GE %token WORD %type nameqs %type names nameq %type format %type relop opt_relop %% all: | nameset ';' | rules ; nameset: '<' WORD '>' '=' names ';' { register_nameset($2, $5); } ; names: nameq { $$ = $1; } | nameq '<' names { $$ = $1; $$->next = $3; } ; nameq: nameqs { $$ = alloc_type(struct names); $$->equiv = $1; $$->next = NULL; } ; nameqs: WORD { $$ = alloc_type(struct equiv); $$->name = $1; $$->next = NULL; } | WORD '=' nameqs { $$ = alloc_type(struct equiv); $$->name = $1; $$->next = $3; } ; rules: field '{' { field_mark(); } selections opt_wildcard '}' { field_release(); } ; selections: | selectors ':' opt_fields rules selections ; selectors: selector | selector '|' { field_more_selectors(); } selectors ; selector: opt_relop WORD { field_add_selector($1, $2); } ; opt_wildcard: '*' ':' { field_add_wildcard(); } ; opt_relop: { $$ = rel_eq; } | relop { $$ = $1; } ; relop: '=' { $$ = rel_eq; } | '<' { $$ = rel_le; } | '>' { $$ = rel_gt; } | TOK_LE { $$ = rel_le; } | TOK_GE { $$ = rel_ge; } ; opt_fields: | '{' fields '}' ; fields: | field fields ; field: WORD ':' format { field_add($1, $3); } ; format: '*' { $$ = alloc_type(struct format); $$->ops = ¶m_ops_name; } | '<' WORD '>' { $$ = alloc_type(struct format); $$->ops = ¶m_ops_set; $$->u.set = find_nameset($2); if (!$$->u.set) yyerrorf("unknown name set \"%s\"", $2); } | '#' WORD { $$ = alloc_type(struct format); $$->ops = ¶m_ops_abs; $$->u.abs = $2; } | '%' WORD { $$ = alloc_type(struct format); $$->ops = ¶m_ops_rel; $$->u.rel = field_find($2); if (!$$->u.rel) yyerrorf("unknown field \"%s\"", $2); } ;