2 * This file is part of the LibreOffice project.
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/.
8 * This file incorporates work covered by the following license notice:
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 .
23 * scanner.ll - Lexical scanner for IDLC 1.0
30 #ifndef _IDLC_IDLC_HXX_
31 #include <idlc/idlc.hxx>
33 #ifndef _IDLC_ERRORHANDLER_HXX_
34 #include <idlc/errorhandler.hxx>
36 #ifndef _IDLC_FEHELPER_HXX_
37 #include <idlc/fehelper.hxx>
40 #include "attributeexceptions.hxx"
49 /* handle locations */
52 #define YY_USER_ACTION idlc()->setOffset(yycolumn, yycolumn+yyleng-1); \
55 sal_Int32 beginLine = 0;
58 static int asciiToInteger(char const * s, sal_Int64 * sval, sal_uInt64 * uval) {
64 unsigned int base = 10;
68 if (*s == 'X' || *s == 'x') {
74 for (; *s != 0; ++s) {
76 if (*s >= '0' && *s <= '9') {
108 // The following guarantees the invariant val <= SAL_MAX_UINT64 (because
109 // base and n are sufficiently small), *if*
110 // std::numeric_limits<sal_uInt64>::max() == SAL_MAX_UINT64:
111 sal_uInt64 nval = val * base + n;
113 idlc()->error()->syntaxError(
114 PS_NoState, idlc()->getLineNumber(),
115 "integral constant too large");
123 if (val < SAL_CONST_UINT64(0x8000000000000000)) {
124 *sval = -static_cast< sal_Int64 >(val);
125 } else if (val == SAL_CONST_UINT64(0x8000000000000000)) {
126 *sval = SAL_MIN_INT64;
128 idlc()->error()->syntaxError(
129 PS_NoState, idlc()->getLineNumber(),
130 "negative integral constant too large");
133 return IDL_INTEGER_LITERAL;
134 } else if (val <= static_cast< sal_uInt64 >(SAL_MAX_INT64)) {
135 *sval = static_cast< sal_Int64 >(val);
136 return IDL_INTEGER_LITERAL;
139 return IDL_INTEGER_ULITERAL;
143 static double asciiToFloat(const sal_Char *s)
147 sal_Int32 neg = 0, negexp = 0;
154 while (*s >= '0' && *s <= '9')
156 d = (d * 10) + *s - '0';
163 while (*s >= '0' && *s <= '9')
165 d += (*s - '0') / (e * 1.0);
170 if (*s == 'e' || *s == 'E')
182 while (*s >= '0' && *s <= '9')
184 e = (e * 10) + *s - '0';
189 for (k = 1; e > 0; k *= 10, e--)
202 static void idlParsePragma(sal_Char* pPragma)
204 ::rtl::OString pragma(pPragma);
205 sal_Int32 index = pragma.indexOf("include");
206 sal_Char* begin = pPragma + index + 8;
207 sal_Char* offset = begin;
208 while (*offset != ',') offset++;
209 //::rtl::OString include = pragma.copy(index + 8, offset - begin);
210 //unused// idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin)));
213 static void parseLineAndFile(sal_Char* pBuf)
217 sal_Bool bIsInMain = sal_False;
219 /* Skip initial '#' */
223 /* Find line number */
224 for (r++; *r == ' ' || *r == '\t' || isalpha(*r); r++) ;
226 for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ;
228 idlc()->setLineNumber((sal_uInt32)atol(h));
231 /* Find file name, if present */
232 for (; *r != '"'; r++)
234 if (*r == '\n' || *r == '\0')
238 for (; *r != '"'; r++) ;
241 idlc()->setFileName(::rtl::OString("standard input"));
243 idlc()->setFileName(::rtl::OString(h));
245 bIsInMain = (idlc()->getFileName() == idlc()->getRealFileName()) ? sal_True : sal_False;
246 idlc()->setInMainfile(bIsInMain);
249 // Suppress any warnings from generated code:
251 #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
252 #pragma GCC diagnostic ignored "-Wunused-function"
253 #pragma GCC diagnostic ignored "-Wunused-label"
255 #elif defined __SUNPRO_CC
257 #elif defined _MSC_VER
258 #pragma warning(push, 1)
269 %option never-interactive
276 HEX_DIGIT [a-fA-F0-9]
279 INT_LITERAL [1-9][0-9]*
280 OCT_LITERAL 0{OCT_DIGIT}*
281 HEX_LITERAL (0x|0X){HEX_DIGIT}*
283 IDENTIFIER_NEW ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*)
284 IDENTIFIER ("_"?({ALPHA}|{DIGIT})+)*
288 [ \t\r]+ ; /* eat up whitespace */
290 idlc()->incLineNumber();
295 attribute return IDL_ATTRIBUTE;
296 bound return IDL_BOUND;
297 case return IDL_CASE;
298 const return IDL_CONST;
299 constants return IDL_CONSTANTS;
300 constrained return IDL_CONSTRAINED;
301 default return IDL_DEFAULT;
302 enum return IDL_ENUM;
303 exception return IDL_EXCEPTION;
304 interface return IDL_INTERFACE;
305 maybeambiguous return IDL_MAYBEAMBIGUOUS;
306 maybedefault return IDL_MAYBEDEFAULT;
307 maybevoid return IDL_MAYBEVOID;
308 module return IDL_MODULE;
309 needs return IDL_NEEDS;
310 observes return IDL_OBSERVES;
311 optional return IDL_OPTIONAL;
312 property return IDL_PROPERTY;
313 raises return IDL_RAISES;
314 readonly return IDL_READONLY;
315 removable return IDL_REMOVEABLE;
316 service return IDL_SERVICE;
317 sequence return IDL_SEQUENCE;
318 singleton return IDL_SINGLETON;
319 struct return IDL_STRUCT;
320 switch return IDL_SWITCH;
321 transient return IDL_TRANSIENT;
322 typedef return IDL_TYPEDEF;
323 union return IDL_UNION;
326 boolean return IDL_BOOLEAN;
327 byte return IDL_BYTE;
328 char return IDL_CHAR;
329 double return IDL_DOUBLE;
330 float return IDL_FLOAT;
331 hyper return IDL_HYPER;
332 long return IDL_LONG;
333 short return IDL_SHORT;
334 string return IDL_STRING;
335 type return IDL_TYPE;
336 unsigned return IDL_UNSIGNED;
337 void return IDL_VOID;
339 TRUE return IDL_TRUE;
340 True return IDL_TRUE;
341 FALSE return IDL_FALSE;
342 False return IDL_FALSE;
346 inout return IDL_INOUT;
351 published return IDL_PUBLISHED;
353 "..." return IDL_ELLIPSIS;
355 ("-")?{INT_LITERAL}+(l|L|u|U)? {
356 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
359 ("-")?{OCT_LITERAL}+(l|L|u|U)? {
360 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
363 ("-")?{HEX_LITERAL}+(l|L|u|U)? {
364 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
367 ("-")?{DIGIT}+(e|E){1}(("+"|"-")?{DIGIT}+)+(f|F)? |
368 ("-")?"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? |
369 ("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? {
370 yylval.dval = asciiToFloat( yytext );
371 return IDL_FLOATING_PT_LITERAL;
375 yylval.sval = new ::rtl::OString(yytext);
376 return IDL_IDENTIFIER;
380 yylval.strval = yytext;
381 return IDL_LEFTSHIFT;
384 yylval.strval = yytext;
385 return IDL_RIGHTSHIFT;
388 yylval.strval = yytext;
389 return IDL_SCOPESEPARATOR;
394 docu = ::rtl::OString();
395 beginLine = idlc()->getLineNumber();
400 docu = ::rtl::OString();
401 beginLine = idlc()->getLineNumber();
405 docu += ::rtl::OString(yytext);
409 docu += ::rtl::OString(yytext);
413 docu += ::rtl::OString(yytext);
418 sal_Int32 nIndex = 0;
420 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
421 idlc()->setLineNumber( beginLine + count - 1);
427 docu = ::rtl::OString();
428 beginLine = idlc()->getLineNumber();
432 docu += ::rtl::OString(yytext);
435 <DOCU>"\n"[ \t]*"*"{1} {
436 idlc()->setLineNumber( idlc()->getLineNumber() + 1);
437 docu += ::rtl::OString("\n");
441 idlc()->setLineNumber( idlc()->getLineNumber() + 1);
442 docu += ::rtl::OString(yytext);
446 docu += ::rtl::OString(yytext);
449 <DOCU>"\n"[ \t]*"*/" {
451 sal_Int32 nIndex = 0;
453 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
454 idlc()->setLineNumber( beginLine + count - 1);
455 if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 )
458 (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
459 idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(),
460 "nested documentation strings are not allowed!");
462 idlc()->setDocumentation(docu);
468 sal_Int32 nIndex = 0;
470 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
471 idlc()->setLineNumber( beginLine + count - 1);
472 if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 )
475 (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
476 idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(),
477 "nested documentation strings are not allowed!");
479 idlc()->setDocumentation(docu);
485 ::rtl::OString docStr(yytext);
486 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
487 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
488 docStr = docStr.trim();
489 idlc()->incLineNumber();
493 ::rtl::OString docStr(yytext);
494 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
495 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
496 docStr = docStr.trim();
497 idlc()->incLineNumber();
498 idlc()->setDocumentation(docStr);
503 ^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
504 parseLineAndFile(yytext);
507 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n {
508 parseLineAndFile(yytext);
511 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
512 parseLineAndFile(yytext);
516 parseLineAndFile(yytext);
520 /* ignore cpp ident */
521 idlc()->incLineNumber();
524 ^#[ \t]*pragma[ \t].*\n { /* remember pragma */
525 idlParsePragma(yytext);
526 idlc()->incLineNumber();