diff options
Diffstat (limited to 'lexer.l')
-rw-r--r-- | lexer.l | 464 |
1 files changed, 464 insertions, 0 deletions
@@ -0,0 +1,464 @@ +/*************************************************************************** + + lexer.l (IDL lex scanner) + + Copyright (C) 1998, 1999 Andrew T. Veliath + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: lexer.l,v 1.83 2003/05/09 15:19:06 jody Exp $ + +***************************************************************************/ +%{ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <glib.h> +#include "rename.h" +#include "util.h" +#include "parser.h" + +#ifdef XP_MAC +# include <unix.h> +# define YY_NEVER_INTERACTIVE 1 +#endif + +/* Eliminate warning */ +#define YY_NO_UNPUT 1 + +#define YY_INPUT(buf,result,the_max_size) do { \ + if (__IDL_inputcb == NULL) { \ + if ((result = fread (buf, 1, the_max_size, yyin)) == YY_NULL && \ + ferror (yyin)) \ + YY_FATAL_ERROR ("input in scanner failed"); \ + } else { \ + union IDL_input_data data; \ + \ + data.fill.buffer = buf; \ + data.fill.max_size = the_max_size; \ + result = (*__IDL_inputcb) (IDL_INPUT_REASON_FILL, &data, \ + __IDL_inputcb_user_data); \ + if (result < 0) \ + YY_FATAL_ERROR ("input callback returned failure"); \ + } \ +} while (0) + +#define tokreturn(token) do { \ + __IDL_prev_token_line = __IDL_cur_token_line; \ + __IDL_cur_token_line = __IDL_cur_line; \ + return token; \ +} while (0) + +#define SELECT_START \ + /* Parser driven start conditions */ \ + if (__IDL_flagsi & IDLFP_PROPERTIES) \ + BEGIN (PROP); \ + else if (__IDL_flagsi & IDLFP_NATIVE) \ + BEGIN (NATIVE); \ + /* Global syntax start conditions */ \ + else if (__IDL_flags & IDLF_XPIDL) \ + BEGIN (XP); \ + else if (__IDL_flags & IDLF_CODEFRAGS) \ + BEGIN (CFRG); + +#define SELECT_RESTART \ + SELECT_START \ + else \ + BEGIN (INITIAL); + +static int count_nl (const char *s); + +static void IDL_parse_cpp_status(char *mytext) { + gint line; + + line = atoi (mytext); + + while (g_ascii_isdigit (*mytext)) + mytext++; + + if (g_ascii_isspace (*mytext)) { + mytext++; + + if (mytext [0] == '"') { + gchar *p = ++mytext; + + while (*p && *p != '"') p++; + + *p = '\0'; + } + + if (mytext [0] == '<' && + (!strcmp (mytext, "<builtin>") || + !strcmp (mytext, "<built-in>") || + !strcmp (mytext, "<stdin>") || + !strcmp (mytext, "<command-line>") || + !strcmp (mytext, "<command line>"))) + + yylval.tree = IDL_file_set ("", line); + else { + gchar *filename = g_strdup (mytext); +#ifdef G_OS_WIN32 + /* + * On Windows when using MSVC, the file name + * output by cl.exe may have "\\" as the path + * separator. We need to strip the extra '\' + * so we can compare to our internal file + * name. + */ + gchar *dst, *src; + for (dst = filename, src = mytext; + *src != '\0'; src++, dst++) { + if (*src == '\\' && *(src + 1) == '\\') { + src++; + } + *dst = *src; + } + *dst = '\0'; +#endif + + yylval.tree = IDL_file_set (filename, line); + + g_free (filename); + } + } + else + yylval.tree = IDL_file_set ("", line); +} + + +#ifdef YYDEBUG +extern int yydebug; +#endif +int __IDL_prev_token_line; +int __IDL_cur_token_line; +static int warn_underscores; +static char * codefrag_desc; +static GSList * codefrag_list; +static GSList * codefrag_list_tail; +%} + +whitespace [ \t\v\f\r]* +whitespacenl [ \t\v\f\r\n]* +newline \n +cpp_pragma ^{whitespace}#{whitespace}pragma{whitespace}.* +cpp_status ^{whitespace}#{whitespace}[0-9][0-9]*.* +cpp_status_ms ^{whitespace}#line{whitespace}[0-9][0-9]*.* +cpp_other ^{whitespace}#.* +b8_int 0[0-9]* +b10_uint [1-9][0-9]* +b16_int 0[xX][0-9A-Fa-f]+ +float_lit [0-9]*\.[0-9]+([eE]-?[0-9]+)?|[0-9]+\.?([eE]-?[0-9]+)? +fixed_lit ([0-9]*\.[0-9]+|-?[0-9]+\.?[0-9]*)[dD] +declspec __declspec{whitespacenl}\({whitespacenl}[A-Za-z]*{whitespacenl}\) +happy_ident [A-Za-z][A-Za-z0-9]* +escaped_ident _[A-Za-z0-9_]+ +warn1_ident [A-Za-z][A-Za-z0-9_]* +prop_key [A-Za-z][A-Za-z0-9_]* +prop_value \([^\)]+\) +native_type [^\)]+\) +sqstring \'[^\'\n]*[\'\n] +dqstring \"[^\"\n]*[\"\n] + +%p 5000 + +%s XP + +%x PROP +%x NATIVE + +%s CFRG +%x CFRGX + +%% + + SELECT_START; + +<INITIAL,XP,CFRG>^%\{.* { + char *s = yytext + 2; + + while (g_ascii_isspace (*s)) ++s; + codefrag_desc = g_strdup (s); + codefrag_list = codefrag_list_tail = NULL; + + if (!(__IDL_flags & IDLF_XPIDL || __IDL_flags & IDLF_CODEFRAGS)) + yyerror ("Code fragment syntax not enabled"); + else + BEGIN (CFRGX); +} +<CFRGX>^%\}.* { + yylval.tree = IDL_codefrag_new (codefrag_desc, codefrag_list); + tokreturn (TOK_CODEFRAG); +} +<CFRGX>.* { + char *s; + GSList *slist; + + s = g_strdup (yytext); + slist = g_slist_alloc (); + slist->data = s; + + if (codefrag_list == NULL) { + codefrag_list = slist; + codefrag_list_tail = slist; + } else { + codefrag_list_tail->next = slist; + codefrag_list_tail = slist; + } +} +<*>{cpp_pragma} { + int n; + char *p = yytext; + char *s, *t; + + while (g_ascii_isspace (*p) || *p == '#') ++p; + s = p; + sscanf (p, "%*6s%n", &n); s += n; + while (g_ascii_isspace (*s)) ++s; + + t = s + strlen(s) - 1; + while(g_ascii_isspace(*t) && t > s) *(t--) = '\0'; /* Chomp trailing spaces */ + + __IDL_do_pragma (s); +} +<*>{cpp_status} { + gchar *mytext = yytext; + + while (g_ascii_isspace (*mytext)) + mytext++; + + g_assert (mytext [0] == '#' && mytext [1] == ' '); + + mytext += 2; + IDL_parse_cpp_status(mytext); + if (yylval.tree) + tokreturn (TOK_SRCFILE); +} +<*>{cpp_status_ms} { + gchar *mytext = yytext; + + while (g_ascii_isspace (*mytext)) + mytext++; + + g_assert (mytext [0] == '#' && + mytext [1] == 'l' && + mytext [2] == 'i' && + mytext [3] == 'n' && + mytext [4] == 'e' && + g_ascii_isspace(mytext [5])); + + mytext += 6; + IDL_parse_cpp_status(mytext); + if (yylval.tree) + tokreturn (TOK_SRCFILE); +} +<*>{cpp_other} ; +<*>{whitespace} ; +{b8_int} { + yylval.integer = 0; + sscanf (yytext, "%" IDL_LL "o", &yylval.integer); + tokreturn (TOK_INTEGER); +} +{b10_uint} { + yylval.integer = 0; + sscanf (yytext, "%" IDL_LL "u", &yylval.integer); + tokreturn (TOK_INTEGER); +} +{b16_int} { + yylval.integer = 0; + sscanf (yytext + 2, "%" IDL_LL "x", &yylval.integer); + tokreturn (TOK_INTEGER); +} +{fixed_lit} { + yylval.str = g_strdup (yytext); + tokreturn (TOK_FIXEDP); +} +{float_lit} { + yylval.floatp = atof (yytext); + tokreturn (TOK_FLOATP); +} +FALSE tokreturn (TOK_FALSE); +TRUE tokreturn (TOK_TRUE); +any tokreturn (TOK_ANY); +attribute tokreturn (TOK_ATTRIBUTE); +boolean tokreturn (TOK_BOOLEAN); +case tokreturn (TOK_CASE); +char tokreturn (TOK_CHAR); +const tokreturn (TOK_CONST); +context tokreturn (TOK_CONTEXT); +default tokreturn (TOK_DEFAULT); +double tokreturn (TOK_DOUBLE); +enum tokreturn (TOK_ENUM); +exception tokreturn (TOK_EXCEPTION); +fixed tokreturn (TOK_FIXED); +float tokreturn (TOK_FLOAT); +in tokreturn (TOK_IN); +inout tokreturn (TOK_INOUT); +interface tokreturn (TOK_INTERFACE); +long tokreturn (TOK_LONG); +module tokreturn (TOK_MODULE); +native tokreturn (TOK_NATIVE); +octet tokreturn (TOK_OCTET); +oneway tokreturn (TOK_ONEWAY); +out tokreturn (TOK_OUT); +raises tokreturn (TOK_RAISES); +readonly tokreturn (TOK_READONLY); +sequence tokreturn (TOK_SEQUENCE); +short tokreturn (TOK_SHORT); +string tokreturn (TOK_STRING); +struct tokreturn (TOK_STRUCT); +switch tokreturn (TOK_SWITCH); +typedef tokreturn (TOK_TYPEDEF); +union tokreturn (TOK_UNION); +unsigned tokreturn (TOK_UNSIGNED); +<XP>\.\.\. tokreturn (TOK_VARARGS); +void tokreturn (TOK_VOID); +wchar tokreturn (TOK_WCHAR); +wstring tokreturn (TOK_WSTRING); +:: tokreturn (TOK_OP_SCOPE); +\>\> tokreturn (TOK_OP_SHR); +\<\< tokreturn (TOK_OP_SHL); +{declspec} { + char *s = g_strdup (yytext); + + /* Get the parenthesized expression (ignoring whitespace) */ + sscanf (yytext, "__declspec %*[(] %[A-Za-z_] %*[)]", s); + yylval.str = s; + __IDL_cur_line += count_nl (yytext); + tokreturn (TOK_DECLSPEC); +} +{happy_ident} { +#if 0 + if ((__IDL_flags & IDLF_TYPECODES) && strcmp (yytext, "TypeCode") == 0) + tokreturn (TOK_TYPECODE); +#endif + if (__IDL_typecodes_as_tok>0 && strcmp (yytext, "TypeCode") == 0) + tokreturn (TOK_TYPECODE); + if ( (__IDL_pidl <= 0) && strcmp(yytext, "Object")==0 ) + tokreturn (TOK_OBJECT); + yylval.str = g_strdup (yytext); + tokreturn (TOK_IDENT); +} +{escaped_ident} { + yylval.str = g_strdup (&yytext[1]); + tokreturn (TOK_IDENT); +} +{warn1_ident} { + if (!warn_underscores) { + yywarningv (IDL_WARNING2, + "`%s' underscores within identifiers are discouraged for use " + "with C-language IDL mappings", yytext); + warn_underscores = 1; + } + yylval.str = g_strdup (yytext); + tokreturn (TOK_IDENT); +} +<PROP>] { + __IDL_flagsi &= ~IDLFP_PROPERTIES; + SELECT_RESTART; + tokreturn (yytext[0]); +} +<PROP>{prop_key} { + yylval.str = g_strdup (yytext); + tokreturn (TOK_PROP_KEY); +} +<PROP>{prop_value} { + yylval.str = g_strdup (yytext + 1); + yylval.str[strlen (yylval.str) - 1] = 0; + tokreturn (TOK_PROP_VALUE); +} +<NATIVE>{native_type} { + __IDL_flagsi &= ~IDLFP_NATIVE; + yylval.str = g_strdup (yytext); + yylval.str[strlen (yylval.str) - 1] = 0; + tokreturn (TOK_NATIVE_TYPE); +} +{sqstring} { + yylval.str = g_strdup (yytext + 1); + yylval.str[strlen (yytext) - 2] = 0; + tokreturn (TOK_SQSTRING); +} +{dqstring} { + yylval.str = g_strdup (yytext + 1); + yylval.str[strlen (yytext) - 2] = 0; + tokreturn (TOK_DQSTRING); +} +<*>{newline} ++__IDL_cur_line; +<*>\/\/.* ; +<*>\/\* { + int c; + + while (1) { + while ((c = input ()) != '*' && c != EOF) + if (c == '\n') ++__IDL_cur_line; + if (c == '*') { + while ((c = input ()) == '*') ; + if (c == '/') break; + } + if (c == '\n') ++__IDL_cur_line; + if (c == EOF) { + yywarning (IDL_WARNING1, "End of file in comment"); + break; + } + } +} +<*>. tokreturn (yytext[0]); + +%% + +void __IDL_lex_init (void) +{ + __IDL_inputcb = NULL; + __IDL_cur_line = 1; + __IDL_cur_token_line = 0; + __IDL_prev_token_line = 0; + __IDL_cur_filename = NULL; + __IDL_cur_fileinfo = NULL; + warn_underscores = 0; +} + +void __IDL_lex_cleanup (void) +{ + __IDL_cur_filename = NULL; +#ifdef YY_NEW_FILE + YY_NEW_FILE; /* obsolete with newer versions of flex */ +#endif +} + +int yywrap (void) +{ + return 1; +} + +static int count_nl (const char *s) +{ + int i; + + for (i = 0; + (s = strchr (s, '\n')) != NULL; + ++s, ++i) ; + + return i; +} + +/* + * Local variables: + * mode: C + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + */ |