1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: scanner.ll,v $
10 * $Revision: 1.16.16.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
33 * scanner.ll - Lexical scanner for IDLC 1.0
40 #ifndef _IDLC_IDLC_HXX_
41 #include <idlc/idlc.hxx>
43 #ifndef _IDLC_ERRORHANDLER_HXX_
44 #include <idlc/errorhandler.hxx>
46 #ifndef _IDLC_FEHELPER_HXX_
47 #include <idlc/fehelper.hxx>
50 #include "attributeexceptions.hxx"
58 sal_Int32 beginLine = 0;
61 static int asciiToInteger(char const * s, sal_Int64 * sval, sal_uInt64 * uval) {
67 unsigned int base = 10;
71 if (*s == 'X' || *s == 'x') {
77 for (; *s != 0; ++s) {
79 if (*s >= '0' && *s <= '9') {
111 // The following guarantees the invariant val <= SAL_MAX_UINT64 (because
112 // base and n are sufficiently small), *if*
113 // std::numeric_limits<sal_uInt64>::max() == SAL_MAX_UINT64:
114 sal_uInt64 nval = val * base + n;
116 idlc()->error()->syntaxError(
117 PS_NoState, idlc()->getLineNumber(),
118 "integral constant too large");
126 if (val < SAL_CONST_UINT64(0x8000000000000000)) {
127 *sval = -static_cast< sal_Int64 >(val);
128 } else if (val == SAL_CONST_UINT64(0x8000000000000000)) {
129 *sval = SAL_MIN_INT64;
131 idlc()->error()->syntaxError(
132 PS_NoState, idlc()->getLineNumber(),
133 "negative integral constant too large");
136 return IDL_INTEGER_LITERAL;
137 } else if (val <= static_cast< sal_uInt64 >(SAL_MAX_INT64)) {
138 *sval = static_cast< sal_Int64 >(val);
139 return IDL_INTEGER_LITERAL;
142 return IDL_INTEGER_ULITERAL;
146 static double asciiToFloat(const sal_Char *s)
150 sal_Int32 neg = 0, negexp = 0;
157 while (*s >= '0' && *s <= '9')
159 d = (d * 10) + *s - '0';
166 while (*s >= '0' && *s <= '9')
168 d += (*s - '0') / (e * 1.0);
173 if (*s == 'e' || *s == 'E')
185 while (*s >= '0' && *s <= '9')
187 e = (e * 10) + *s - '0';
192 for (k = 1; e > 0; k *= 10, e--) ;
204 static void idlParsePragma(sal_Char* pPragma)
206 ::rtl::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 //::rtl::OString include = pragma.copy(index + 8, offset - begin);
212 idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin)));
215 static void parseLineAndFile(sal_Char* pBuf)
219 sal_Bool bIsInMain = sal_False;
221 /* Skip initial '#' */
225 /* Find line number */
226 for (r++; *r == ' ' || *r == '\t' || isalpha(*r); r++) ;
228 for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ;
230 idlc()->setLineNumber((sal_uInt32)atol(h));
232 /* Find file name, if present */
233 for (; *r != '"'; r++)
235 if (*r == '\n' || *r == '\0')
239 for (; *r != '"'; r++) ;
242 idlc()->setFileName(::rtl::OString("standard input"));
244 idlc()->setFileName(::rtl::OString(h));
246 bIsInMain = (idlc()->getFileName() == idlc()->getRealFileName()) ? sal_True : sal_False;
247 idlc()->setInMainfile(bIsInMain);
250 // Suppress any warnings from generated code:
252 #pragma GCC system_header
253 #elif defined __SUNPRO_CC
255 #elif defined _MSC_VER
256 #pragma warning(push, 1)
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();
291 attribute return IDL_ATTRIBUTE;
292 bound return IDL_BOUND;
293 case return IDL_CASE;
294 const return IDL_CONST;
295 constants return IDL_CONSTANTS;
296 constrained return IDL_CONSTRAINED;
297 default return IDL_DEFAULT;
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_REMOVEABLE;
312 service return IDL_SERVICE;
313 sequence return IDL_SEQUENCE;
314 singleton return IDL_SINGLETON;
315 struct return IDL_STRUCT;
316 switch return IDL_SWITCH;
317 transient return IDL_TRANSIENT;
318 typedef return IDL_TYPEDEF;
319 union return IDL_UNION;
322 boolean return IDL_BOOLEAN;
323 byte return IDL_BYTE;
324 char return IDL_CHAR;
325 double return IDL_DOUBLE;
326 float return IDL_FLOAT;
327 hyper return IDL_HYPER;
328 long return IDL_LONG;
329 short return IDL_SHORT;
330 string return IDL_STRING;
331 type return IDL_TYPE;
332 unsigned return IDL_UNSIGNED;
333 void return IDL_VOID;
335 TRUE return IDL_TRUE;
336 True return IDL_TRUE;
337 FALSE return IDL_FALSE;
338 False return IDL_FALSE;
342 inout return IDL_INOUT;
343 oneway return IDL_ONEWAY;
348 published return IDL_PUBLISHED;
350 "..." return IDL_ELLIPSIS;
352 ("-")?{INT_LITERAL}+(l|L|u|U)? {
353 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
356 ("-")?{OCT_LITERAL}+(l|L|u|U)? {
357 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
360 ("-")?{HEX_LITERAL}+(l|L|u|U)? {
361 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
364 ("-")?{DIGIT}+(e|E){1}(("+"|"-")?{DIGIT}+)+(f|F)? |
365 ("-")?"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? |
366 ("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? {
367 yylval.dval = asciiToFloat( yytext );
368 return IDL_FLOATING_PT_LITERAL;
372 yylval.sval = new ::rtl::OString(yytext);
373 return IDL_IDENTIFIER;
377 yylval.strval = yytext;
378 return IDL_LEFTSHIFT;
381 yylval.strval = yytext;
382 return IDL_RIGHTSHIFT;
385 yylval.strval = yytext;
386 return IDL_SCOPESEPARATOR;
391 docu = ::rtl::OString();
392 beginLine = idlc()->getLineNumber();
397 docu = ::rtl::OString();
398 beginLine = idlc()->getLineNumber();
402 docu += ::rtl::OString(yytext);
406 docu += ::rtl::OString(yytext);
410 docu += ::rtl::OString(yytext);
415 sal_Int32 nIndex = 0;
417 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
418 idlc()->setLineNumber( beginLine + count - 1);
424 docu = ::rtl::OString();
425 beginLine = idlc()->getLineNumber();
429 docu += ::rtl::OString(yytext);
432 <DOCU>"\n"[ \t]*"*"{1} {
433 idlc()->setLineNumber( idlc()->getLineNumber() + 1);
434 docu += ::rtl::OString("\n");
438 idlc()->setLineNumber( idlc()->getLineNumber() + 1);
439 docu += ::rtl::OString(yytext);
443 docu += ::rtl::OString(yytext);
446 <DOCU>"\n"[ \t]*"*/" {
448 sal_Int32 nIndex = 0;
450 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
451 idlc()->setLineNumber( beginLine + count - 1);
452 if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 )
455 (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
456 idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(),
457 "nested documentation strings are not allowed!");
459 idlc()->setDocumentation(docu);
465 sal_Int32 nIndex = 0;
467 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
468 idlc()->setLineNumber( beginLine + count - 1);
469 if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 )
472 (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
473 idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(),
474 "nested documentation strings are not allowed!");
476 idlc()->setDocumentation(docu);
482 ::rtl::OString docStr(yytext);
483 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
484 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
485 docStr = docStr.trim();
486 idlc()->incLineNumber();
490 ::rtl::OString docStr(yytext);
491 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
492 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
493 docStr = docStr.trim();
494 idlc()->incLineNumber();
495 idlc()->setDocumentation(docStr);
500 ^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
501 parseLineAndFile(yytext);
504 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n {
505 parseLineAndFile(yytext);
508 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
509 parseLineAndFile(yytext);
513 parseLineAndFile(yytext);
517 /* ignore cpp ident */
518 idlc()->incLineNumber();
521 ^#[ \t]*pragma[ \t].*\n { /* remember pragma */
522 idlParsePragma(yytext);
523 idlc()->incLineNumber();