1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
24 * scanner.ll - Lexical scanner for IDLC 1.0
27 #include <sal/config.h>
32 #include <rtl/character.hxx>
35 #pragma warning ( push )
36 // Silence warnings about redefinition of INT8_MIN etc in stdint.h
37 // The flex-generated workdir/LexTarget/idlc/source/scanner.cxx defines them prior to these includes
38 #pragma warning ( disable : 4005 )
42 #pragma warning ( pop )
44 #include <errorhandler.hxx>
45 #include <fehelper.hxx>
47 #include "attributeexceptions.hxx"
55 /* handle locations */
56 static int yycolumn = 1;
58 #define YY_USER_ACTION idlc()->setOffset(yycolumn, yycolumn+yyleng-1); \
61 static sal_Int32 beginLine = 0;
64 static int asciiToInteger(char const * s, sal_Int64 * sval, sal_uInt64 * uval) {
70 unsigned int base = 10;
74 if (*s == 'X' || *s == 'x') {
80 for (; *s != 0; ++s) {
82 if (*s >= '0' && *s <= '9') {
114 // The following guarantees the invariant val <= SAL_MAX_UINT64 (because
115 // base and n are sufficiently small), *if*
116 // std::numeric_limits<sal_uInt64>::max() == SAL_MAX_UINT64:
117 sal_uInt64 nval = val * base + n;
119 ErrorHandler::syntaxError(
120 PS_NoState, idlc()->getLineNumber(),
121 "integral constant too large");
129 if (val < SAL_CONST_UINT64(0x8000000000000000)) {
130 *sval = -static_cast< sal_Int64 >(val);
131 } else if (val == SAL_CONST_UINT64(0x8000000000000000)) {
132 *sval = SAL_MIN_INT64;
134 ErrorHandler::syntaxError(
135 PS_NoState, idlc()->getLineNumber(),
136 "negative integral constant too large");
139 return IDL_INTEGER_LITERAL;
140 } else if (val <= static_cast< sal_uInt64 >(SAL_MAX_INT64)) {
141 *sval = static_cast< sal_Int64 >(val);
142 return IDL_INTEGER_LITERAL;
145 return IDL_INTEGER_ULITERAL;
149 static double asciiToFloat(const sal_Char *s)
160 while (*s >= '0' && *s <= '9')
162 d = (d * 10) + *s - '0';
169 while (*s >= '0' && *s <= '9')
171 d += (*s - '0') / (e * 1.0);
176 if (*s == 'e' || *s == 'E')
187 while (*s >= '0' && *s <= '9')
189 e = (e * 10) + *s - '0';
194 for (k = 1; e > 0; k *= 10, e--)
204 static void idlParsePragma(sal_Char* pPragma)
206 OString pragma(pPragma);
207 sal_Int32 index = pragma.indexOf("include");
208 sal_Char* begin = pPragma + index + 8;
209 sal_Char* offset = begin;
210 while (*offset != ',') offset++;
211 //OString include = pragma.copy(index + 8, offset - begin);
212 //unused// idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin)));
215 static void parseLineAndFile(sal_Char* pBuf)
219 bool bIsInMain = false;
221 /* Skip initial '#' */
225 /* Find line number */
226 for (r++; *r == ' ' || *r == '\t' || rtl::isAsciiAlpha(static_cast<unsigned char>(*r)); r++) ;
228 for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ;
230 idlc()->setLineNumber(sal_uInt32(atol(h)));
233 /* Find file name, if present */
234 for (; *r != '"'; r++)
236 if (*r == '\n' || *r == '\0')
240 for (; *r != '"'; r++) ;
243 idlc()->setFileName("standard input");
245 idlc()->setFileName(OString(h));
247 bIsInMain = idlc()->getFileName() == idlc()->getRealFileName();
248 idlc()->setInMainfile(bIsInMain);
251 // Suppress any warnings from generated code:
253 #pragma GCC diagnostic ignored "-Wunused-function"
254 #pragma GCC diagnostic ignored "-Wunused-label"
255 #elif defined _MSC_VER
263 #define YY_NO_UNISTD_H
267 %option never-interactive
274 HEX_DIGIT [a-fA-F0-9]
277 INT_LITERAL [1-9][0-9]*
278 OCT_LITERAL 0{OCT_DIGIT}*
279 HEX_LITERAL (0x|0X){HEX_DIGIT}*
281 IDENTIFIER_NEW ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*)
282 IDENTIFIER ("_"?({ALPHA}|{DIGIT})+)*
286 [ \t\r]+ ; /* eat up whitespace */
288 idlc()->incLineNumber();
293 attribute return IDL_ATTRIBUTE;
294 bound return IDL_BOUND;
295 const return IDL_CONST;
296 constants return IDL_CONSTANTS;
297 constrained return IDL_CONSTRAINED;
298 enum return IDL_ENUM;
299 exception return IDL_EXCEPTION;
300 interface return IDL_INTERFACE;
301 maybeambiguous return IDL_MAYBEAMBIGUOUS;
302 maybedefault return IDL_MAYBEDEFAULT;
303 maybevoid return IDL_MAYBEVOID;
304 module return IDL_MODULE;
305 needs return IDL_NEEDS;
306 observes return IDL_OBSERVES;
307 optional return IDL_OPTIONAL;
308 property return IDL_PROPERTY;
309 raises return IDL_RAISES;
310 readonly return IDL_READONLY;
311 removable return IDL_REMOVABLE;
312 service return IDL_SERVICE;
313 sequence return IDL_SEQUENCE;
314 singleton return IDL_SINGLETON;
315 struct return IDL_STRUCT;
316 transient return IDL_TRANSIENT;
317 typedef return IDL_TYPEDEF;
320 boolean return IDL_BOOLEAN;
321 byte return IDL_BYTE;
322 char return IDL_CHAR;
323 double return IDL_DOUBLE;
324 float return IDL_FLOAT;
325 hyper return IDL_HYPER;
326 long return IDL_LONG;
327 short return IDL_SHORT;
328 string return IDL_STRING;
329 type return IDL_TYPE;
330 unsigned return IDL_UNSIGNED;
331 void return IDL_VOID;
333 TRUE return IDL_TRUE;
334 True return IDL_TRUE;
335 FALSE return IDL_FALSE;
336 False return IDL_FALSE;
340 inout return IDL_INOUT;
345 published return IDL_PUBLISHED;
347 "..." return IDL_ELLIPSIS;
349 ("-")?{INT_LITERAL}+(l|L|u|U)? {
350 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
353 ("-")?{OCT_LITERAL}+(l|L|u|U)? {
354 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
357 ("-")?{HEX_LITERAL}+(l|L|u|U)? {
358 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
361 ("-")?{DIGIT}+(e|E)(("+"|"-")?{DIGIT}+)?(f|F)? |
362 ("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? {
363 yylval.dval = asciiToFloat( yytext );
364 return IDL_FLOATING_PT_LITERAL;
368 yylval.sval = new OString(yytext);
369 return IDL_IDENTIFIER;
373 yylval.strval = yytext;
374 return IDL_LEFTSHIFT;
377 yylval.strval = yytext;
378 return IDL_RIGHTSHIFT;
381 yylval.strval = yytext;
382 return IDL_SCOPESEPARATOR;
388 beginLine = idlc()->getLineNumber();
394 beginLine = idlc()->getLineNumber();
398 docu += OString(yytext);
402 docu += OString(yytext);
406 docu += OString(yytext);
411 sal_Int32 nIndex = 0;
413 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
414 idlc()->setLineNumber( beginLine + count - 1);
421 beginLine = idlc()->getLineNumber();
425 docu += OString(yytext);
428 <DOCU>"\n"[ \t]*"*"{1} {
429 idlc()->setLineNumber( idlc()->getLineNumber() + 1);
430 docu += OString("\n");
434 idlc()->setLineNumber( idlc()->getLineNumber() + 1);
435 docu += OString(yytext);
439 docu += OString(yytext);
442 <DOCU>"\n"[ \t]*"*/" {
444 sal_Int32 nIndex = 0;
446 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
447 idlc()->setLineNumber( beginLine + count - 1);
448 if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 )
451 (docu[nIndex - 1] != '"' && docu[nIndex - 1] != ':') )
452 ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
453 "nested documentation strings are not allowed!");
455 idlc()->setDocumentation(docu);
461 sal_Int32 nIndex = 0;
463 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
464 idlc()->setLineNumber( beginLine + count - 1);
465 if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 )
468 (docu[nIndex - 1] != '"' && docu[nIndex - 1] != ':') )
469 ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
470 "nested documentation strings are not allowed!");
472 idlc()->setDocumentation(docu);
478 OString docStr(yytext);
479 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
480 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
481 docStr = docStr.trim();
482 idlc()->incLineNumber();
486 OString docStr(yytext);
487 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
488 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
489 docStr = docStr.trim();
490 idlc()->incLineNumber();
491 idlc()->setDocumentation(docStr);
496 ^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
497 parseLineAndFile(yytext);
500 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n {
501 parseLineAndFile(yytext);
504 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
505 parseLineAndFile(yytext);
509 parseLineAndFile(yytext);
513 /* ignore cpp ident */
514 idlc()->incLineNumber();
517 ^#[ \t]*pragma[ \t].*\n { /* remember pragma */
518 idlParsePragma(yytext);
519 idlc()->incLineNumber();
524 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */