summaryrefslogtreecommitdiff
path: root/lexer.l
diff options
context:
space:
mode:
Diffstat (limited to 'lexer.l')
-rw-r--r--lexer.l464
1 files changed, 464 insertions, 0 deletions
diff --git a/lexer.l b/lexer.l
new file mode 100644
index 0000000..0677bb5
--- /dev/null
+++ b/lexer.l
@@ -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:
+ */