Mercurial > projects > qtd
comparison generator/typeparser.cpp @ 1:e78566595089
initial import
author | mandel |
---|---|
date | Mon, 11 May 2009 16:01:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:36fb74dc547d | 1:e78566595089 |
---|---|
1 /**************************************************************************** | |
2 ** | |
3 ** Copyright (C) 1992-2008 Nokia. All rights reserved. | |
4 ** | |
5 ** This file is part of Qt Jambi. | |
6 ** | |
7 ** * Commercial Usage | |
8 * Licensees holding valid Qt Commercial licenses may use this file in | |
9 * accordance with the Qt Commercial License Agreement provided with the | |
10 * Software or, alternatively, in accordance with the terms contained in | |
11 * a written agreement between you and Nokia. | |
12 * | |
13 * | |
14 * GNU General Public License Usage | |
15 * Alternatively, this file may be used under the terms of the GNU | |
16 * General Public License versions 2.0 or 3.0 as published by the Free | |
17 * Software Foundation and appearing in the file LICENSE.GPL included in | |
18 * the packaging of this file. Please review the following information | |
19 * to ensure GNU General Public Licensing requirements will be met: | |
20 * http://www.fsf.org/licensing/licenses/info/GPLv2.html and | |
21 * http://www.gnu.org/copyleft/gpl.html. In addition, as a special | |
22 * exception, Nokia gives you certain additional rights. These rights | |
23 * are described in the Nokia Qt GPL Exception version 1.2, included in | |
24 * the file GPL_EXCEPTION.txt in this package. | |
25 * | |
26 * Qt for Windows(R) Licensees | |
27 * As a special exception, Nokia, as the sole copyright holder for Qt | |
28 * Designer, grants users of the Qt/Eclipse Integration plug-in the | |
29 * right for the Qt/Eclipse Integration to link to functionality | |
30 * provided by Qt Designer and its related libraries. | |
31 * | |
32 * | |
33 * If you are unsure which license is appropriate for your use, please | |
34 * contact the sales department at qt-sales@nokia.com. | |
35 | |
36 ** | |
37 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | |
38 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
39 ** | |
40 ****************************************************************************/ | |
41 | |
42 #include "typeparser.h" | |
43 | |
44 #include <qdebug.h> | |
45 #include <QStack> | |
46 | |
47 class Scanner | |
48 { | |
49 public: | |
50 enum Token { | |
51 StarToken, | |
52 AmpersandToken, | |
53 LessThanToken, | |
54 ColonToken, | |
55 CommaToken, | |
56 OpenParenToken, | |
57 CloseParenToken, | |
58 SquareBegin, | |
59 SquareEnd, | |
60 GreaterThanToken, | |
61 | |
62 ConstToken, | |
63 Identifier, | |
64 NoToken | |
65 }; | |
66 | |
67 Scanner(const QString &s) | |
68 : m_pos(0), m_length(s.length()), m_chars(s.constData()) | |
69 { | |
70 } | |
71 | |
72 Token nextToken(); | |
73 QString identifier() const; | |
74 | |
75 private: | |
76 int m_pos; | |
77 int m_length; | |
78 int m_token_start; | |
79 const QChar *m_chars; | |
80 }; | |
81 | |
82 QString Scanner::identifier() const | |
83 { | |
84 return QString(m_chars + m_token_start, m_pos - m_token_start); | |
85 } | |
86 | |
87 Scanner::Token Scanner::nextToken() | |
88 { | |
89 Token tok = NoToken; | |
90 | |
91 // remove whitespace | |
92 while (m_pos < m_length && m_chars[m_pos] == ' ') { | |
93 ++m_pos; | |
94 } | |
95 | |
96 m_token_start = m_pos; | |
97 | |
98 while (m_pos < m_length) { | |
99 | |
100 const QChar &c = m_chars[m_pos]; | |
101 | |
102 if (tok == NoToken) { | |
103 switch (c.toLatin1()) { | |
104 case '*': tok = StarToken; break; | |
105 case '&': tok = AmpersandToken; break; | |
106 case '<': tok = LessThanToken; break; | |
107 case '>': tok = GreaterThanToken; break; | |
108 case ',': tok = CommaToken; break; | |
109 case '(': tok = OpenParenToken; break; | |
110 case ')': tok = CloseParenToken; break; | |
111 case '[': tok = SquareBegin; break; | |
112 case ']' : tok = SquareEnd; break; | |
113 case ':': | |
114 tok = ColonToken; | |
115 Q_ASSERT(m_pos + 1 < m_length); | |
116 ++m_pos; | |
117 break; | |
118 default: | |
119 if (c.isLetterOrNumber() || c == '_') | |
120 tok = Identifier; | |
121 else | |
122 qFatal("Unrecognized character in lexer: %c", c.toLatin1()); | |
123 break; | |
124 } | |
125 } | |
126 | |
127 if (tok <= GreaterThanToken) { | |
128 ++m_pos; | |
129 break; | |
130 } | |
131 | |
132 if (tok == Identifier) { | |
133 if (c.isLetterOrNumber() || c == '_') | |
134 ++m_pos; | |
135 else | |
136 break; | |
137 } | |
138 } | |
139 | |
140 if (tok == Identifier && m_pos - m_token_start == 5) { | |
141 if (m_chars[m_token_start] == 'c' | |
142 && m_chars[m_token_start + 1] == 'o' | |
143 && m_chars[m_token_start + 2] == 'n' | |
144 && m_chars[m_token_start + 3] == 's' | |
145 && m_chars[m_token_start + 4] == 't') | |
146 tok = ConstToken; | |
147 } | |
148 | |
149 return tok; | |
150 | |
151 } | |
152 | |
153 TypeParser::Info TypeParser::parse(const QString &str) | |
154 { | |
155 Scanner scanner(str); | |
156 | |
157 Info info; | |
158 QStack<Info *> stack; | |
159 stack.push(&info); | |
160 | |
161 bool colon_prefix = false; | |
162 bool in_array = false; | |
163 QString array; | |
164 | |
165 Scanner::Token tok = scanner.nextToken(); | |
166 while (tok != Scanner::NoToken) { | |
167 | |
168 // switch (tok) { | |
169 // case Scanner::StarToken: printf(" - *\n"); break; | |
170 // case Scanner::AmpersandToken: printf(" - &\n"); break; | |
171 // case Scanner::LessThanToken: printf(" - <\n"); break; | |
172 // case Scanner::GreaterThanToken: printf(" - >\n"); break; | |
173 // case Scanner::ColonToken: printf(" - ::\n"); break; | |
174 // case Scanner::CommaToken: printf(" - ,\n"); break; | |
175 // case Scanner::ConstToken: printf(" - const\n"); break; | |
176 // case Scanner::SquareBegin: printf(" - [\n"); break; | |
177 // case Scanner::SquareEnd: printf(" - ]\n"); break; | |
178 // case Scanner::Identifier: printf(" - '%s'\n", qPrintable(scanner.identifier())); break; | |
179 // default: | |
180 // break; | |
181 // } | |
182 | |
183 switch (tok) { | |
184 | |
185 case Scanner::StarToken: | |
186 ++stack.top()->indirections; | |
187 break; | |
188 | |
189 case Scanner::AmpersandToken: | |
190 stack.top()->is_reference = true; | |
191 break; | |
192 | |
193 case Scanner::LessThanToken: | |
194 stack.top()->template_instantiations << Info(); | |
195 stack.push(&stack.top()->template_instantiations.last()); | |
196 break; | |
197 | |
198 case Scanner::CommaToken: | |
199 stack.pop(); | |
200 stack.top()->template_instantiations << Info(); | |
201 stack.push(&stack.top()->template_instantiations.last()); | |
202 break; | |
203 | |
204 case Scanner::GreaterThanToken: | |
205 stack.pop(); | |
206 break; | |
207 | |
208 case Scanner::ColonToken: | |
209 colon_prefix = true; | |
210 break; | |
211 | |
212 case Scanner::ConstToken: | |
213 stack.top()->is_constant = true; | |
214 break; | |
215 | |
216 case Scanner::OpenParenToken: // function pointers not supported | |
217 case Scanner::CloseParenToken: | |
218 { | |
219 Info i; | |
220 i.is_busted = true; | |
221 return i; | |
222 } | |
223 | |
224 | |
225 case Scanner::Identifier: | |
226 if (in_array) { | |
227 array = scanner.identifier(); | |
228 } else if (colon_prefix || stack.top()->qualified_name.isEmpty()) { | |
229 stack.top()->qualified_name << scanner.identifier(); | |
230 colon_prefix = false; | |
231 } else { | |
232 stack.top()->qualified_name.last().append(" " + scanner.identifier()); | |
233 } | |
234 break; | |
235 | |
236 case Scanner::SquareBegin: | |
237 in_array = true; | |
238 break; | |
239 | |
240 case Scanner::SquareEnd: | |
241 in_array = false; | |
242 stack.top()->arrays += array; | |
243 break; | |
244 | |
245 | |
246 default: | |
247 break; | |
248 } | |
249 | |
250 tok = scanner.nextToken(); | |
251 } | |
252 | |
253 return info; | |
254 } | |
255 | |
256 QString TypeParser::Info::instantiationName() const | |
257 { | |
258 QString s(qualified_name.join("::")); | |
259 if (!template_instantiations.isEmpty()) { | |
260 s += '<'; | |
261 for (int i=0; i<template_instantiations.size(); ++i) { | |
262 if (i != 0) | |
263 s += ","; | |
264 s += template_instantiations.at(i).toString(); | |
265 } | |
266 s += '>'; | |
267 } | |
268 | |
269 return s; | |
270 } | |
271 | |
272 QString TypeParser::Info::toString() const | |
273 { | |
274 QString s; | |
275 | |
276 if (is_constant) s += "const "; | |
277 s += instantiationName(); | |
278 for (int i=0; i<arrays.size(); ++i) | |
279 s += "[" + arrays.at(i) + "]"; | |
280 s += QString(indirections, '*'); | |
281 if (is_reference) s += '&'; | |
282 | |
283 return s; | |
284 } |