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 AstArray;
41 : class AstMember;
42 :
43 : #include <parser.hxx>
44 :
45 : /* handle locations */
46 : int yycolumn = 1;
47 :
48 : #define YY_USER_ACTION idlc()->setOffset(yycolumn, yycolumn+yyleng-1); \
49 : yycolumn += yyleng;
50 :
51 : sal_Int32 beginLine = 0;
52 452 : ::rtl::OString docu;
53 :
54 14329 : static int asciiToInteger(char const * s, sal_Int64 * sval, sal_uInt64 * uval) {
55 14329 : bool neg = false;
56 14329 : if (*s == '-') {
57 637 : neg = true;
58 637 : ++s;
59 : }
60 14329 : unsigned int base = 10;
61 14329 : if (*s == '0') {
62 1584 : base = 8;
63 1584 : ++s;
64 1584 : if (*s == 'X' || *s == 'x') {
65 572 : base = 16;
66 572 : ++s;
67 : }
68 : }
69 14329 : sal_uInt64 val = 0;
70 43896 : for (; *s != 0; ++s) {
71 : unsigned int n;
72 29570 : if (*s >= '0' && *s <= '9') {
73 29417 : n = *s - '0';
74 : } else {
75 153 : switch (*s) {
76 : case 'A':
77 : case 'a':
78 4 : n = 10;
79 4 : break;
80 : case 'B':
81 : case 'b':
82 9 : n = 11;
83 9 : break;
84 : case 'C':
85 : case 'c':
86 4 : n = 12;
87 4 : break;
88 : case 'D':
89 : case 'd':
90 4 : n = 13;
91 4 : break;
92 : case 'E':
93 : case 'e':
94 4 : n = 14;
95 4 : break;
96 : case 'F':
97 : case 'f':
98 128 : n = 15;
99 128 : break;
100 : default:
101 0 : goto done;
102 : }
103 : }
104 : // The following guarantees the invariant val <= SAL_MAX_UINT64 (because
105 : // base and n are sufficiently small), *if*
106 : // std::numeric_limits<sal_uInt64>::max() == SAL_MAX_UINT64:
107 29570 : sal_uInt64 nval = val * base + n;
108 29570 : if (nval < val) {
109 : idlc()->error()->syntaxError(
110 3 : PS_NoState, idlc()->getLineNumber(),
111 3 : "integral constant too large");
112 3 : val = 0;
113 3 : break;
114 : }
115 29567 : val = nval;
116 : }
117 : done:
118 14329 : if (neg) {
119 637 : if (val < SAL_CONST_UINT64(0x8000000000000000)) {
120 630 : *sval = -static_cast< sal_Int64 >(val);
121 7 : } else if (val == SAL_CONST_UINT64(0x8000000000000000)) {
122 4 : *sval = SAL_MIN_INT64;
123 : } else {
124 : idlc()->error()->syntaxError(
125 3 : PS_NoState, idlc()->getLineNumber(),
126 3 : "negative integral constant too large");
127 3 : *sval = 0;
128 : }
129 637 : return IDL_INTEGER_LITERAL;
130 13692 : } else if (val <= static_cast< sal_uInt64 >(SAL_MAX_INT64)) {
131 13685 : *sval = static_cast< sal_Int64 >(val);
132 13685 : return IDL_INTEGER_LITERAL;
133 : } else {
134 7 : *uval = val;
135 7 : return IDL_INTEGER_ULITERAL;
136 : }
137 : }
138 :
139 24 : static double asciiToFloat(const sal_Char *s)
140 : {
141 24 : double d = 0.0;
142 : double e, k;
143 24 : sal_Int32 neg = 0, negexp = 0;
144 :
145 24 : if (*s == '-')
146 : {
147 0 : neg = 1;
148 0 : s++;
149 : }
150 100 : while (*s >= '0' && *s <= '9')
151 : {
152 52 : d = (d * 10) + *s - '0';
153 52 : s++;
154 : }
155 24 : if (*s == '.')
156 : {
157 24 : s++;
158 24 : e = 10;
159 172 : while (*s >= '0' && *s <= '9')
160 : {
161 124 : d += (*s - '0') / (e * 1.0);
162 124 : e *= 10;
163 124 : s++;
164 : }
165 : }
166 24 : if (*s == 'e' || *s == 'E')
167 : {
168 0 : s++;
169 0 : if (*s == '-')
170 : {
171 0 : negexp = 1;
172 0 : s++;
173 : } else
174 : {
175 0 : if (*s == '+')
176 0 : s++;
177 0 : e = 0;
178 0 : while (*s >= '0' && *s <= '9')
179 : {
180 0 : e = (e * 10) + *s - '0';
181 0 : s++;
182 : }
183 0 : if (e > 0)
184 : {
185 0 : for (k = 1; e > 0; k *= 10, e--)
186 : ;
187 0 : if (negexp)
188 0 : d /= k;
189 : else
190 0 : d *= k;
191 : }
192 : }
193 : }
194 24 : if (neg) d *= -1.0;
195 24 : return d;
196 : }
197 :
198 0 : static void idlParsePragma(sal_Char* pPragma)
199 : {
200 0 : ::rtl::OString pragma(pPragma);
201 0 : sal_Int32 index = pragma.indexOf("include");
202 0 : sal_Char* begin = pPragma + index + 8;
203 0 : sal_Char* offset = begin;
204 0 : while (*offset != ',') offset++;
205 : //::rtl::OString include = pragma.copy(index + 8, offset - begin);
206 : //unused// idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin)));
207 0 : }
208 :
209 120672 : static void parseLineAndFile(sal_Char* pBuf)
210 : {
211 120672 : sal_Char *r = pBuf;
212 : sal_Char *h;
213 120672 : sal_Bool bIsInMain = sal_False;
214 :
215 : /* Skip initial '#' */
216 120672 : if (*r != '#')
217 0 : return;
218 :
219 : /* Find line number */
220 120672 : for (r++; *r == ' ' || *r == '\t' || isalpha(*r); r++) ;
221 120672 : h = r;
222 120672 : for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ;
223 120672 : *r++ = 0;
224 120672 : idlc()->setLineNumber((sal_uInt32)atol(h));
225 120672 : yylineno = atol(h);
226 :
227 : /* Find file name, if present */
228 120672 : for (; *r != '"'; r++)
229 : {
230 0 : if (*r == '\n' || *r == '\0')
231 0 : return;
232 : }
233 120672 : h = ++r;
234 120672 : for (; *r != '"'; r++) ;
235 120672 : *r = 0;
236 120672 : if (*h == '\0')
237 0 : idlc()->setFileName(::rtl::OString("standard input"));
238 : else
239 120672 : idlc()->setFileName(::rtl::OString(h));
240 :
241 120672 : bIsInMain = (idlc()->getFileName() == idlc()->getRealFileName()) ? sal_True : sal_False;
242 120672 : idlc()->setInMainfile(bIsInMain);
243 : }
244 :
245 : // Suppress any warnings from generated code:
246 : #if HAVE_GCC_PRAGMA_DIAGNOSTIC_MODIFY
247 : #pragma GCC diagnostic ignored "-Wunused-function"
248 : #pragma GCC diagnostic ignored "-Wunused-label"
249 : #elif defined __SUNPRO_CC
250 : #pragma disable_warn
251 : #elif defined _MSC_VER
252 : #pragma warning(push, 1)
253 : /**/
254 : #ifdef yywrap
255 : #undef yywrap
256 : #define yywrap() 1
257 : #endif
258 : /**/
259 : #endif
260 : #define YY_NO_UNISTD_H
261 : %}
262 :
263 : %option noyywrap
264 : %option never-interactive
265 :
266 : %x DOCU
267 : %x COMMENT
268 :
269 : DIGIT [0-9]
270 : OCT_DIGIT [0-7]
271 : HEX_DIGIT [a-fA-F0-9]
272 : CAPITAL [A-Z]
273 : ALPHA [a-zA-Z]
274 : INT_LITERAL [1-9][0-9]*
275 : OCT_LITERAL 0{OCT_DIGIT}*
276 : HEX_LITERAL (0x|0X){HEX_DIGIT}*
277 :
278 : IDENTIFIER_NEW ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*)
279 : IDENTIFIER ("_"?({ALPHA}|{DIGIT})+)*
280 :
281 : %%
282 :
283 : [ \t\r]+ ; /* eat up whitespace */
284 2360502 : [\n] {
285 2285787 : idlc()->incLineNumber();
286 2285787 : yycolumn = 1;
287 4571574 : yylineno++;
288 : }
289 2285787 :
290 4918 : attribute return IDL_ATTRIBUTE;
291 6466 : bound return IDL_BOUND;
292 0 : case return IDL_CASE;
293 15470 : const return IDL_CONST;
294 1553 : constants return IDL_CONSTANTS;
295 13923 : constrained return IDL_CONSTRAINED;
296 1553 : default return IDL_DEFAULT;
297 4799 : enum return IDL_ENUM;
298 13594 : exception return IDL_EXCEPTION;
299 49110 : interface return IDL_INTERFACE;
300 13594 : maybeambiguous return IDL_MAYBEAMBIGUOUS;
301 44316 : maybedefault return IDL_MAYBEDEFAULT;
302 392 : maybevoid return IDL_MAYBEVOID;
303 253310 : module return IDL_MODULE;
304 392 : needs return IDL_NEEDS;
305 253306 : observes return IDL_OBSERVES;
306 10154 : optional return IDL_OPTIONAL;
307 17588 : property return IDL_PROPERTY;
308 35893 : raises return IDL_RAISES;
309 19588 : readonly return IDL_READONLY;
310 25740 : removable return IDL_REMOVABLE;
311 6976 : service return IDL_SERVICE;
312 18644 : sequence return IDL_SEQUENCE;
313 5154 : singleton return IDL_SINGLETON;
314 30702 : struct return IDL_STRUCT;
315 178 : switch return IDL_SWITCH;
316 12080 : transient return IDL_TRANSIENT;
317 767 : typedef return IDL_TYPEDEF;
318 21 : union return IDL_UNION;
319 767 :
320 17666 : any return IDL_ANY;
321 37113 : boolean return IDL_BOOLEAN;
322 2570 : byte return IDL_BYTE;
323 20392 : char return IDL_CHAR;
324 5263 : double return IDL_DOUBLE;
325 2372 : float return IDL_FLOAT;
326 3001 : hyper return IDL_HYPER;
327 46807 : long return IDL_LONG;
328 22011 : short return IDL_SHORT;
329 88184 : string return IDL_STRING;
330 27333 : type return IDL_TYPE;
331 50886 : unsigned return IDL_UNSIGNED;
332 51340 : void return IDL_VOID;
333 8082 :
334 45710 : TRUE return IDL_TRUE;
335 0 : True return IDL_TRUE;
336 2 : FALSE return IDL_FALSE;
337 0 : False return IDL_FALSE;
338 2 :
339 83559 : in return IDL_IN;
340 85923 : out return IDL_OUT;
341 97 : inout return IDL_INOUT;
342 2364 :
343 1302 : get return IDL_GET;
344 2590 : set return IDL_SET;
345 :
346 65360 : published return IDL_PUBLISHED;
347 63975 :
348 14 : "..." return IDL_ELLIPSIS;
349 14 :
350 : ("-")?{INT_LITERAL}+(l|L|u|U)? {
351 12745 : return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
352 : }
353 :
354 : ("-")?{OCT_LITERAL}+(l|L|u|U)? {
355 1012 : return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
356 : }
357 :
358 : ("-")?{HEX_LITERAL}+(l|L|u|U)? {
359 572 : return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
360 : }
361 :
362 : ("-")?{DIGIT}+(e|E){1}(("+"|"-")?{DIGIT}+)+(f|F)? |
363 : ("-")?"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? |
364 : ("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? {
365 24 : yylval.dval = asciiToFloat( yytext );
366 24 : return IDL_FLOATING_PT_LITERAL;
367 : }
368 :
369 : {IDENTIFIER} {
370 1382168 : yylval.sval = new ::rtl::OString(yytext);
371 1382168 : return IDL_IDENTIFIER;
372 : }
373 :
374 : \<\< {
375 0 : yylval.strval = yytext;
376 0 : return IDL_LEFTSHIFT;
377 : }
378 : \>\> {
379 0 : yylval.strval = yytext;
380 0 : return IDL_RIGHTSHIFT;
381 : }
382 : \:\: {
383 542792 : yylval.strval = yytext;
384 1085584 : return IDL_SCOPESEPARATOR;
385 : }
386 :
387 : "/*" {
388 186901 : BEGIN( COMMENT );
389 186901 : docu = ::rtl::OString();
390 186901 : beginLine = idlc()->getLineNumber();
391 : }
392 186901 :
393 : "/***" {
394 4 : BEGIN( COMMENT );
395 4 : docu = ::rtl::OString();
396 4 : beginLine = idlc()->getLineNumber();
397 : }
398 4 :
399 : <COMMENT>[^*]+ {
400 312116 : docu += ::rtl::OString(yytext);
401 312116 : }
402 312116 :
403 : <COMMENT>"*"[^*/]+ {
404 1062332 : docu += ::rtl::OString(yytext);
405 1062332 : }
406 1062332 :
407 : <COMMENT>"**" {
408 0 : docu += ::rtl::OString(yytext);
409 : }
410 0 :
411 : <COMMENT>[*]+"/" {
412 186905 : docu = docu.trim();
413 186905 : sal_Int32 nIndex = 0;
414 186905 : int count = 0;
415 1065098 : do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
416 186905 : idlc()->setLineNumber( beginLine + count - 1);
417 186905 : BEGIN( INITIAL );
418 : }
419 186905 :
420 : "/**" {
421 314387 : BEGIN( DOCU );
422 314387 : docu = ::rtl::OString();
423 314387 : beginLine = idlc()->getLineNumber();
424 : }
425 314387 :
426 : <DOCU>[^*\n]+ {
427 1319089 : docu += ::rtl::OString(yytext);
428 : }
429 1319089 :
430 : <DOCU>"\n"[ \t]*"*"{1} {
431 3927 : idlc()->setLineNumber( idlc()->getLineNumber() + 1);
432 7854 : docu += ::rtl::OString("\n");
433 : }
434 3927 :
435 : <DOCU>"\n" {
436 1268396 : idlc()->setLineNumber( idlc()->getLineNumber() + 1);
437 2536792 : docu += ::rtl::OString(yytext);
438 : }
439 1268396 :
440 : <DOCU>"*"[^*^/\n]* {
441 1172 : docu += ::rtl::OString(yytext);
442 : }
443 1172 :
444 : <DOCU>"\n"[ \t]*"*/" {
445 312957 : docu = docu.trim();
446 625914 : sal_Int32 nIndex = 0;
447 312957 : int count = 0;
448 1569265 : do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
449 312957 : idlc()->setLineNumber( beginLine + count - 1);
450 312957 : if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 )
451 : {
452 32 : if ( 0 != nIndex &&
453 31 : (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
454 0 : idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(),
455 0 : "nested documentation strings are not allowed!");
456 : }
457 312957 : idlc()->setDocumentation(docu);
458 312957 : BEGIN( INITIAL );
459 : }
460 312957 :
461 : <DOCU>"*/" {
462 1430 : docu = docu.trim();
463 1430 : sal_Int32 nIndex = 0;
464 1430 : int count = 0;
465 2193 : do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
466 1430 : idlc()->setLineNumber( beginLine + count - 1);
467 1430 : if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 )
468 : {
469 0 : if ( 0 != nIndex &&
470 0 : (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
471 0 : idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(),
472 0 : "nested documentation strings are not allowed!");
473 : }
474 1430 : idlc()->setDocumentation(docu);
475 1430 : BEGIN( INITIAL );
476 : }
477 1430 :
478 : "//"[^/]{1}.*"\n" {
479 : /* only a comment */
480 5086 : ::rtl::OString docStr(yytext);
481 5086 : docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
482 5086 : docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
483 5086 : docStr = docStr.trim();
484 5086 : idlc()->incLineNumber();
485 : }
486 5086 :
487 : "///".*"\n" {
488 3462 : ::rtl::OString docStr(yytext);
489 6924 : docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
490 3462 : docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
491 3462 : docStr = docStr.trim();
492 3462 : idlc()->incLineNumber();
493 3462 : idlc()->setDocumentation(docStr);
494 : }
495 3462 :
496 1871900 : . return yytext[0];
497 1871900 :
498 : ^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
499 120672 : parseLineAndFile(yytext);
500 120672 : }
501 120672 :
502 : ^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n {
503 0 : parseLineAndFile(yytext);
504 0 : }
505 0 :
506 : ^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
507 0 : parseLineAndFile(yytext);
508 0 : }
509 0 :
510 : ^#[ \t]*[0-9]*\n {
511 0 : parseLineAndFile(yytext);
512 0 : }
513 0 :
514 : ^#[ \t]*ident.*\n {
515 : /* ignore cpp ident */
516 0 : idlc()->incLineNumber();
517 : }
518 0 :
519 : ^#[ \t]*pragma[ \t].*\n { /* remember pragma */
520 0 : idlParsePragma(yytext);
521 0 : idlc()->incLineNumber();
522 : }
523 0 :
524 0 : %%
|