gdb/ada-lex.l - gdb
- /*----------------------------------------------------------------------*/
- /* The converted version of this file is to be included in ada-exp.y, */
- /* the Ada parser for gdb. The function yylex obtains characters from */
- /* the global pointer lexptr. It returns a syntactic category for */
- /* each successive token and places a semantic value into yylval */
- /* (ada-lval), defined by the parser. */
- DIG [0-9]
- NUM10 ({DIG}({DIG}|_)*)
- HEXDIG [0-9a-f]
- NUM16 ({HEXDIG}({HEXDIG}|_)*)
- OCTDIG [0-7]
- LETTER [a-z_]
- ID ({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">")
- WHITE [ \t\n]
- TICK ("'"{WHITE}*)
- GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~]
- OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs")
- EXP (e[+-]{NUM10})
- POSEXP (e"+"?{NUM10})
- %{
- #define NUMERAL_WIDTH 256
- #define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
- static char numbuf[NUMERAL_WIDTH];
- static void canonicalizeNumeral (char *s1, const char *);
- static struct stoken processString (const char*, int);
- static int processInt (struct parser_state *, const char *, const char *,
- const char *);
- static int processReal (struct parser_state *, const char *);
- static struct stoken processId (const char *, int);
- static int processAttribute (const char *);
- static int find_dot_all (const char *);
- static void rewind_to_char (int);
- #undef YY_DECL
- #define YY_DECL static int yylex ( void )
- #define YY_NO_INPUT
- #undef YY_INPUT
- #define YY_INPUT(BUF, RESULT, MAX_SIZE) \
- if ( *lexptr == '\000' ) \
- (RESULT) = YY_NULL; \
- else \
- { \
- *(BUF) = *lexptr; \
- (RESULT) = 1; \
- lexptr += 1; \
- }
- static int find_dot_all (const char *);
- %}
- %option case-insensitive interactive nodefault
- %s BEFORE_QUAL_QUOTE
- %%
- {WHITE} { }
- "--".* { yyterminate(); }
- {NUM10}{POSEXP} {
- canonicalizeNumeral (numbuf, yytext);
- return processInt (pstate, NULL, numbuf,
- strrchr (numbuf, 'e') + 1);
- }
- {NUM10} {
- canonicalizeNumeral (numbuf, yytext);
- return processInt (pstate, NULL, numbuf, NULL);
- }
- {NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} {
- canonicalizeNumeral (numbuf, yytext);
- return processInt (pstate, numbuf,
- strchr (numbuf, '#') + 1,
- strrchr(numbuf, '#') + 1);
- }
- {NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" {
- canonicalizeNumeral (numbuf, yytext);
- return processInt (pstate, numbuf, strchr (numbuf, '#') + 1,
- NULL);
- }
- "0x"{HEXDIG}+ {
- canonicalizeNumeral (numbuf, yytext+2);
- return processInt (pstate, "16#", numbuf, NULL);
- }
- {NUM10}"."{NUM10}{EXP} {
- canonicalizeNumeral (numbuf, yytext);
- return processReal (pstate, numbuf);
- }
- {NUM10}"."{NUM10} {
- canonicalizeNumeral (numbuf, yytext);
- return processReal (pstate, numbuf);
- }
- {NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} {
- error (_("Based real literals not implemented yet."));
- }
- {NUM10}"#"{NUM16}"."{NUM16}"#" {
- error (_("Based real literals not implemented yet."));
- }
- <INITIAL>"'"({GRAPHIC}|\")"'" {
- yylval.typed_val.type = type_char (pstate);
- yylval.typed_val.val = yytext[1];
- return CHARLIT;
- }
- <INITIAL>"'[\""{HEXDIG}{2}"\"]'" {
- int v;
- yylval.typed_val.type = type_char (pstate);
- sscanf (yytext+3, "%2x", &v);
- yylval.typed_val.val = v;
- return CHARLIT;
- }
- \"({GRAPHIC}|"[\""({HEXDIG}{2}|\")"\"]")*\" {
- yylval.sval = processString (yytext+1, yyleng-2);
- return STRING;
- }
- \" {
- error (_("ill-formed or non-terminated string literal"));
- }
- if {
- rewind_to_char ('i');
- return 0;
- }
- task {
- rewind_to_char ('t');
- return 0;
- }
- thread{WHITE}+{DIG} {
-
- rewind_to_char ('t');
- return 0;
- }
- abs { return ABS; }
- and { return _AND_; }
- else { return ELSE; }
- in { return IN; }
- mod { return MOD; }
- new { return NEW; }
- not { return NOT; }
- null { return NULL_PTR; }
- or { return OR; }
- others { return OTHERS; }
- rem { return REM; }
- then { return THEN; }
- xor { return XOR; }
- true { return TRUEKEYWORD; }
- false { return FALSEKEYWORD; }
- {TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
- "=>" { return ARROW; }
- ".." { return DOTDOT; }
- "**" { return STARSTAR; }
- ":=" { return ASSIGN; }
- "/=" { return NOTEQUAL; }
- "<=" { return LEQ; }
- ">=" { return GEQ; }
- <BEFORE_QUAL_QUOTE>"'" { BEGIN INITIAL; return '\''; }
- [-&*+./:<>=|;\[\]] { return yytext[0]; }
- "," { if (paren_depth == 0 && comma_terminates)
- {
- rewind_to_char (',');
- return 0;
- }
- else
- return ',';
- }
- "(" { paren_depth += 1; return '('; }
- ")" { if (paren_depth == 0)
- {
- rewind_to_char (')');
- return 0;
- }
- else
- {
- paren_depth -= 1;
- return ')';
- }
- }
- "."{WHITE}*all { return DOT_ALL; }
- "."{WHITE}*{ID} {
- yylval.sval = processId (yytext+1, yyleng-1);
- return DOT_ID;
- }
- {ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? {
- int all_posn = find_dot_all (yytext);
- if (all_posn == -1 && yytext[yyleng-1] == '\'')
- {
- BEGIN BEFORE_QUAL_QUOTE;
- yyless (yyleng-1);
- }
- else if (all_posn >= 0)
- yyless (all_posn);
- yylval.sval = processId (yytext, yyleng);
- return NAME;
- }
- "'"[^']+"'"{WHITE}*:: {
- yyless (yyleng - 2);
- yylval.sval = processId (yytext, yyleng);
- return NAME;
- }
- "::" { return COLONCOLON; }
- [{}@] { return yytext[0]; }
- "$"({LETTER}|{DIG}|"$")* {
- yylval.sval.ptr = yytext;
- yylval.sval.length = yyleng;
- return SPECIAL_VARIABLE;
- }
- . { error (_("Invalid character '%s' in expression."), yytext); }
- %%
- #include <ctype.h>
- static void
- lexer_init (FILE *inp)
- {
- BEGIN INITIAL;
- yyrestart (inp);
- }
- static void
- canonicalizeNumeral (char *s1, const char *s2)
- {
- for (; *s2 != '\000'; s2 += 1)
- {
- if (*s2 != '_')
- {
- *s1 = tolower(*s2);
- s1 += 1;
- }
- }
- s1[0] = '\000';
- }
- static int
- processInt (struct parser_state *par_state, const char *base0,
- const char *num0, const char *exp0)
- {
- ULONGEST result;
- long exp;
- int base;
- const char *trailer;
- if (base0 == NULL)
- base = 10;
- else
- {
- base = strtol (base0, (char **) NULL, 10);
- if (base < 2 || base > 16)
- error (_("Invalid base: %d."), base);
- }
- if (exp0 == NULL)
- exp = 0;
- else
- exp = strtol(exp0, (char **) NULL, 10);
- errno = 0;
- result = strtoulst (num0, &trailer, base);
- if (errno == ERANGE)
- error (_("Integer literal out of range"));
- if (isxdigit(*trailer))
- error (_("Invalid digit `%c' in based literal"), *trailer);
- while (exp > 0)
- {
- if (result > (ULONG_MAX / base))
- error (_("Integer literal out of range"));
- result *= base;
- exp -= 1;
- }
- if ((result >> (gdbarch_int_bit (parse_gdbarch (par_state))-1)) == 0)
- yylval.typed_val.type = type_int (par_state);
- else if ((result >> (gdbarch_long_bit (parse_gdbarch (par_state))-1)) == 0)
- yylval.typed_val.type = type_long (par_state);
- else if (((result >> (gdbarch_long_bit (parse_gdbarch (par_state))-1)) >> 1) == 0)
- {
-
- yylval.typed_val.type
- = builtin_type (parse_gdbarch (par_state))->builtin_unsigned_long;
- if (result & LONGEST_SIGN)
- yylval.typed_val.val =
- (LONGEST) (result & ~LONGEST_SIGN)
- - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
- else
- yylval.typed_val.val = (LONGEST) result;
- return INT;
- }
- else
- yylval.typed_val.type = type_long_long (par_state);
- yylval.typed_val.val = (LONGEST) result;
- return INT;
- }
- static int
- processReal (struct parser_state *par_state, const char *num0)
- {
- sscanf (num0, "%" DOUBLEST_SCAN_FORMAT, &yylval.typed_val_float.dval);
- yylval.typed_val_float.type = type_float (par_state);
- if (sizeof(DOUBLEST) >= gdbarch_double_bit (parse_gdbarch (par_state))
- / TARGET_CHAR_BIT)
- yylval.typed_val_float.type = type_double (par_state);
- if (sizeof(DOUBLEST) >= gdbarch_long_double_bit (parse_gdbarch (par_state))
- / TARGET_CHAR_BIT)
- yylval.typed_val_float.type = type_long_double (par_state);
- return FLOAT;
- }
- static struct stoken
- processId (const char *name0, int len)
- {
- char *name = obstack_alloc (&temp_parse_space, len + 11);
- int i0, i;
- struct stoken result;
- result.ptr = name;
- while (len > 0 && isspace (name0[len-1]))
- len -= 1;
- if (strstr (name0, "___") != NULL)
- {
- strncpy (name, name0, len);
- name[len] = '\000';
- result.length = len;
- return result;
- }
- i = i0 = 0;
- while (i0 < len)
- {
- if (isalnum (name0[i0]))
- {
- name[i] = tolower (name0[i0]);
- i += 1; i0 += 1;
- }
- else switch (name0[i0])
- {
- default:
- name[i] = name0[i0];
- i += 1; i0 += 1;
- break;
- case ' ': case '\t':
- i0 += 1;
- break;
- case '\'':
- do
- {
- name[i] = name0[i0];
- i += 1; i0 += 1;
- }
- while (i0 < len && name0[i0] != '\'');
- i0 += 1;
- break;
- case '<':
- i0 += 1;
- while (i0 < len && name0[i0] != '>')
- {
- name[i] = name0[i0];
- i += 1; i0 += 1;
- }
- i0 += 1;
- break;
- }
- }
- name[i] = '\000';
- result.length = i;
- return result;
- }
- static struct stoken
- processString (const char *text, int len)
- {
- const char *p;
- char *q;
- const char *lim = text + len;
- struct stoken result;
- q = obstack_alloc (&temp_parse_space, len);
- result.ptr = q;
- p = text;
- while (p < lim)
- {
- if (p[0] == '[' && p[1] == '"' && p+2 < lim)
- {
- if (p[2] == '"')
- {
- *q = '"';
- p += 4;
- }
- else
- {
- int chr;
- sscanf (p+2, "%2x", &chr);
- *q = (char) chr;
- p += 5;
- }
- }
- else
- *q = *p;
- q += 1;
- p += 1;
- }
- result.length = q - result.ptr;
- return result;
- }
- static int
- find_dot_all (const char *str)
- {
- int i;
- for (i = 0; str[i] != '\000'; i++)
- if (str[i] == '.')
- {
- int i0 = i;
- do
- i += 1;
- while (isspace (str[i]));
- if (strncasecmp (str + i, "all", 3) == 0
- && !isalnum (str[i + 3]) && str[i + 3] != '_')
- return i0;
- }
- return -1;
- }
- static int
- subseqMatch (const char *subseq, const char *str)
- {
- if (subseq[0] == '\0')
- return 1;
- else if (str[0] == '\0')
- return 0;
- else if (tolower (subseq[0]) == tolower (str[0]))
- return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
- else
- return subseqMatch (subseq, str+1);
- }
- static struct { const char *name; int code; }
- attributes[] = {
- { "address", TICK_ADDRESS },
- { "unchecked_access", TICK_ACCESS },
- { "unrestricted_access", TICK_ACCESS },
- { "access", TICK_ACCESS },
- { "first", TICK_FIRST },
- { "last", TICK_LAST },
- { "length", TICK_LENGTH },
- { "max", TICK_MAX },
- { "min", TICK_MIN },
- { "modulus", TICK_MODULUS },
- { "pos", TICK_POS },
- { "range", TICK_RANGE },
- { "size", TICK_SIZE },
- { "tag", TICK_TAG },
- { "val", TICK_VAL },
- { NULL, -1 }
- };
- static int
- processAttribute (const char *str)
- {
- int i, k;
- for (i = 0; attributes[i].code != -1; i += 1)
- if (strcasecmp (str, attributes[i].name) == 0)
- return attributes[i].code;
- for (i = 0, k = -1; attributes[i].code != -1; i += 1)
- if (subseqMatch (str, attributes[i].name))
- {
- if (k == -1)
- k = i;
- else
- error (_("ambiguous attribute name: `%s'"), str);
- }
- if (k == -1)
- error (_("unrecognized attribute: `%s'"), str);
- return attributes[k].code;
- }
- static void
- rewind_to_char (int ch)
- {
- lexptr -= yyleng;
- while (toupper (*lexptr) != toupper (ch))
- lexptr -= 1;
- yyrestart (NULL);
- }
- int
- yywrap(void)
- {
- return 1;
- }
- typedef void (*dummy_function) ();
- dummy_function ada_flex_use[] =
- {
- (dummy_function) yyunput
- };