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
26 #include "sal/config.h"
32 #include <idlc/idlc.hxx>
33 #include <idlc/errorhandler.hxx>
34 #include <idlc/fehelper.hxx>
36 #include "attributeexceptions.hxx"
44 /* handle locations */
47 #define YY_USER_ACTION idlc()->setOffset(yycolumn, yycolumn+yyleng-1); \
50 sal_Int32 beginLine = 0;
53 static int asciiToInteger(char const * s, sal_Int64 * sval, sal_uInt64 * uval) {
59 unsigned int base = 10;
63 if (*s == 'X' || *s == 'x') {
69 for (; *s != 0; ++s) {
71 if (*s >= '0' && *s <= '9') {
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 sal_uInt64 nval = val * base + n;
108 ErrorHandler::syntaxError(
109 PS_NoState, idlc()->getLineNumber(),
110 "integral constant too large");
118 if (val < SAL_CONST_UINT64(0x8000000000000000)) {
119 *sval = -static_cast< sal_Int64 >(val);
120 } else if (val == SAL_CONST_UINT64(0x8000000000000000)) {
121 *sval = SAL_MIN_INT64;
123 ErrorHandler::syntaxError(
124 PS_NoState, idlc()->getLineNumber(),
125 "negative integral constant too large");
128 return IDL_INTEGER_LITERAL;
129 } else if (val <= static_cast< sal_uInt64 >(SAL_MAX_INT64)) {
130 *sval = static_cast< sal_Int64 >(val);
131 return IDL_INTEGER_LITERAL;
134 return IDL_INTEGER_ULITERAL;
138 static double asciiToFloat(const sal_Char *s)
149 while (*s >= '0' && *s <= '9')
151 d = (d * 10) + *s - '0';
158 while (*s >= '0' && *s <= '9')
160 d += (*s - '0') / (e * 1.0);
165 if (*s == 'e' || *s == 'E')
176 while (*s >= '0' && *s <= '9')
178 e = (e * 10) + *s - '0';
183 for (k = 1; e > 0; k *= 10, e--)
193 static void idlParsePragma(sal_Char* pPragma)
195 ::rtl::OString pragma(pPragma);
196 sal_Int32 index = pragma.indexOf("include");
197 sal_Char* begin = pPragma + index + 8;
198 sal_Char* offset = begin;
199 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)));
204 static void parseLineAndFile(sal_Char* pBuf)
208 bool bIsInMain = false;
210 /* Skip initial '#' */
214 /* Find line number */
215 for (r++; *r == ' ' || *r == '\t' || isalpha(*r); r++) ;
217 for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ;
219 idlc()->setLineNumber((sal_uInt32)atol(h));
222 /* Find file name, if present */
223 for (; *r != '"'; r++)
225 if (*r == '\n' || *r == '\0')
229 for (; *r != '"'; r++) ;
232 idlc()->setFileName(::rtl::OString("standard input"));
234 idlc()->setFileName(::rtl::OString(h));
236 bIsInMain = idlc()->getFileName() == idlc()->getRealFileName();
237 idlc()->setInMainfile(bIsInMain);
240 // Suppress any warnings from generated code:
242 #pragma GCC diagnostic ignored "-Wunused-function"
243 #pragma GCC diagnostic ignored "-Wunused-label"
244 #elif defined _MSC_VER
245 #pragma warning(push, 1)
253 #define YY_NO_UNISTD_H
257 %option never-interactive
264 HEX_DIGIT [a-fA-F0-9]
267 INT_LITERAL [1-9][0-9]*
268 OCT_LITERAL 0{OCT_DIGIT}*
269 HEX_LITERAL (0x|0X){HEX_DIGIT}*
271 IDENTIFIER_NEW ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*)
272 IDENTIFIER ("_"?({ALPHA}|{DIGIT})+)*
276 [ \t\r]+ ; /* eat up whitespace */
278 idlc()->incLineNumber();
283 attribute return IDL_ATTRIBUTE;
284 bound return IDL_BOUND;
285 const return IDL_CONST;
286 constants return IDL_CONSTANTS;
287 constrained return IDL_CONSTRAINED;
288 enum return IDL_ENUM;
289 exception return IDL_EXCEPTION;
290 interface return IDL_INTERFACE;
291 maybeambiguous return IDL_MAYBEAMBIGUOUS;
292 maybedefault return IDL_MAYBEDEFAULT;
293 maybevoid return IDL_MAYBEVOID;
294 module return IDL_MODULE;
295 needs return IDL_NEEDS;
296 observes return IDL_OBSERVES;
297 optional return IDL_OPTIONAL;
298 property return IDL_PROPERTY;
299 raises return IDL_RAISES;
300 readonly return IDL_READONLY;
301 removable return IDL_REMOVABLE;
302 service return IDL_SERVICE;
303 sequence return IDL_SEQUENCE;
304 singleton return IDL_SINGLETON;
305 struct return IDL_STRUCT;
306 transient return IDL_TRANSIENT;
307 typedef return IDL_TYPEDEF;
310 boolean return IDL_BOOLEAN;
311 byte return IDL_BYTE;
312 char return IDL_CHAR;
313 double return IDL_DOUBLE;
314 float return IDL_FLOAT;
315 hyper return IDL_HYPER;
316 long return IDL_LONG;
317 short return IDL_SHORT;
318 string return IDL_STRING;
319 type return IDL_TYPE;
320 unsigned return IDL_UNSIGNED;
321 void return IDL_VOID;
323 TRUE return IDL_TRUE;
324 True return IDL_TRUE;
325 FALSE return IDL_FALSE;
326 False return IDL_FALSE;
330 inout return IDL_INOUT;
335 published return IDL_PUBLISHED;
337 "..." return IDL_ELLIPSIS;
339 ("-")?{INT_LITERAL}+(l|L|u|U)? {
340 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
343 ("-")?{OCT_LITERAL}+(l|L|u|U)? {
344 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
347 ("-")?{HEX_LITERAL}+(l|L|u|U)? {
348 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
351 ("-")?{DIGIT}+(e|E)(("+"|"-")?{DIGIT}+)?(f|F)? |
352 ("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? {
353 yylval.dval = asciiToFloat( yytext );
354 return IDL_FLOATING_PT_LITERAL;
358 yylval.sval = new ::rtl::OString(yytext);
359 return IDL_IDENTIFIER;
363 yylval.strval = yytext;
364 return IDL_LEFTSHIFT;
367 yylval.strval = yytext;
368 return IDL_RIGHTSHIFT;
371 yylval.strval = yytext;
372 return IDL_SCOPESEPARATOR;
377 docu = ::rtl::OString();
378 beginLine = idlc()->getLineNumber();
383 docu = ::rtl::OString();
384 beginLine = idlc()->getLineNumber();
388 docu += ::rtl::OString(yytext);
392 docu += ::rtl::OString(yytext);
396 docu += ::rtl::OString(yytext);
401 sal_Int32 nIndex = 0;
403 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
404 idlc()->setLineNumber( beginLine + count - 1);
410 docu = ::rtl::OString();
411 beginLine = idlc()->getLineNumber();
415 docu += ::rtl::OString(yytext);
418 <DOCU>"\n"[ \t]*"*"{1} {
419 idlc()->setLineNumber( idlc()->getLineNumber() + 1);
420 docu += ::rtl::OString("\n");
424 idlc()->setLineNumber( idlc()->getLineNumber() + 1);
425 docu += ::rtl::OString(yytext);
429 docu += ::rtl::OString(yytext);
432 <DOCU>"\n"[ \t]*"*/" {
434 sal_Int32 nIndex = 0;
436 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
437 idlc()->setLineNumber( beginLine + count - 1);
438 if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 )
441 (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
442 ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
443 "nested documentation strings are not allowed!");
445 idlc()->setDocumentation(docu);
451 sal_Int32 nIndex = 0;
453 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
454 idlc()->setLineNumber( beginLine + count - 1);
455 if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 )
458 (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
459 ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
460 "nested documentation strings are not allowed!");
462 idlc()->setDocumentation(docu);
468 ::rtl::OString docStr(yytext);
469 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
470 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
471 docStr = docStr.trim();
472 idlc()->incLineNumber();
476 ::rtl::OString docStr(yytext);
477 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
478 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
479 docStr = docStr.trim();
480 idlc()->incLineNumber();
481 idlc()->setDocumentation(docStr);
486 ^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
487 parseLineAndFile(yytext);
490 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n {
491 parseLineAndFile(yytext);
494 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
495 parseLineAndFile(yytext);
499 parseLineAndFile(yytext);
503 /* ignore cpp ident */
504 idlc()->incLineNumber();
507 ^#[ \t]*pragma[ \t].*\n { /* remember pragma */
508 idlParsePragma(yytext);
509 idlc()->incLineNumber();