librdesc
Loading...
Searching...
No Matches
grammar.c
1#include "grammar.h"
2
3#include <rdesc/grammar.h>
4#include <rdesc/rule_macros.h>
5
6#include <stdlib.h>
7#include <string.h>
8
9
12struct rdesc_grammar_symbol pm_grammar[PM_PRODUCTION_COUNT]
13 [PM_MAX_ALTERNATIVE_COUNT + 1]
14 [PM_MAX_ALTERNATIVE_SIZE + 1] = {
16/* <stmt> ::= */ r(
17 NT(EXPR), TK(SEMI)
18),
19/* <expr> ::= */ r(
20 NT(EXPONENTIATION_EXPR), TK(PIPE), NT(PIPE_EXPR)
21alt NT(EXPONENTIATION_EXPR)
22)
24,
26/* <exponentiation_expr> ::= */
27 rrr(EXPONENTIATION_EXPR, (TK(NUM)), (TK(CARET), TK(NUM))),
28/* this also expands to <exponentiation_expr_rest> */
29
30/* <pipe_expr> ::= */
31 rrr(PIPE_EXPR, (NT(FUNCTION_CALL)), (TK(PIPE), NT(FUNCTION_CALL))),
32/* similarly, this also expands to <pipe_expr_rest> */
33
34/* <function_arg_ls> ::= */
35 rrr(FUNCTION_ARG_LS, (NT(EXPR)), (TK(COMMA), NT(EXPR)))
36/* <function_arg_ls_rest> */
38,
40/* <function_call> ::= */ r(
41 TK(IDENT), TK(LPAREN), NT(FUNCTION_ARG_LS), TK(RPAREN)
42alt TK(IDENT)
43)
46};
47
49const char *tk_names[] = {
50 "\0", /* We skip token with id 0, as we started enum from 1. */
51 "@num", "@ident", /* rdesc_dump_bnf utility wraps tokens with double
52 * quotes ("). Use @ to suppress automatic wrap. */
53 "(", ")", "|", "^", ",", ";",
54};
55
57const char *nt_names[] = {
58 "stmt", "expr",
59
60 "exponentiation_expr", "exponentiation_expr_rest",
61 "pipe_expr", "pipe_expr_rest",
62
63 "function_arg_ls", "function_arg_ls_rest",
64
65 "function_call",
66};
68
70const char exblex_tks[] = {
71 '\0', /* exblex requires null termination at the beginning and end */
72 'd', /* num */ 'w', /* ident */
73 '(', ')', '|', '^', ',', ';',
74 '\0'
75};
77
78
80void tk_destroyer(uint16_t id, void *seminfo)
81{
82 if (id == TK_NUM || id == TK_IDENT) {
83 char *string;
84
85 /* seminfo is a pointer to user-specific data, which is char *
86 * in our program. Extract the char * from void * by
87 * type-punning. */
88 memcpy(&string, seminfo, sizeof(char *));
89
90 free(string);
91 }
92}
94
95
97#include <rdesc/cst_macros.h>
98
99void node_printer(FILE *out, const struct rdesc_node *node)
100{
101 if (rtype(node) == RDESC_TOKEN) {
102 if (rid(node) == TK_NUM || rid(node) == TK_IDENT) {
103 char *string;
104
105 memcpy(&string, rseminfo(node), sizeof(char *));
106
107 fprintf(out, "[shape=box,label=<%s>]", string);
108 } else {
109 fprintf(out, "[shape=box,label=<%s>]", tk_names[rid(node)]);
110 }
111 } else {
112 fprintf(out, "[label=\"%s\"]", nt_names[rid(node)]);
113 }
114
115}
#define rid(node)
Returns the 15-bit identifier for underlying token/nonterminal.
Definition cst_macros.h:77
#define rtype(node)
Returns node type (RDESC_TOKEN or RDESC_NONTERMINAL).
Definition cst_macros.h:70
#define rseminfo(tk_node)
Returns a reference to the token's seminfo field.
Definition cst_macros.h:99
Grammar data structures.
@ RDESC_TOKEN
Token.
Definition grammar.h:75
#define rrr(head, base, suffix)
Defines right-recursive list rules. base and suffix parameters should wrapped with parenthesis (()).
#define NT(nt)
Macro to create a nonterminal production symbol.
Definition rule_macros.h:58
#define TK(tk)
Macro to create a terminal (token) production symbol.
Definition rule_macros.h:56
#define r(...)
Macro to define a grammar rule. Adds end of alternative and end of production body sentinels to gramm...
Definition rule_macros.h:72
#define alt
Separates grammar alternatives (alternative separator).
A terminal or nonterminal representing the body (right side) of a production rule.
Definition grammar.h:89