Line data Source code
1 : /*
2 : * This file is part of the LibreOffice project.
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * This file incorporates work covered by the following license notice:
9 : *
10 : * Licensed to the Apache Software Foundation (ASF) under one or more
11 : * contributor license agreements. See the NOTICE file distributed
12 : * with this work for additional information regarding copyright
13 : * ownership. The ASF licenses this file to you under the Apache
14 : * License, Version 2.0 (the "License"); you may not use this file
15 : * except in compliance with the License. You may obtain a copy of
16 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
17 : */
18 :
19 : %option yylineno
20 :
21 : %{
22 : /*
23 : * scanner.ll - Lexical scanner for IDLC 1.0
24 : */
25 :
26 : #include "sal/config.h"
27 :
28 : #include <ctype.h>
29 : #include <stdlib.h>
30 : #include <string.h>
31 :
32 : #include <idlc/idlc.hxx>
33 : #include <idlc/errorhandler.hxx>
34 : #include <idlc/fehelper.hxx>
35 :
36 : #include "attributeexceptions.hxx"
37 :
38 :
39 : class AstExpression;
40 : class AstMember;
41 :
42 : #include <parser.hxx>
43 :
44 : /* handle locations */
45 : int yycolumn = 1;
46 :
47 : #define YY_USER_ACTION idlc()->setOffset(yycolumn, yycolumn+yyleng-1); \
48 : yycolumn += yyleng;
49 :
50 : sal_Int32 beginLine = 0;
51 329 : ::rtl::OString docu;
52 :
53 117 : static int asciiToInteger(char const * s, sal_Int64 * sval, sal_uInt64 * uval) {
54 117 : bool neg = false;
55 117 : if (*s == '-') {
56 33 : neg = true;
57 33 : ++s;
58 : }
59 117 : unsigned int base = 10;
60 117 : if (*s == '0') {
61 72 : base = 8;
62 72 : ++s;
63 72 : if (*s == 'X' || *s == 'x') {
64 29 : base = 16;
65 29 : ++s;
66 : }
67 : }
68 117 : sal_uInt64 val = 0;
69 795 : for (; *s != 0; ++s) {
70 : unsigned int n;
71 681 : if (*s >= '0' && *s <= '9') {
72 625 : n = *s - '0';
73 : } else {
74 56 : switch (*s) {
75 : case 'A':
76 : case 'a':
77 0 : n = 10;
78 0 : break;
79 : case 'B':
80 : case 'b':
81 0 : n = 11;
82 0 : break;
83 : case 'C':
84 : case 'c':
85 0 : n = 12;
86 0 : break;
87 : case 'D':
88 : case 'd':
89 0 : n = 13;
90 0 : break;
91 : case 'E':
92 : case 'e':
93 0 : n = 14;
94 0 : break;
95 : case 'F':
96 : case 'f':
97 56 : n = 15;
98 56 : break;
99 : default:
100 0 : goto done;
101 : }
102 : }
103 : // The following guarantees the invariant val <= SAL_MAX_UINT64 (because
104 : // base and n are sufficiently small), *if*
105 : // std::numeric_limits<sal_uInt64>::max() == SAL_MAX_UINT64:
106 681 : sal_uInt64 nval = val * base + n;
107 681 : if (nval < val) {
108 : ErrorHandler::syntaxError(
109 3 : PS_NoState, idlc()->getLineNumber(),
110 3 : "integral constant too large");
111 3 : val = 0;
112 3 : break;
113 : }
114 678 : val = nval;
115 : }
116 : done:
117 117 : if (neg) {
118 33 : if (val < SAL_CONST_UINT64(0x8000000000000000)) {
119 27 : *sval = -static_cast< sal_Int64 >(val);
120 6 : } else if (val == SAL_CONST_UINT64(0x8000000000000000)) {
121 3 : *sval = SAL_MIN_INT64;
122 : } else {
123 : ErrorHandler::syntaxError(
124 3 : PS_NoState, idlc()->getLineNumber(),
125 3 : "negative integral constant too large");
126 3 : *sval = 0;
127 : }
128 33 : return IDL_INTEGER_LITERAL;
129 84 : } else if (val <= static_cast< sal_uInt64 >(SAL_MAX_INT64)) {
130 78 : *sval = static_cast< sal_Int64 >(val);
131 78 : return IDL_INTEGER_LITERAL;
132 : } else {
133 6 : *uval = val;
134 6 : return IDL_INTEGER_ULITERAL;
135 : }
136 : }
137 :
138 4 : static double asciiToFloat(const sal_Char *s)
139 : {
140 4 : double d = 0.0;
141 : double e, k;
142 4 : sal_Int32 neg = 0;
143 :
144 4 : if (*s == '-')
145 : {
146 0 : neg = 1;
147 0 : s++;
148 : }
149 12 : while (*s >= '0' && *s <= '9')
150 : {
151 4 : d = (d * 10) + *s - '0';
152 4 : s++;
153 : }
154 4 : if (*s == '.')
155 : {
156 4 : s++;
157 4 : e = 10;
158 12 : while (*s >= '0' && *s <= '9')
159 : {
160 4 : d += (*s - '0') / (e * 1.0);
161 4 : e *= 10;
162 4 : s++;
163 : }
164 : }
165 4 : if (*s == 'e' || *s == 'E')
166 : {
167 0 : s++;
168 0 : if (*s == '-')
169 : {
170 0 : s++;
171 : } else
172 : {
173 0 : if (*s == '+')
174 0 : s++;
175 0 : e = 0;
176 0 : while (*s >= '0' && *s <= '9')
177 : {
178 0 : e = (e * 10) + *s - '0';
179 0 : s++;
180 : }
181 0 : if (e > 0)
182 : {
183 0 : for (k = 1; e > 0; k *= 10, e--)
184 : ;
185 0 : d /= k;
186 : }
187 : }
188 : }
189 4 : if (neg) d *= -1.0;
190 4 : return d;
191 : }
192 :
193 0 : static void idlParsePragma(sal_Char* pPragma)
194 : {
195 0 : ::rtl::OString pragma(pPragma);
196 0 : sal_Int32 index = pragma.indexOf("include");
197 0 : sal_Char* begin = pPragma + index + 8;
198 0 : sal_Char* offset = begin;
199 0 : while (*offset != ',') offset++;
200 : //::rtl::OString include = pragma.copy(index + 8, offset - begin);
201 : //unused// idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin)));
202 0 : }
203 :
204 329 : static void parseLineAndFile(sal_Char* pBuf)
205 : {
206 329 : sal_Char *r = pBuf;
207 : sal_Char *h;
208 329 : bool bIsInMain = false;
209 :
210 : /* Skip initial '#' */
211 329 : if (*r != '#')
212 0 : return;
213 :
214 : /* Find line number */
215 329 : for (r++; *r == ' ' || *r == '\t' || isalpha(*r); r++) ;
216 329 : h = r;
217 329 : for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ;
218 329 : *r++ = 0;
219 329 : idlc()->setLineNumber((sal_uInt32)atol(h));
220 329 : yylineno = atol(h);
221 :
222 : /* Find file name, if present */
223 329 : for (; *r != '"'; r++)
224 : {
225 0 : if (*r == '\n' || *r == '\0')
226 0 : return;
227 : }
228 329 : h = ++r;
229 329 : for (; *r != '"'; r++) ;
230 329 : *r = 0;
231 329 : if (*h == '\0')
232 0 : idlc()->setFileName(::rtl::OString("standard input"));
233 : else
234 329 : idlc()->setFileName(::rtl::OString(h));
235 :
236 329 : bIsInMain = idlc()->getFileName() == idlc()->getRealFileName();
237 329 : idlc()->setInMainfile(bIsInMain);
238 : }
239 :
240 : // Suppress any warnings from generated code:
241 : #ifdef __GNUC__
242 : #pragma GCC diagnostic ignored "-Wunused-function"
243 : #pragma GCC diagnostic ignored "-Wunused-label"
244 : #elif defined _MSC_VER
245 : #pragma warning(push, 1)
246 : /**/
247 : #ifdef yywrap
248 : #undef yywrap
249 : #define yywrap() 1
250 : #endif
251 : /**/
252 : #endif
253 : #define YY_NO_UNISTD_H
254 : %}
255 :
256 : %option noyywrap
257 : %option never-interactive
258 :
259 : %x DOCU
260 : %x COMMENT
261 :
262 : DIGIT [0-9]
263 : OCT_DIGIT [0-7]
264 : HEX_DIGIT [a-fA-F0-9]
265 : CAPITAL [A-Z]
266 : ALPHA [a-zA-Z]
267 : INT_LITERAL [1-9][0-9]*
268 : OCT_LITERAL 0{OCT_DIGIT}*
269 : HEX_LITERAL (0x|0X){HEX_DIGIT}*
270 :
271 : IDENTIFIER_NEW ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*)
272 : IDENTIFIER ("_"?({ALPHA}|{DIGIT})+)*
273 :
274 : %%
275 :
276 : [ \t\r]+ ; /* eat up whitespace */
277 3968 : [\n] {
278 2071 : idlc()->incLineNumber();
279 2071 : yycolumn = 1;
280 4142 : yylineno++;
281 : }
282 2071 :
283 46 : attribute return IDL_ATTRIBUTE;
284 50 : bound return IDL_BOUND;
285 127 : const return IDL_CONST;
286 70 : constants return IDL_CONSTANTS;
287 128 : constrained return IDL_CONSTRAINED;
288 107 : enum return IDL_ENUM;
289 41 : exception return IDL_EXCEPTION;
290 381 : interface return IDL_INTERFACE;
291 40 : maybeambiguous return IDL_MAYBEAMBIGUOUS;
292 341 : maybedefault return IDL_MAYBEDEFAULT;
293 1 : maybevoid return IDL_MAYBEVOID;
294 117 : module return IDL_MODULE;
295 1 : needs return IDL_NEEDS;
296 116 : observes return IDL_OBSERVES;
297 50 : optional return IDL_OPTIONAL;
298 6 : property return IDL_PROPERTY;
299 79 : raises return IDL_RAISES;
300 10 : readonly return IDL_READONLY;
301 30 : removable return IDL_REMOVABLE;
302 81 : service return IDL_SERVICE;
303 22 : sequence return IDL_SEQUENCE;
304 90 : singleton return IDL_SINGLETON;
305 151 : struct return IDL_STRUCT;
306 14 : transient return IDL_TRANSIENT;
307 169 : typedef return IDL_TYPEDEF;
308 1 :
309 51 : any return IDL_ANY;
310 14 : boolean return IDL_BOOLEAN;
311 17 : byte return IDL_BYTE;
312 5 : char return IDL_CHAR;
313 19 : double return IDL_DOUBLE;
314 5 : float return IDL_FLOAT;
315 30 : hyper return IDL_HYPER;
316 172 : long return IDL_LONG;
317 63 : short return IDL_SHORT;
318 173 : string return IDL_STRING;
319 35 : type return IDL_TYPE;
320 49 : unsigned return IDL_UNSIGNED;
321 45 : void return IDL_VOID;
322 46 :
323 45 : TRUE return IDL_TRUE;
324 0 : True return IDL_TRUE;
325 2 : FALSE return IDL_FALSE;
326 0 : False return IDL_FALSE;
327 2 :
328 39 : in return IDL_IN;
329 42 : out return IDL_OUT;
330 0 : inout return IDL_INOUT;
331 3 :
332 15 : get return IDL_GET;
333 21 : set return IDL_SET;
334 :
335 144 : published return IDL_PUBLISHED;
336 138 :
337 12 : "..." return IDL_ELLIPSIS;
338 12 :
339 : ("-")?{INT_LITERAL}+(l|L|u|U)? {
340 45 : return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
341 : }
342 :
343 : ("-")?{OCT_LITERAL}+(l|L|u|U)? {
344 43 : return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
345 : }
346 :
347 : ("-")?{HEX_LITERAL}+(l|L|u|U)? {
348 29 : return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
349 : }
350 :
351 : ("-")?{DIGIT}+(e|E)(("+"|"-")?{DIGIT}+)?(f|F)? |
352 : ("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? {
353 4 : yylval.dval = asciiToFloat( yytext );
354 4 : return IDL_FLOATING_PT_LITERAL;
355 : }
356 :
357 : {IDENTIFIER} {
358 1748 : yylval.sval = new ::rtl::OString(yytext);
359 1748 : return IDL_IDENTIFIER;
360 : }
361 :
362 : \<\< {
363 0 : yylval.strval = yytext;
364 0 : return IDL_LEFTSHIFT;
365 : }
366 : \>\> {
367 0 : yylval.strval = yytext;
368 0 : return IDL_RIGHTSHIFT;
369 : }
370 : \:\: {
371 47 : yylval.strval = yytext;
372 94 : return IDL_SCOPESEPARATOR;
373 : }
374 :
375 : "/*" {
376 0 : BEGIN( COMMENT );
377 0 : docu = ::rtl::OString();
378 0 : beginLine = idlc()->getLineNumber();
379 : }
380 0 :
381 : "/***" {
382 0 : BEGIN( COMMENT );
383 0 : docu = ::rtl::OString();
384 0 : beginLine = idlc()->getLineNumber();
385 : }
386 0 :
387 : <COMMENT>[^*]+ {
388 0 : docu += ::rtl::OString(yytext);
389 0 : }
390 0 :
391 : <COMMENT>"*"[^*/]+ {
392 0 : docu += ::rtl::OString(yytext);
393 0 : }
394 0 :
395 : <COMMENT>"**" {
396 0 : docu += ::rtl::OString(yytext);
397 : }
398 0 :
399 : <COMMENT>[*]+"/" {
400 0 : docu = docu.trim();
401 0 : sal_Int32 nIndex = 0;
402 0 : int count = 0;
403 0 : do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
404 0 : idlc()->setLineNumber( beginLine + count - 1);
405 0 : BEGIN( INITIAL );
406 : }
407 0 :
408 : "/**" {
409 0 : BEGIN( DOCU );
410 0 : docu = ::rtl::OString();
411 0 : beginLine = idlc()->getLineNumber();
412 : }
413 0 :
414 : <DOCU>[^*\n]+ {
415 0 : docu += ::rtl::OString(yytext);
416 : }
417 0 :
418 : <DOCU>"\n"[ \t]*"*"{1} {
419 0 : idlc()->setLineNumber( idlc()->getLineNumber() + 1);
420 0 : docu += ::rtl::OString("\n");
421 : }
422 0 :
423 : <DOCU>"\n" {
424 0 : idlc()->setLineNumber( idlc()->getLineNumber() + 1);
425 0 : docu += ::rtl::OString(yytext);
426 : }
427 0 :
428 : <DOCU>"*"[^*^/\n]* {
429 0 : docu += ::rtl::OString(yytext);
430 : }
431 0 :
432 : <DOCU>"\n"[ \t]*"*/" {
433 0 : docu = docu.trim();
434 0 : sal_Int32 nIndex = 0;
435 0 : int count = 0;
436 0 : do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
437 0 : idlc()->setLineNumber( beginLine + count - 1);
438 0 : if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 )
439 : {
440 0 : if ( 0 != nIndex &&
441 0 : (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
442 0 : ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
443 0 : "nested documentation strings are not allowed!");
444 : }
445 0 : idlc()->setDocumentation(docu);
446 0 : BEGIN( INITIAL );
447 : }
448 0 :
449 : <DOCU>"*/" {
450 0 : docu = docu.trim();
451 0 : sal_Int32 nIndex = 0;
452 0 : int count = 0;
453 0 : do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
454 0 : idlc()->setLineNumber( beginLine + count - 1);
455 0 : if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 )
456 : {
457 0 : if ( 0 != nIndex &&
458 0 : (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
459 0 : ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
460 0 : "nested documentation strings are not allowed!");
461 : }
462 0 : idlc()->setDocumentation(docu);
463 0 : BEGIN( INITIAL );
464 : }
465 0 :
466 : "//"[^/]{1}.*"\n" {
467 : /* only a comment */
468 0 : ::rtl::OString docStr(yytext);
469 0 : docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
470 0 : docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
471 0 : docStr = docStr.trim();
472 0 : idlc()->incLineNumber();
473 : }
474 0 :
475 : "///".*"\n" {
476 0 : ::rtl::OString docStr(yytext);
477 0 : docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
478 0 : docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
479 0 : docStr = docStr.trim();
480 0 : idlc()->incLineNumber();
481 0 : idlc()->setDocumentation(docStr);
482 : }
483 0 :
484 3752 : . return yytext[0];
485 3752 :
486 : ^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
487 329 : parseLineAndFile(yytext);
488 329 : }
489 329 :
490 : ^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n {
491 0 : parseLineAndFile(yytext);
492 0 : }
493 0 :
494 : ^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
495 0 : parseLineAndFile(yytext);
496 0 : }
497 0 :
498 : ^#[ \t]*[0-9]*\n {
499 0 : parseLineAndFile(yytext);
500 0 : }
501 0 :
502 : ^#[ \t]*ident.*\n {
503 : /* ignore cpp ident */
504 0 : idlc()->incLineNumber();
505 : }
506 0 :
507 : ^#[ \t]*pragma[ \t].*\n { /* remember pragma */
508 0 : idlParsePragma(yytext);
509 0 : idlc()->incLineNumber();
510 : }
511 0 :
512 0 : %%
|