1/************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28%{ 29/* 30 * scanner.ll - Lexical scanner for IDLC 1.0 31 */ 32 33#include <ctype.h> 34#include <stdlib.h> 35#include <string.h> 36 37#ifndef _IDLC_IDLC_HXX_ 38#include <idlc/idlc.hxx> 39#endif 40#ifndef _IDLC_ERRORHANDLER_HXX_ 41#include <idlc/errorhandler.hxx> 42#endif 43#ifndef _IDLC_FEHELPER_HXX_ 44#include <idlc/fehelper.hxx> 45#endif 46 47#include "attributeexceptions.hxx" 48 49class AstExpression; 50class AstArray; 51class AstMember; 52 53#include <parser.hxx> 54 55sal_Int32 beginLine = 0; 56::rtl::OString docu; 57 58static int asciiToInteger(char const * s, sal_Int64 * sval, sal_uInt64 * uval) { 59 bool neg = false; 60 if (*s == '-') { 61 neg = true; 62 ++s; 63 } 64 unsigned int base = 10; 65 if (*s == '0') { 66 base = 8; 67 ++s; 68 if (*s == 'X' || *s == 'x') { 69 base = 16; 70 ++s; 71 } 72 } 73 sal_uInt64 val = 0; 74 for (; *s != 0; ++s) { 75 unsigned int n; 76 if (*s >= '0' && *s <= '9') { 77 n = *s - '0'; 78 } else { 79 switch (*s) { 80 case 'A': 81 case 'a': 82 n = 10; 83 break; 84 case 'B': 85 case 'b': 86 n = 11; 87 break; 88 case 'C': 89 case 'c': 90 n = 12; 91 break; 92 case 'D': 93 case 'd': 94 n = 13; 95 break; 96 case 'E': 97 case 'e': 98 n = 14; 99 break; 100 case 'F': 101 case 'f': 102 n = 15; 103 break; 104 default: 105 goto done; 106 } 107 } 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; 112 if (nval < val) { 113 idlc()->error()->syntaxError( 114 PS_NoState, idlc()->getLineNumber(), 115 "integral constant too large"); 116 val = 0; 117 break; 118 } 119 val = nval; 120 } 121 done: 122 if (neg) { 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; 127 } else { 128 idlc()->error()->syntaxError( 129 PS_NoState, idlc()->getLineNumber(), 130 "negative integral constant too large"); 131 *sval = 0; 132 } 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; 137 } else { 138 *uval = val; 139 return IDL_INTEGER_ULITERAL; 140 } 141} 142 143static double asciiToFloat(const sal_Char *s) 144{ 145 double d = 0.0; 146 double e, k; 147 sal_Int32 neg = 0, negexp = 0; 148 149 if (*s == '-') 150 { 151 neg = 1; 152 s++; 153 } 154 while (*s >= '0' && *s <= '9') 155 { 156 d = (d * 10) + *s - '0'; 157 s++; 158 } 159 if (*s == '.') 160 { 161 s++; 162 e = 10; 163 while (*s >= '0' && *s <= '9') 164 { 165 d += (*s - '0') / (e * 1.0); 166 e *= 10; 167 s++; 168 } 169 } 170 if (*s == 'e' || *s == 'E') 171 { 172 s++; 173 if (*s == '-') 174 { 175 negexp = 1; 176 s++; 177 } else 178 { 179 if (*s == '+') 180 s++; 181 e = 0; 182 while (*s >= '0' && *s <= '9') 183 { 184 e = (e * 10) + *s - '0'; 185 s++; 186 } 187 if (e > 0) 188 { 189 for (k = 1; e > 0; k *= 10, e--) ; 190 if (negexp) 191 d /= k; 192 else 193 d *= k; 194 } 195 } 196 } 197 if (neg) d *= -1.0; 198 return d; 199} 200 201static void idlParsePragma(sal_Char* pPragma) 202{ 203 ::rtl::OString pragma(pPragma); 204 sal_Int32 index = pragma.indexOf("include"); 205 sal_Char* begin = pPragma + index + 8; 206 sal_Char* offset = begin; 207 while (*offset != ',') offset++; 208 //::rtl::OString include = pragma.copy(index + 8, offset - begin); 209 idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin))); 210} 211 212static void parseLineAndFile(sal_Char* pBuf) 213{ 214 sal_Char *r = pBuf; 215 sal_Char *h; 216 sal_Bool bIsInMain = sal_False; 217 218 /* Skip initial '#' */ 219 if (*r != '#') 220 return; 221 222 /* Find line number */ 223 for (r++; *r == ' ' || *r == '\t' || isalpha(*r); r++) ; 224 h = r; 225 for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ; 226 *r++ = 0; 227 idlc()->setLineNumber((sal_uInt32)atol(h)); 228 229 /* Find file name, if present */ 230 for (; *r != '"'; r++) 231 { 232 if (*r == '\n' || *r == '\0') 233 return; 234 } 235 h = ++r; 236 for (; *r != '"'; r++) ; 237 *r = 0; 238 if (*h == '\0') 239 idlc()->setFileName(::rtl::OString("standard input")); 240 else 241 idlc()->setFileName(::rtl::OString(h)); 242 243 bIsInMain = (idlc()->getFileName() == idlc()->getRealFileName()) ? sal_True : sal_False; 244 idlc()->setInMainfile(bIsInMain); 245} 246 247// Suppress any warnings from generated code: 248#if defined __GNUC__ 249#pragma GCC system_header 250#elif defined __SUNPRO_CC 251#pragma disable_warn 252#elif defined _MSC_VER 253#pragma warning(push, 1) 254/**/ 255#ifdef yywrap 256#undef yywrap 257#define yywrap() 1 258#endif 259/**/ 260#endif 261%} 262 263%option noyywrap 264%option never-interactive 265 266%x DOCU 267%x COMMENT 268 269DIGIT [0-9] 270OCT_DIGIT [0-7] 271HEX_DIGIT [a-fA-F0-9] 272CAPITAL [A-Z] 273ALPHA [a-zA-Z] 274INT_LITERAL [1-9][0-9]* 275OCT_LITERAL 0{OCT_DIGIT}* 276HEX_LITERAL (0x|0X){HEX_DIGIT}* 277 278IDENTIFIER_NEW ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*) 279IDENTIFIER ("_"?({ALPHA}|{DIGIT})+)* 280 281%% 282 283[ \t\r]+ ; /* eat up whitespace */ 284[\n] { 285 idlc()->incLineNumber(); 286} 287 288attribute return IDL_ATTRIBUTE; 289bound return IDL_BOUND; 290case return IDL_CASE; 291const return IDL_CONST; 292constants return IDL_CONSTANTS; 293constrained return IDL_CONSTRAINED; 294default return IDL_DEFAULT; 295enum return IDL_ENUM; 296exception return IDL_EXCEPTION; 297interface return IDL_INTERFACE; 298maybeambiguous return IDL_MAYBEAMBIGUOUS; 299maybedefault return IDL_MAYBEDEFAULT; 300maybevoid return IDL_MAYBEVOID; 301module return IDL_MODULE; 302needs return IDL_NEEDS; 303observes return IDL_OBSERVES; 304optional return IDL_OPTIONAL; 305property return IDL_PROPERTY; 306raises return IDL_RAISES; 307readonly return IDL_READONLY; 308removable return IDL_REMOVEABLE; 309service return IDL_SERVICE; 310sequence return IDL_SEQUENCE; 311singleton return IDL_SINGLETON; 312struct return IDL_STRUCT; 313switch return IDL_SWITCH; 314transient return IDL_TRANSIENT; 315typedef return IDL_TYPEDEF; 316union return IDL_UNION; 317 318any return IDL_ANY; 319boolean return IDL_BOOLEAN; 320byte return IDL_BYTE; 321char return IDL_CHAR; 322double return IDL_DOUBLE; 323float return IDL_FLOAT; 324hyper return IDL_HYPER; 325long return IDL_LONG; 326short return IDL_SHORT; 327string return IDL_STRING; 328type return IDL_TYPE; 329unsigned return IDL_UNSIGNED; 330void return IDL_VOID; 331 332TRUE return IDL_TRUE; 333True return IDL_TRUE; 334FALSE return IDL_FALSE; 335False return IDL_FALSE; 336 337in return IDL_IN; 338out return IDL_OUT; 339inout return IDL_INOUT; 340oneway return IDL_ONEWAY; 341 342get return IDL_GET; 343set return IDL_SET; 344 345published return IDL_PUBLISHED; 346 347"..." return IDL_ELLIPSIS; 348 349("-")?{INT_LITERAL}+(l|L|u|U)? { 350 return asciiToInteger(yytext, &yylval.ival, &yylval.uval); 351 } 352 353("-")?{OCT_LITERAL}+(l|L|u|U)? { 354 return asciiToInteger(yytext, &yylval.ival, &yylval.uval); 355 } 356 357("-")?{HEX_LITERAL}+(l|L|u|U)? { 358 return asciiToInteger(yytext, &yylval.ival, &yylval.uval); 359 } 360 361("-")?{DIGIT}+(e|E){1}(("+"|"-")?{DIGIT}+)+(f|F)? | 362("-")?"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? | 363("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? { 364 yylval.dval = asciiToFloat( yytext ); 365 return IDL_FLOATING_PT_LITERAL; 366 } 367 368{IDENTIFIER} { 369 yylval.sval = new ::rtl::OString(yytext); 370 return IDL_IDENTIFIER; 371 } 372 373\<\< { 374 yylval.strval = yytext; 375 return IDL_LEFTSHIFT; 376 } 377\>\> { 378 yylval.strval = yytext; 379 return IDL_RIGHTSHIFT; 380 } 381\:\: { 382 yylval.strval = yytext; 383 return IDL_SCOPESEPARATOR; 384 } 385 386"/*" { 387 BEGIN( COMMENT ); 388 docu = ::rtl::OString(); 389 beginLine = idlc()->getLineNumber(); 390 } 391 392"/***" { 393 BEGIN( COMMENT ); 394 docu = ::rtl::OString(); 395 beginLine = idlc()->getLineNumber(); 396 } 397 398<COMMENT>[^*]+ { 399 docu += ::rtl::OString(yytext); 400 } 401 402<COMMENT>"*"[^*/]+ { 403 docu += ::rtl::OString(yytext); 404 } 405 406<COMMENT>"**" { 407 docu += ::rtl::OString(yytext); 408 } 409 410<COMMENT>[*]+"/" { 411 docu = docu.trim(); 412 sal_Int32 nIndex = 0; 413 int count = 0; 414 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 ); 415 idlc()->setLineNumber( beginLine + count - 1); 416 BEGIN( INITIAL ); 417 } 418 419"/**" { 420 BEGIN( DOCU ); 421 docu = ::rtl::OString(); 422 beginLine = idlc()->getLineNumber(); 423 } 424 425<DOCU>[^*\n]+ { 426 docu += ::rtl::OString(yytext); 427 } 428 429<DOCU>"\n"[ \t]*"*"{1} { 430 idlc()->setLineNumber( idlc()->getLineNumber() + 1); 431 docu += ::rtl::OString("\n"); 432 } 433 434<DOCU>"\n" { 435 idlc()->setLineNumber( idlc()->getLineNumber() + 1); 436 docu += ::rtl::OString(yytext); 437 } 438 439<DOCU>"*"[^*^/\n]* { 440 docu += ::rtl::OString(yytext); 441 } 442 443<DOCU>"\n"[ \t]*"*/" { 444 docu = docu.trim(); 445 sal_Int32 nIndex = 0; 446 int count = 0; 447 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 ); 448 idlc()->setLineNumber( beginLine + count - 1); 449 if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 ) 450 { 451 if ( 0 != nIndex && 452 (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') ) 453 idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(), 454 "nested documentation strings are not allowed!"); 455 } 456 idlc()->setDocumentation(docu); 457 BEGIN( INITIAL ); 458 } 459 460<DOCU>"*/" { 461 docu = docu.trim(); 462 sal_Int32 nIndex = 0; 463 int count = 0; 464 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 ); 465 idlc()->setLineNumber( beginLine + count - 1); 466 if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 ) 467 { 468 if ( 0 != nIndex && 469 (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') ) 470 idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(), 471 "nested documentation strings are not allowed!"); 472 } 473 idlc()->setDocumentation(docu); 474 BEGIN( INITIAL ); 475 } 476 477"//"[^/]{1}.*"\n" { 478 /* only a comment */ 479 ::rtl::OString docStr(yytext); 480 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') ); 481 docStr = docStr.copy( docStr.lastIndexOf('/')+1 ); 482 docStr = docStr.trim(); 483 idlc()->incLineNumber(); 484 } 485 486"///".*"\n" { 487 ::rtl::OString docStr(yytext); 488 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') ); 489 docStr = docStr.copy( docStr.lastIndexOf('/')+1 ); 490 docStr = docStr.trim(); 491 idlc()->incLineNumber(); 492 idlc()->setDocumentation(docStr); 493 } 494 495. return yytext[0]; 496 497^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n { 498 parseLineAndFile(yytext); 499} 500 501^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n { 502 parseLineAndFile(yytext); 503} 504 505^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n { 506 parseLineAndFile(yytext); 507} 508 509^#[ \t]*[0-9]*\n { 510 parseLineAndFile(yytext); 511} 512 513^#[ \t]*ident.*\n { 514 /* ignore cpp ident */ 515 idlc()->incLineNumber(); 516} 517 518^#[ \t]*pragma[ \t].*\n { /* remember pragma */ 519 idlParsePragma(yytext); 520 idlc()->incLineNumber(); 521} 522 523%% 524