blob: 1a7ec4970d5ae270c3fa76eaac921462972f6cbb [file] [log] [blame]
Carl Worth3a37b872010-05-10 11:44:09 -07001%{
2/*
3 * Copyright © 2010 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <stdio.h>
26#include <stdlib.h>
Carl Worth33cc4002010-05-12 12:17:10 -070027#include <talloc.h>
Carl Worth3a37b872010-05-10 11:44:09 -070028
Carl Wortha1e32bc2010-05-10 13:17:25 -070029#include "glcpp.h"
30
Carl Worth0b27b5f2010-05-10 16:16:06 -070031#define YYLEX_PARAM parser->scanner
Carl Worth3a37b872010-05-10 11:44:09 -070032
Carl Worth33cc4002010-05-12 12:17:10 -070033struct glcpp_parser {
34 yyscan_t scanner;
35 struct hash_table *defines;
36};
37
Carl Worth3a37b872010-05-10 11:44:09 -070038void
Carl Wortha1e32bc2010-05-10 13:17:25 -070039yyerror (void *scanner, const char *error);
Carl Worth3a37b872010-05-10 11:44:09 -070040
Carl Worth33cc4002010-05-12 12:17:10 -070041void
42_print_resolved_token (glcpp_parser_t *parser, const char *token);
43
44list_t *
45_list_create (void *ctx);
46
47void
48_list_append (list_t *list, const char *str);
Carl Worthc6d5af32010-05-11 12:30:09 -070049
Carl Worth3a37b872010-05-10 11:44:09 -070050%}
51
Carl Worth33cc4002010-05-12 12:17:10 -070052%union {
53 char *str;
54 list_t *list;
55}
56
Carl Worth0b27b5f2010-05-10 16:16:06 -070057%parse-param {glcpp_parser_t *parser}
Carl Worth38aa8352010-05-10 11:52:29 -070058%lex-param {void *scanner}
59
Carl Worth33cc4002010-05-12 12:17:10 -070060%token DEFINE IDENTIFIER NEWLINE TOKEN
61%type <str> token IDENTIFIER TOKEN
62%type <list> replacement_list
Carl Worth3a37b872010-05-10 11:44:09 -070063
64%%
65
Carl Worth33cc4002010-05-12 12:17:10 -070066input:
67 /* empty */
68| content
Carl Worth3a37b872010-05-10 11:44:09 -070069;
70
Carl Worth33cc4002010-05-12 12:17:10 -070071content:
72 token {
73 _print_resolved_token (parser, $1);
Carl Worth5070a202010-05-12 12:45:33 -070074 talloc_free ($1);
Carl Worth33cc4002010-05-12 12:17:10 -070075 }
76| directive
77| content token {
78 _print_resolved_token (parser, $2);
Carl Worth5070a202010-05-12 12:45:33 -070079 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -070080 }
81| content directive
Carl Worth3a37b872010-05-10 11:44:09 -070082;
83
Carl Worth33cc4002010-05-12 12:17:10 -070084directive:
85 DEFINE IDENTIFIER replacement_list NEWLINE {
Carl Worth5070a202010-05-12 12:45:33 -070086 talloc_steal ($3, $2);
87 hash_table_insert (parser->defines, $3, $2);
Carl Worth33cc4002010-05-12 12:17:10 -070088 printf ("\n");
89 }
90;
91
92replacement_list:
93 /* empty */ {
94 $$ = _list_create (parser);
95 }
96
97| replacement_list token {
98 _list_append ($1, $2);
Carl Worth5070a202010-05-12 12:45:33 -070099 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -0700100 $$ = $1;
101 }
102;
103
104token:
105 TOKEN { $$ = $1; }
106| IDENTIFIER { $$ = $1; }
107;
108
109%%
110
111list_t *
112_list_create (void *ctx)
113{
114 list_t *list;
115
Carl Worth5070a202010-05-12 12:45:33 -0700116 list = xtalloc (ctx, list_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700117 list->head = NULL;
118 list->tail = NULL;
119
120 return list;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700121}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700122
Carl Worth33cc4002010-05-12 12:17:10 -0700123void
124_list_append (list_t *list, const char *str)
125{
126 node_t *node;
Carl Worth3a37b872010-05-10 11:44:09 -0700127
Carl Worth5070a202010-05-12 12:45:33 -0700128 node = xtalloc (list, node_t);
129 node->str = xtalloc_strdup (node, str);
Carl Worth33cc4002010-05-12 12:17:10 -0700130
131 node->next = NULL;
132
133 if (list->head == NULL) {
134 list->head = node;
135 } else {
136 list->tail->next = node;
137 }
138
139 list->tail = node;
140}
141
Carl Worth3a37b872010-05-10 11:44:09 -0700142void
Carl Wortha1e32bc2010-05-10 13:17:25 -0700143yyerror (void *scanner, const char *error)
Carl Worth3a37b872010-05-10 11:44:09 -0700144{
145 fprintf (stderr, "Parse error: %s\n", error);
146}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700147
Carl Worth33cc4002010-05-12 12:17:10 -0700148glcpp_parser_t *
149glcpp_parser_create (void)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700150{
Carl Worth33cc4002010-05-12 12:17:10 -0700151 glcpp_parser_t *parser;
152
Carl Worth5070a202010-05-12 12:45:33 -0700153 parser = xtalloc (NULL, glcpp_parser_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700154
Carl Worth5070a202010-05-12 12:45:33 -0700155 yylex_init_extra (parser, &parser->scanner);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700156 parser->defines = hash_table_ctor (32, hash_table_string_hash,
157 hash_table_string_compare);
Carl Worth33cc4002010-05-12 12:17:10 -0700158
159 return parser;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700160}
161
162int
163glcpp_parser_parse (glcpp_parser_t *parser)
164{
165 return yyparse (parser);
166}
167
168void
Carl Worth33cc4002010-05-12 12:17:10 -0700169glcpp_parser_destroy (glcpp_parser_t *parser)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700170{
171 yylex_destroy (parser->scanner);
172 hash_table_dtor (parser->defines);
Carl Worth33cc4002010-05-12 12:17:10 -0700173 talloc_free (parser);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700174}
Carl Worthc6d5af32010-05-11 12:30:09 -0700175
Carl Worth33cc4002010-05-12 12:17:10 -0700176static void
177_print_resolved_recursive (glcpp_parser_t *parser,
178 const char *token,
179 const char *orig,
180 int *first)
Carl Worthc6d5af32010-05-11 12:30:09 -0700181{
Carl Worth33cc4002010-05-12 12:17:10 -0700182 list_t *replacement;
183 node_t *node;
Carl Worthc6d5af32010-05-11 12:30:09 -0700184
Carl Worth33cc4002010-05-12 12:17:10 -0700185 replacement = hash_table_find (parser->defines, token);
186 if (replacement == NULL) {
187 printf ("%s%s", *first ? "" : " ", token);
188 *first = 0;
189 } else {
190 for (node = replacement->head ; node ; node = node->next) {
191 token = node->str;
192 if (strcmp (token, orig) == 0) {
193 printf ("%s%s", *first ? "" : " ", token);
194 *first = 0;
195 } else {
196 _print_resolved_recursive (parser, token, orig, first);
197 }
198 }
Carl Worthc6d5af32010-05-11 12:30:09 -0700199 }
Carl Worthc6d5af32010-05-11 12:30:09 -0700200}
201
Carl Worth33cc4002010-05-12 12:17:10 -0700202void
203_print_resolved_token (glcpp_parser_t *parser, const char *token)
204{
205 int first = 1;
206
207 _print_resolved_recursive (parser, token, token, &first);
208}