Synopsis - Cross-Reference
File: /Synopsis/Parsers/IDL/idl.ll1%{ // -*- c++ -*- 2// Package : omniidl 3// idl.ll Created on: 1999/10/05 4// Author : Duncan Grisby (dpg1) 5// 6// Copyright (C) 1999 AT&T Laboratories Cambridge 7// 8// This file is part of omniidl. 9// 10// omniidl is free software; you can redistribute it and/or modify it 11// under the terms of the GNU General Public License as published by 12// the Free Software Foundation; either version 2 of the License, or 13// (at your option) any later version. 14// 15// This program 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 GNU 18// General Public License for more details. 19// 20// You should have received a copy of the GNU General Public License 21// along with this program; if not, write to the Free Software 22// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 23// 02111-1307, USA. 24// 25// Description: 26// 27// Flex lexical analyser 28 29// $Id: idl.ll,v 1.13.2.2 2005/01/06 23:11:14 dgrisby Exp $ 30// $Log: idl.ll,v $ 31// Revision 1.13.2.2 2005/01/06 23:11:14 dgrisby 32// Big merge from omni4_0_develop. 33// 34// Revision 1.13.2.1 2003/03/23 21:01:48 dgrisby 35// Start of omniORB 4.1.x development branch. 36// 37// Revision 1.9.2.8 2001/10/22 10:48:22 dpg1 38// Cope with DOS line endings in all IDL situations. 39// 40// Revision 1.9.2.7 2001/10/17 16:48:32 dpg1 41// Minor error message tweaks 42// 43// Revision 1.9.2.6 2001/06/13 11:28:20 dpg1 44// Proper omniidl support for wchar/wstring constants. 45// 46// Revision 1.9.2.5 2001/03/13 10:32:10 dpg1 47// Fixed point support. 48// 49// Revision 1.9.2.4 2000/11/01 12:45:55 dpg1 50// Update to CORBA 2.4 specification. 51// 52// Revision 1.9.2.3 2000/10/27 16:31:07 dpg1 53// Clean up of omniidl dependencies and types, from omni3_develop. 54// 55// Revision 1.9.2.2 2000/10/10 10:18:50 dpg1 56// Update omniidl front-end from omni3_develop. 57// 58// Revision 1.7.2.8 2000/08/07 15:34:35 dpg1 59// Partial back-port of long long from omni3_1_develop. 60// 61// Revision 1.7.2.7 2000/06/09 11:20:47 dpg1 62// Last fix put __omni_pragma line numbers off by one... 63// 64// Revision 1.7.2.6 2000/06/08 14:58:19 dpg1 65// Line numbers for #pragmas and // comments were off by one 66// 67// Revision 1.7.2.5 2000/06/08 14:36:19 dpg1 68// Comments and pragmas are now objects rather than plain strings, so 69// they can have file,line associated with them. 70// 71// Revision 1.7.2.4 2000/06/05 18:12:25 dpg1 72// Support for __omni_pragma 73// 74// Revision 1.7.2.3 2000/04/26 09:55:48 dpg1 75// cccp escapes characters like \ in line directives, so 76// parseLineDirective() needs to use escapedStringToString(). 77// 78// Revision 1.7.2.2 2000/03/06 15:03:49 dpg1 79// Minor bug fixes to omniidl. New -nf and -k flags. 80// 81// Revision 1.7.2.1 2000/02/16 16:30:54 dpg1 82// #pragma ID was misspelled #pragma id. Oops. 83// 84// Revision 1.7 2000/02/04 12:17:10 dpg1 85// Support for VMS. 86// 87// Revision 1.6 1999/12/28 17:44:01 dpg1 88// Stupid string allocation bug. 89// 90// Revision 1.5 1999/11/19 16:03:40 dpg1 91// Flex scanner now accepts \r as whitespace. 92// 93// Revision 1.4 1999/11/05 10:36:42 dpg1 94// Sorted out isatty() problems. 95// 96// Revision 1.3 1999/11/02 17:07:28 dpg1 97// Changes to compile on Solaris. 98// 99// Revision 1.2 1999/11/01 10:05:00 dpg1 100// New file attribute to AST. 101// 102// Revision 1.1 1999/10/27 14:06:00 dpg1 103// *** empty log message *** 104// 105 106#define YY_NEVER_INTERACTIVE 1 107 108#include <stdlib.h> 109#include <string.h> 110#include <ctype.h> 111#include <errno.h> 112 113#include <idlerr.h> 114#include <idlutil.h> 115#include <idlrepoId.h> 116#include <idlscope.h> 117#include <idlexpr.h> 118#include <idlast.h> 119 120#include <y.tab.h> 121 122char* currentFile; 123IDL_Boolean mainFile = 1; // Are we processing the main file 124int nestDepth = 0; // #include nesting depth 125 126char octalToChar(char* s); 127char hexToChar(char* s); 128char escapeToChar(char* s); 129IDL_UShort octalToWChar(char* s); 130IDL_UShort hexToWChar(char* s); 131IDL_UShort escapeToWChar(char* s); 132char* escapedStringToString(char* s); 133IDL_UShort* escapedStringToWString(char* s); 134void parseLineDirective(char* s); 135 136%} 137 138%option noyywrap 139%option yylineno 140 141%x comment 142%s known_pragma 143%x unknown_pragma 144%x omni_pragma 145 146WS [ \t\v\n\f\r] 147SPACE [ \t] 148 149ASCIILETTER [a-zA-Z] 150IDCHAR [a-zA-Z0-9_] 151IDENT ({ASCIILETTER}{IDCHAR}*) 152 153DECDIGIT [0-9] 154DECSTART [1-9] 155OCTSTART 0 156OCTDIGIT [0-7] 157HEXSTART (0[xX]) 158HEXDIGIT [0-9a-fA-F] 159 160EXPONENT ([Ee][+-]?{DECDIGIT}+) 161 162STR (\"([^\"]|\\\")*\") 163 164%% 165 166abstract return ABSTRACT; 167any return ANY; 168attribute return ATTRIBUTE; 169boolean return BOOLEAN; 170case return CASE; 171char return CHAR; 172const return CONST; 173context return CONTEXT; 174custom return CUSTOM; 175default return DEFAULT; 176double return DOUBLE; 177enum return ENUM; 178exception return EXCEPTION; 179factory return FACTORY; 180FALSE return FALSE_; 181fixed return FIXED; 182float return FLOAT; 183in return IN; 184inout return INOUT; 185interface return INTERFACE; 186local return LOCAL; 187long return LONG; 188module return MODULE; 189native return NATIVE; 190Object return OBJECT; 191octet return OCTET; 192oneway return ONEWAY; 193out return OUT; 194private return PRIVATE; 195public return PUBLIC; 196raises return RAISES; 197readonly return READONLY; 198sequence return SEQUENCE; 199short return SHORT; 200string return STRING; 201struct return STRUCT; 202supports return SUPPORTS; 203switch return SWITCH; 204TRUE return TRUE_; 205truncatable return TRUNCATABLE; 206typedef return TYPEDEF; 207union return UNION; 208unsigned return UNSIGNED; 209ValueBase return VALUEBASE; 210valuetype return VALUETYPE; 211void return VOID; 212wchar return WCHAR; 213wstring return WSTRING; 214 215"<<" return LEFT_SHIFT; 216">>" return RIGHT_SHIFT; 217"::" return SCOPE_DELIM; 218 219{IDENT} { 220 yylval.id_val = idl_strdup(yytext); 221 return IDENTIFIER; 222} 223 224_{IDENT} { 225 yylval.id_val = idl_strdup(yytext); 226 return IDENTIFIER; 227} 228 229{DECSTART}{DECDIGIT}* { 230 errno = 0; 231 yylval.int_literal_val = idl_strtoul(yytext, 10); 232 if (errno == ERANGE) { 233 IdlError(currentFile, yylineno, 234 "Integer literal '%s' is too big", yytext); 235 } 236 return INTEGER_LITERAL; 237} 238 239{OCTSTART}{OCTDIGIT}+ { 240 errno = 0; 241 yylval.int_literal_val = idl_strtoul(yytext, 8); 242 if (errno == ERANGE) { 243 IdlError(currentFile, yylineno, 244 "Integer literal '%s' is too big", yytext); 245 } 246 return INTEGER_LITERAL; 247} 248 249{HEXSTART}{HEXDIGIT}+ { 250 errno = 0; 251 yylval.int_literal_val = idl_strtoul(yytext, 16); 252 if (errno == ERANGE) { 253 IdlError(currentFile, yylineno, 254 "Integer literal '%s' is too big", yytext); 255 } 256 return INTEGER_LITERAL; 257} 258 259"0" { 260 yylval.int_literal_val = 0; 261 return INTEGER_LITERAL; 262} 263 264"'"."'" { 265 yylval.char_val = yytext[1]; 266 return CHARACTER_LITERAL; 267} 268 269"'"\\([0-7]{1,3})"'" { 270 yytext[yyleng-1] = '\0'; 271 yylval.char_val = octalToChar(yytext + 1); 272 return CHARACTER_LITERAL; 273} 274 275"'"\\x({HEXDIGIT}{1,2})"'" { 276 yytext[yyleng-1] = '\0'; 277 yylval.char_val = hexToChar(yytext + 1); 278 return CHARACTER_LITERAL; 279} 280 281"'"\\u({HEXDIGIT}{1,4})"'" { 282 IdlError(currentFile, yylineno, 283 "\\u may only be used in wide characters and strings"); 284 yylval.char_val = 0; 285 return CHARACTER_LITERAL; 286} 287 288"'"\\."'" { 289 yytext[yyleng-1] = '\0'; 290 yylval.char_val = escapeToChar(yytext + 1); 291 return CHARACTER_LITERAL; 292} 293 294L"'"."'" { 295 yylval.wchar_val = yytext[2]; 296 return WIDE_CHARACTER_LITERAL; 297} 298 299L"'"\\([0-7]{1,3})"'" { 300 yytext[yyleng-1] = '\0'; 301 yylval.wchar_val = octalToWChar(yytext + 2); 302 return WIDE_CHARACTER_LITERAL; 303} 304 305L"'"\\x({HEXDIGIT}{1,2})"'" { 306 yytext[yyleng-1] = '\0'; 307 yylval.wchar_val = hexToWChar(yytext + 2); 308 return WIDE_CHARACTER_LITERAL; 309} 310 311L"'"\\u({HEXDIGIT}{1,4})"'" { 312 yytext[yyleng-1] = '\0'; 313 yylval.wchar_val = hexToWChar(yytext + 2); 314 return WIDE_CHARACTER_LITERAL; 315} 316 317L"'"\\."'" { 318 yytext[yyleng-1] = '\0'; 319 yylval.wchar_val = escapeToWChar(yytext + 2); 320 return WIDE_CHARACTER_LITERAL; 321} 322 323<INITIAL>{DECDIGIT}+{EXPONENT} { 324 // Only deal with floats in INITIAL state, so version pragmas don't 325 // get interpreted as floats. 326 yylval.float_literal_val = idl_strtod(yytext); 327 return FLOATING_PT_LITERAL; 328} 329 330<INITIAL>{DECDIGIT}*"."{DECDIGIT}+{EXPONENT}? { 331 yylval.float_literal_val = idl_strtod(yytext); 332 return FLOATING_PT_LITERAL; 333} 334 335<INITIAL>{DECDIGIT}+"."{DECDIGIT}*{EXPONENT}? { 336 yylval.float_literal_val = idl_strtod(yytext); 337 return FLOATING_PT_LITERAL; 338} 339 340{STR} { 341 yytext[yyleng-1] = '\0'; 342 yylval.string_val = escapedStringToString(yytext + 1); 343 return STRING_LITERAL; 344} 345 346L{STR} { 347 yytext[yyleng-1] = '\0'; 348 yylval.wstring_val = escapedStringToWString(yytext + 2); 349 return WIDE_STRING_LITERAL; 350} 351 352{DECDIGIT}+"."{DECDIGIT}*[dD] { 353 yylval.fixed_val = new IDL_Fixed(yytext, currentFile, yylineno); 354 return FIXED_PT_LITERAL; 355} 356 357{DECDIGIT}*"."{DECDIGIT}+[dD] { 358 yylval.fixed_val = new IDL_Fixed(yytext, currentFile, yylineno); 359 return FIXED_PT_LITERAL; 360} 361 362{DECDIGIT}+[dD] { 363 yylval.fixed_val = new IDL_Fixed(yytext, currentFile, yylineno); 364 return FIXED_PT_LITERAL; 365} 366 367"//".*\n { Comment::add(yytext, currentFile, yylineno-1); } 368 369"/*" { 370 Comment::add(yytext, currentFile, yylineno); 371 BEGIN(comment); 372} 373 374<comment>[^*\n]* { Comment::append(yytext); } 375<comment>"*"+[^*/\n]* { Comment::append(yytext); } 376<comment>\n { Comment::append(yytext); } 377<comment>"*"+"/" { Comment::append(yytext); BEGIN(INITIAL); } 378 379"__omni_pragma"{WS}+ { 380 BEGIN(omni_pragma); 381 return OMNI_PRAGMA; 382} 383 384<omni_pragma>{WS}+"__omni_endpragma" { 385 BEGIN(INITIAL); 386 return END_PRAGMA; 387} 388 389<omni_pragma>[^ \t\v\n\f\r]+ { 390 yylval.string_val = idl_strdup(yytext); 391 return UNKNOWN_PRAGMA_BODY; 392} 393<omni_pragma>{WS}+ { 394 yylval.string_val = idl_strdup(yytext); 395 return UNKNOWN_PRAGMA_BODY; 396} 397 398 399^{SPACE}*#{SPACE}*pragma{SPACE}*prefix{SPACE}* { 400 BEGIN(known_pragma); 401 return PRAGMA_PREFIX; 402} 403 404^{SPACE}*#{SPACE}*pragma{SPACE}*ID{SPACE}* { 405 BEGIN(known_pragma); 406 return PRAGMA_ID; 407} 408 409^{SPACE}*#{SPACE}*pragma{SPACE}*version{SPACE}* { 410 BEGIN(known_pragma); 411 return PRAGMA_VERSION; 412} 413 414<known_pragma>{SPACE}+ { /* Eat spaces and tabs */ } 415 416^{SPACE}*#{SPACE}*pragma{SPACE}* { 417 BEGIN(unknown_pragma); 418 return PRAGMA; 419} 420 421<unknown_pragma>([^\\\n\r]|(\\[^\n\r]))+ { 422 yylval.string_val = idl_strdup(yytext); 423 return UNKNOWN_PRAGMA_BODY; 424} 425 426<INITIAL,known_pragma,unknown_pragma>\\(\n|(\r\n)) { 427 /* Continue line if it ends with \ */ 428} 429 430<known_pragma,unknown_pragma>\n|(\r\n) { 431 BEGIN(INITIAL); 432 return END_PRAGMA; 433} 434 435^{SPACE}*#{SPACE}*{DECDIGIT}+{SPACE}+{STR}{SPACE}+{DECDIGIT}*{SPACE}*\n { 436 parseLineDirective(yytext); 437} 438 439^{SPACE}*#{SPACE}*{DECDIGIT}+{SPACE}+{STR}{SPACE}*\n { 440 parseLineDirective(yytext); 441} 442 443^{SPACE}*#{SPACE}*{DECDIGIT}{SPACE}*\n { 444 parseLineDirective(yytext); 445} 446 447^{SPACE}*#line{SPACE}*{DECDIGIT}+{SPACE}+{STR}{SPACE}+{DECDIGIT}*{SPACE}*\n { 448 parseLineDirective(yytext); 449} 450 451^{SPACE}*#line{SPACE}*{DECDIGIT}+{SPACE}+{STR}{SPACE}*\n { 452 parseLineDirective(yytext); 453} 454 455^{SPACE}*#line{SPACE}*{DECDIGIT}{SPACE}*\n { 456 parseLineDirective(yytext); 457} 458 459<INITIAL>{WS} { /* Eat white space */ } 460 461. { 462 return yytext[0]; 463} 464 465%% 466 467char octalToChar(char* s) { 468 unsigned long ret = strtoul(s+1, 0, 8); 469 470 if (ret > 255) { 471 IdlError(currentFile, yylineno, "Octal character value '%s' too big", s); 472 } 473 474 return ret; 475} 476 477char hexToChar(char* s) { 478 unsigned long ret = strtoul(s+2, 0, 16); 479 480 return ret; 481} 482 483char escapeToChar(char* s) { 484 switch (s[1]) { 485 case 'n': return '\n'; 486 case 't': return '\t'; 487 case 'v': return '\v'; 488 case 'b': return '\b'; 489 case 'r': return '\r'; 490 case 'f': return '\f'; 491 case 'a': return '\a'; 492 case '\\': return '\\'; 493 case '?': return '?'; 494 case '\'': return '\''; 495 case '\"': return '\"'; 496 } 497 IdlWarning(currentFile, yylineno, 498 "Behaviour for escape sequence '%s' is undefined by IDL; " 499 "using '%c'", s, s[1]); 500 return s[1]; 501} 502 503IDL_UShort octalToWChar(char* s) { 504 unsigned long ret = strtoul(s+1, 0, 8); 505 506 if (ret > 255) { // This really is meant to be 255 507 IdlError(currentFile, yylineno, "Octal character value '%s' too big", s); 508 } 509 510 return ret; 511} 512 513IDL_UShort hexToWChar(char* s) { 514 unsigned long ret = strtoul(s+2, 0, 16); 515 516 return ret; 517} 518 519IDL_UShort escapeToWChar(char* s) { 520 switch (s[1]) { 521 case 'n': return '\n'; 522 case 't': return '\t'; 523 case 'v': return '\v'; 524 case 'b': return '\b'; 525 case 'r': return '\r'; 526 case 'f': return '\f'; 527 case 'a': return '\a'; 528 case '\\': return '\\'; 529 case '?': return '?'; 530 case '\'': return '\''; 531 case '\"': return '\"'; 532 } 533 IdlWarning(currentFile, yylineno, 534 "Behaviour for escape sequence '%s' is undefined by IDL; " 535 "using '%c'.", s, s[1]); 536 return s[1]; 537} 538 539char* escapedStringToString(char* s) { 540 int len = strlen(s); 541 char* ret = new char[len+1]; 542 char tmp[8]; 543 544 int from, to, i; 545 546 for (from=0, to=0; from < len; from++, to++) { 547 548 if (s[from] == '\\') { 549 tmp[0] = s[from++]; 550 551 if ('0' <= s[from] && s[from] <= '7') { 552 // Octal 553 for (i=1; 554 i < 4 && from < len && '0' <= s[from] && s[from] <= '7'; 555 from++, i++) tmp[i] = s[from]; 556 557 tmp[i] = '\0'; 558 ret[to] = octalToChar(tmp); 559 from--; 560 } 561 else if (s[from] == 'x') { 562 // Hex 563 tmp[1] = s[from++]; 564 for (i=2; i < 4 && from < len && isxdigit(s[from]); from++, i++) 565 tmp[i] = s[from]; 566 567 tmp[i] = '\0'; 568 ret[to] = hexToChar(tmp); 569 from--; 570 } 571 else if (s[from] == 'u') { 572 // Wide hex not allowed 573 IdlError(currentFile, yylineno, 574 "\\u may only be used in wide characters and strings"); 575 ret[to] = '!'; 576 } 577 else { 578 tmp[1] = s[from]; 579 tmp[2] = '\0'; 580 ret[to] = escapeToChar(tmp); 581 } 582 if (ret[to] == '\0') { 583 IdlError(currentFile, yylineno, "String cannot contain \\0"); 584 ret[to] = '!'; 585 } 586 } 587 else ret[to] = s[from]; 588 } 589 ret[to] = '\0'; 590 return ret; 591} 592 593IDL_UShort* escapedStringToWString(char* s) { 594 int len = strlen(s); 595 IDL_UShort* ret = new IDL_UShort[len+1]; 596 char tmp[8]; 597 598 int from, to, i; 599 600 for (from=0, to=0; from < len; from++, to++) { 601 602 if (s[from] == '\\') { 603 tmp[0] = s[from++]; 604 605 if ('0' <= s[from] && s[from] <= '7') { 606 // Octal 607 for (i=1; 608 i < 4 && from < len && '0' <= s[from] && s[from] <= '7'; 609 from++, i++) tmp[i] = s[from]; 610 611 tmp[i] = '\0'; 612 ret[to] = octalToWChar(tmp); 613 from--; 614 } 615 else if (s[from] == 'x') { 616 // Hex 617 tmp[1] = s[from++]; 618 for (i=2; i < 4 && from < len && isxdigit(s[from]); from++, i++) 619 tmp[i] = s[from]; 620 621 tmp[i] = '\0'; 622 ret[to] = hexToWChar(tmp); 623 from--; 624 } 625 else if (s[from] == 'u') { 626 // Wide hex 627 tmp[1] = s[from++]; 628 for (i=2; i < 6 && from < len && isxdigit(s[from]); from++, i++) 629 tmp[i] = s[from]; 630 631 tmp[i] = '\0'; 632 ret[to] = hexToWChar(tmp); 633 from--; 634 } 635 else { 636 tmp[1] = s[from]; 637 tmp[2] = '\0'; 638 ret[to] = escapeToWChar(tmp); 639 } 640 if (ret[to] == 0) { 641 IdlError(currentFile, yylineno, 642 "Wide string cannot contain wide character zero"); 643 ret[to] = '!'; 644 } 645 } 646 else 647 ret[to] = s[from]; 648 } 649 ret[to] = 0; 650 return ret; 651} 652 653void parseLineDirective(char* s) { 654 char* file = new char[strlen(s) + 1]; 655 long int line = 0, mode = 0; 656 int cnt = sscanf(s, "# %ld \"%[^\"]\" %ld", &line, file, &mode); 657 if (cnt == 0) 658 // Retry with a real "#line" directive. 659 cnt = sscanf(s, "#line %ld \"%[^\"]\" %ld", &line, file, &mode); 660 assert(cnt >= 1); 661 662 if (cnt > 1) { 663 if (cnt == 3) { 664 if (mode == 1) { 665 // New #included file 666 ++nestDepth; 667 mainFile = 0; 668 Prefix::newFile(); 669 } 670 else if (mode == 2) { 671 // Return from #include 672 if (--nestDepth == 0) mainFile = 1; 673 Prefix::endFile(); 674 } 675 } 676 delete [] currentFile; 677 // cccp escapes \ characters, so use the normal string parser 678 currentFile = escapedStringToString(file); 679 delete [] file; 680 if (mainFile) 681 AST::tree()->setFile(currentFile); 682 } 683 yylineno = line; 684}