/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: scanner.ll,v $ * * $Revision: 1.14 $ * * last change: $Author: rt $ $Date: 2005-09-07 18:13:18 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ %{ /* * scanner.ll - Lexical scanner for IDLC 1.0 */ #include #include #ifndef _IDLC_IDLC_HXX_ #include #endif #ifndef _IDLC_ERRORHANDLER_HXX_ #include #endif #ifndef _IDLC_FEHELPER_HXX_ #include #endif #include "attributeexceptions.hxx" class AstExpression; class AstArray; class AstMember; #include sal_Int32 beginLine = 0; ::rtl::OString docu; static sal_Int64 asciiToInteger( sal_Int8 base, const sal_Char *s ) { sal_Int64 r = 0; sal_Int64 negative = 0; if (*s == '-') { negative = 1; s++; } if (base == 8 && *s == '0') s++; else if (base == 16 && *s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) s += 2; for (; *s; s++) { if (*s <= '9' && *s >= '0') r = (r * base) + (*s - '0'); else if (base > 10 && *s <= 'f' && *s >= 'a') r = (r * base) + (*s - 'a' + 10); else if (base > 10 && *s <= 'F' && *s >= 'A') r = (r * base) + (*s - 'A' + 10); else break; } if (negative) r *= -1; return r; } static double asciiToFloat(const sal_Char *s) { sal_Char *h = (sal_Char*)s; double d = 0.0; double f = 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)asciiToInteger(10, 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); } %} %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)? { yylval.ival = asciiToInteger( 10, yytext ); return IDL_INTEGER_LITERAL; } ("-")?{OCT_LITERAL}+(l|L|u|U)? { yylval.ival = asciiToInteger( 8, yytext+1 ); return IDL_INTEGER_LITERAL; } ("-")?{HEX_LITERAL}+(l|L|u|U)? { yylval.ival = asciiToInteger( 16, yytext+2 ); return IDL_INTEGER_LITERAL; } ("-")?{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(); } [^*]+ { docu += ::rtl::OString(yytext); } "*"[^*/]+ { docu += ::rtl::OString(yytext); } "**" { docu += ::rtl::OString(yytext); } [*]+"/" { 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(); } [^*\n]+ { docu += ::rtl::OString(yytext); } "\n"[ \t]*"*"{1} { idlc()->setLineNumber( idlc()->getLineNumber() + 1); docu += ::rtl::OString("\n"); } "\n" { idlc()->setLineNumber( idlc()->getLineNumber() + 1); docu += ::rtl::OString(yytext); } "*"[^*^/\n]* { docu += ::rtl::OString(yytext); } "\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.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(); } %%