| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| %{ |
| /* |
| * scanner.ll - Lexical scanner for IDLC 1.0 |
| */ |
| |
| #include <ctype.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #ifndef _IDLC_IDLC_HXX_ |
| #include <idlc/idlc.hxx> |
| #endif |
| #ifndef _IDLC_ERRORHANDLER_HXX_ |
| #include <idlc/errorhandler.hxx> |
| #endif |
| #ifndef _IDLC_FEHELPER_HXX_ |
| #include <idlc/fehelper.hxx> |
| #endif |
| |
| #include "attributeexceptions.hxx" |
| |
| class AstExpression; |
| class AstArray; |
| class AstMember; |
| |
| #include <parser.hxx> |
| |
| sal_Int32 beginLine = 0; |
| ::rtl::OString docu; |
| |
| static int asciiToInteger(char const * s, sal_Int64 * sval, sal_uInt64 * uval) { |
| bool neg = false; |
| if (*s == '-') { |
| neg = true; |
| ++s; |
| } |
| unsigned int base = 10; |
| if (*s == '0') { |
| base = 8; |
| ++s; |
| if (*s == 'X' || *s == 'x') { |
| base = 16; |
| ++s; |
| } |
| } |
| sal_uInt64 val = 0; |
| for (; *s != 0; ++s) { |
| unsigned int n; |
| if (*s >= '0' && *s <= '9') { |
| n = *s - '0'; |
| } else { |
| switch (*s) { |
| case 'A': |
| case 'a': |
| n = 10; |
| break; |
| case 'B': |
| case 'b': |
| n = 11; |
| break; |
| case 'C': |
| case 'c': |
| n = 12; |
| break; |
| case 'D': |
| case 'd': |
| n = 13; |
| break; |
| case 'E': |
| case 'e': |
| n = 14; |
| break; |
| case 'F': |
| case 'f': |
| n = 15; |
| break; |
| default: |
| goto done; |
| } |
| } |
| // The following guarantees the invariant val <= SAL_MAX_UINT64 (because |
| // base and n are sufficiently small), *if* |
| // std::numeric_limits<sal_uInt64>::max() == SAL_MAX_UINT64: |
| sal_uInt64 nval = val * base + n; |
| if (nval < val) { |
| idlc()->error()->syntaxError( |
| PS_NoState, idlc()->getLineNumber(), |
| "integral constant too large"); |
| val = 0; |
| break; |
| } |
| val = nval; |
| } |
| done: |
| if (neg) { |
| if (val < SAL_CONST_UINT64(0x8000000000000000)) { |
| *sval = -static_cast< sal_Int64 >(val); |
| } else if (val == SAL_CONST_UINT64(0x8000000000000000)) { |
| *sval = SAL_MIN_INT64; |
| } else { |
| idlc()->error()->syntaxError( |
| PS_NoState, idlc()->getLineNumber(), |
| "negative integral constant too large"); |
| *sval = 0; |
| } |
| return IDL_INTEGER_LITERAL; |
| } else if (val <= static_cast< sal_uInt64 >(SAL_MAX_INT64)) { |
| *sval = static_cast< sal_Int64 >(val); |
| return IDL_INTEGER_LITERAL; |
| } else { |
| *uval = val; |
| return IDL_INTEGER_ULITERAL; |
| } |
| } |
| |
| static double asciiToFloat(const sal_Char *s) |
| { |
| double d = 0.0; |
| double e, k; |
| sal_Int32 neg = 0, negexp = 0; |
| |
| if (*s == '-') |
| { |
| neg = 1; |
| s++; |
| } |
| while (*s >= '0' && *s <= '9') |
| { |
| d = (d * 10) + *s - '0'; |
| s++; |
| } |
| if (*s == '.') |
| { |
| s++; |
| e = 10; |
| while (*s >= '0' && *s <= '9') |
| { |
| d += (*s - '0') / (e * 1.0); |
| e *= 10; |
| s++; |
| } |
| } |
| if (*s == 'e' || *s == 'E') |
| { |
| s++; |
| if (*s == '-') |
| { |
| negexp = 1; |
| s++; |
| } else |
| { |
| if (*s == '+') |
| s++; |
| e = 0; |
| while (*s >= '0' && *s <= '9') |
| { |
| e = (e * 10) + *s - '0'; |
| s++; |
| } |
| if (e > 0) |
| { |
| for (k = 1; e > 0; k *= 10, e--) ; |
| if (negexp) |
| d /= k; |
| else |
| d *= k; |
| } |
| } |
| } |
| if (neg) d *= -1.0; |
| return d; |
| } |
| |
| static void idlParsePragma(sal_Char* pPragma) |
| { |
| ::rtl::OString pragma(pPragma); |
| sal_Int32 index = pragma.indexOf("include"); |
| sal_Char* begin = pPragma + index + 8; |
| sal_Char* offset = begin; |
| while (*offset != ',') offset++; |
| //::rtl::OString include = pragma.copy(index + 8, offset - begin); |
| idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin))); |
| } |
| |
| static void parseLineAndFile(sal_Char* pBuf) |
| { |
| sal_Char *r = pBuf; |
| sal_Char *h; |
| sal_Bool bIsInMain = sal_False; |
| |
| /* Skip initial '#' */ |
| if (*r != '#') |
| return; |
| |
| /* Find line number */ |
| for (r++; *r == ' ' || *r == '\t' || isalpha(*r); r++) ; |
| h = r; |
| for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ; |
| *r++ = 0; |
| idlc()->setLineNumber((sal_uInt32)atol(h)); |
| |
| /* Find file name, if present */ |
| for (; *r != '"'; r++) |
| { |
| if (*r == '\n' || *r == '\0') |
| return; |
| } |
| h = ++r; |
| for (; *r != '"'; r++) ; |
| *r = 0; |
| if (*h == '\0') |
| idlc()->setFileName(::rtl::OString("standard input")); |
| else |
| idlc()->setFileName(::rtl::OString(h)); |
| |
| bIsInMain = (idlc()->getFileName() == idlc()->getRealFileName()) ? sal_True : sal_False; |
| idlc()->setInMainfile(bIsInMain); |
| } |
| |
| // Suppress any warnings from generated code: |
| #if defined __GNUC__ |
| #pragma GCC system_header |
| #elif defined __SUNPRO_CC |
| #pragma disable_warn |
| #elif defined _MSC_VER |
| #pragma warning(push, 1) |
| /**/ |
| #ifdef yywrap |
| #undef yywrap |
| #define yywrap() 1 |
| #endif |
| /**/ |
| #endif |
| %} |
| |
| %option noyywrap |
| %option never-interactive |
| |
| %x DOCU |
| %x COMMENT |
| |
| DIGIT [0-9] |
| OCT_DIGIT [0-7] |
| HEX_DIGIT [a-fA-F0-9] |
| CAPITAL [A-Z] |
| ALPHA [a-zA-Z] |
| INT_LITERAL [1-9][0-9]* |
| OCT_LITERAL 0{OCT_DIGIT}* |
| HEX_LITERAL (0x|0X){HEX_DIGIT}* |
| |
| IDENTIFIER_NEW ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*) |
| IDENTIFIER ("_"?({ALPHA}|{DIGIT})+)* |
| |
| %% |
| |
| [ \t\r]+ ; /* eat up whitespace */ |
| [\n] { |
| idlc()->incLineNumber(); |
| } |
| |
| attribute return IDL_ATTRIBUTE; |
| bound return IDL_BOUND; |
| case return IDL_CASE; |
| const return IDL_CONST; |
| constants return IDL_CONSTANTS; |
| constrained return IDL_CONSTRAINED; |
| default return IDL_DEFAULT; |
| enum return IDL_ENUM; |
| exception return IDL_EXCEPTION; |
| interface return IDL_INTERFACE; |
| maybeambiguous return IDL_MAYBEAMBIGUOUS; |
| maybedefault return IDL_MAYBEDEFAULT; |
| maybevoid return IDL_MAYBEVOID; |
| module return IDL_MODULE; |
| needs return IDL_NEEDS; |
| observes return IDL_OBSERVES; |
| optional return IDL_OPTIONAL; |
| property return IDL_PROPERTY; |
| raises return IDL_RAISES; |
| readonly return IDL_READONLY; |
| removable return IDL_REMOVEABLE; |
| service return IDL_SERVICE; |
| sequence return IDL_SEQUENCE; |
| singleton return IDL_SINGLETON; |
| struct return IDL_STRUCT; |
| switch return IDL_SWITCH; |
| transient return IDL_TRANSIENT; |
| typedef return IDL_TYPEDEF; |
| union return IDL_UNION; |
| |
| any return IDL_ANY; |
| boolean return IDL_BOOLEAN; |
| byte return IDL_BYTE; |
| char return IDL_CHAR; |
| double return IDL_DOUBLE; |
| float return IDL_FLOAT; |
| hyper return IDL_HYPER; |
| long return IDL_LONG; |
| short return IDL_SHORT; |
| string return IDL_STRING; |
| type return IDL_TYPE; |
| unsigned return IDL_UNSIGNED; |
| void return IDL_VOID; |
| |
| TRUE return IDL_TRUE; |
| True return IDL_TRUE; |
| FALSE return IDL_FALSE; |
| False return IDL_FALSE; |
| |
| in return IDL_IN; |
| out return IDL_OUT; |
| inout return IDL_INOUT; |
| oneway return IDL_ONEWAY; |
| |
| get return IDL_GET; |
| set return IDL_SET; |
| |
| published return IDL_PUBLISHED; |
| |
| "..." return IDL_ELLIPSIS; |
| |
| ("-")?{INT_LITERAL}+(l|L|u|U)? { |
| return asciiToInteger(yytext, &yylval.ival, &yylval.uval); |
| } |
| |
| ("-")?{OCT_LITERAL}+(l|L|u|U)? { |
| return asciiToInteger(yytext, &yylval.ival, &yylval.uval); |
| } |
| |
| ("-")?{HEX_LITERAL}+(l|L|u|U)? { |
| return asciiToInteger(yytext, &yylval.ival, &yylval.uval); |
| } |
| |
| ("-")?{DIGIT}+(e|E){1}(("+"|"-")?{DIGIT}+)+(f|F)? | |
| ("-")?"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? | |
| ("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? { |
| yylval.dval = asciiToFloat( yytext ); |
| return IDL_FLOATING_PT_LITERAL; |
| } |
| |
| {IDENTIFIER} { |
| yylval.sval = new ::rtl::OString(yytext); |
| return IDL_IDENTIFIER; |
| } |
| |
| \<\< { |
| yylval.strval = yytext; |
| return IDL_LEFTSHIFT; |
| } |
| \>\> { |
| yylval.strval = yytext; |
| return IDL_RIGHTSHIFT; |
| } |
| \:\: { |
| yylval.strval = yytext; |
| return IDL_SCOPESEPARATOR; |
| } |
| |
| "/*" { |
| BEGIN( COMMENT ); |
| docu = ::rtl::OString(); |
| beginLine = idlc()->getLineNumber(); |
| } |
| |
| "/***" { |
| BEGIN( COMMENT ); |
| docu = ::rtl::OString(); |
| beginLine = idlc()->getLineNumber(); |
| } |
| |
| <COMMENT>[^*]+ { |
| docu += ::rtl::OString(yytext); |
| } |
| |
| <COMMENT>"*"[^*/]+ { |
| docu += ::rtl::OString(yytext); |
| } |
| |
| <COMMENT>"**" { |
| docu += ::rtl::OString(yytext); |
| } |
| |
| <COMMENT>[*]+"/" { |
| docu = docu.trim(); |
| sal_Int32 nIndex = 0; |
| int count = 0; |
| do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 ); |
| idlc()->setLineNumber( beginLine + count - 1); |
| BEGIN( INITIAL ); |
| } |
| |
| "/**" { |
| BEGIN( DOCU ); |
| docu = ::rtl::OString(); |
| beginLine = idlc()->getLineNumber(); |
| } |
| |
| <DOCU>[^*\n]+ { |
| docu += ::rtl::OString(yytext); |
| } |
| |
| <DOCU>"\n"[ \t]*"*"{1} { |
| idlc()->setLineNumber( idlc()->getLineNumber() + 1); |
| docu += ::rtl::OString("\n"); |
| } |
| |
| <DOCU>"\n" { |
| idlc()->setLineNumber( idlc()->getLineNumber() + 1); |
| docu += ::rtl::OString(yytext); |
| } |
| |
| <DOCU>"*"[^*^/\n]* { |
| docu += ::rtl::OString(yytext); |
| } |
| |
| <DOCU>"\n"[ \t]*"*/" { |
| docu = docu.trim(); |
| sal_Int32 nIndex = 0; |
| int count = 0; |
| do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 ); |
| idlc()->setLineNumber( beginLine + count - 1); |
| if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 ) |
| { |
| if ( 0 != nIndex && |
| (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') ) |
| idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(), |
| "nested documentation strings are not allowed!"); |
| } |
| idlc()->setDocumentation(docu); |
| BEGIN( INITIAL ); |
| } |
| |
| <DOCU>"*/" { |
| docu = docu.trim(); |
| sal_Int32 nIndex = 0; |
| int count = 0; |
| do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 ); |
| idlc()->setLineNumber( beginLine + count - 1); |
| if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 ) |
| { |
| if ( 0 != nIndex && |
| (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') ) |
| idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(), |
| "nested documentation strings are not allowed!"); |
| } |
| idlc()->setDocumentation(docu); |
| BEGIN( INITIAL ); |
| } |
| |
| "//"[^/]{1}.*"\n" { |
| /* only a comment */ |
| ::rtl::OString docStr(yytext); |
| docStr = docStr.copy( 0, docStr.lastIndexOf('\n') ); |
| docStr = docStr.copy( docStr.lastIndexOf('/')+1 ); |
| docStr = docStr.trim(); |
| idlc()->incLineNumber(); |
| } |
| |
| "///".*"\n" { |
| ::rtl::OString docStr(yytext); |
| docStr = docStr.copy( 0, docStr.lastIndexOf('\n') ); |
| docStr = docStr.copy( docStr.lastIndexOf('/')+1 ); |
| docStr = docStr.trim(); |
| idlc()->incLineNumber(); |
| idlc()->setDocumentation(docStr); |
| } |
| |
| . return yytext[0]; |
| |
| ^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n { |
| parseLineAndFile(yytext); |
| } |
| |
| ^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n { |
| parseLineAndFile(yytext); |
| } |
| |
| ^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n { |
| parseLineAndFile(yytext); |
| } |
| |
| ^#[ \t]*[0-9]*\n { |
| parseLineAndFile(yytext); |
| } |
| |
| ^#[ \t]*ident.*\n { |
| /* ignore cpp ident */ |
| idlc()->incLineNumber(); |
| } |
| |
| ^#[ \t]*pragma[ \t].*\n { /* remember pragma */ |
| idlParsePragma(yytext); |
| idlc()->incLineNumber(); |
| } |
| |
| %% |