📄 lex.l
字号:
/* Lexical analysis for genksyms. Copyright 1996, 1997 Linux International. New implementation contributed by Richard Henderson <rth@tamu.edu> Based on original work by Bjorn Ekwall <bj0rn@blox.se> Taken from Linux modutils 2.4.22. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */%{#include <limits.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "genksyms.h"#include "parse.h"/* We've got a two-level lexer here. We let flex do basic tokenization and then we categorize those basic tokens in the second stage. */#define YY_DECL static int yylex1(void)%}IDENT [A-Za-z_\$][A-Za-z0-9_\$]*O_INT 0[0-7]*D_INT [1-9][0-9]*X_INT 0[Xx][0-9A-Fa-f]+I_SUF [Uu]|[Ll]|[Uu][Ll]|[Ll][Uu]INT ({O_INT}|{D_INT}|{X_INT}){I_SUF}?FRAC ([0-9]*\.[0-9]+)|([0-9]+\.)EXP [Ee][+-]?[0-9]+F_SUF [FfLl]REAL ({FRAC}{EXP}?{F_SUF}?)|([0-9]+{EXP}{F_SUF}?)STRING L?\"([^\\\"]*\\.)*[^\\\"]*\"CHAR L?\'([^\\\']*\\.)*[^\\\']*\'MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)/* Version 2 checksumming does proper tokenization; version 1 wasn't quite so pedantic. */%s V2_TOKENS/* We don't do multiple input files. */%option noyywrap%% /* Keep track of our location in the original source files. */^#[ \t]+{INT}[ \t]+\"[^\"\n]+\".*\n return FILENAME;^#.*\n cur_line++;\n cur_line++; /* Ignore all other whitespace. */[ \t\f\v\r]+ ;{STRING} return STRING;{CHAR} return CHAR;{IDENT} return IDENT; /* The Pedant requires that the other C multi-character tokens be recognized as tokens. We don't actually use them since we don't parse expressions, but we do want whitespace to be arranged around them properly. */<V2_TOKENS>{MC_TOKEN} return OTHER;<V2_TOKENS>{INT} return INT;<V2_TOKENS>{REAL} return REAL;"..." return DOTS; /* All other tokens are single characters. */. return yytext[0];%%/* Bring in the keyword recognizer. */#include "keywords.c"/* Macros to append to our phrase collection list. */#define _APP(T,L) do { \ cur_node = next_node; \ next_node = xmalloc(sizeof(*next_node)); \ next_node->next = cur_node; \ cur_node->string = memcpy(xmalloc(L+1), T, L+1); \ cur_node->tag = SYM_NORMAL; \ } while (0)#define APP _APP(yytext, yyleng)/* The second stage lexer. Here we incorporate knowledge of the state of the parser to tailor the tokens that are returned. */intyylex(void){ static enum { ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_BRACKET, ST_BRACE, ST_EXPRESSION, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4, ST_TABLE_5, ST_TABLE_6 } lexstate = ST_NOTSTARTED; static int suppress_type_lookup, dont_want_brace_phrase; static struct string_list *next_node; int token, count = 0; struct string_list *cur_node; if (lexstate == ST_NOTSTARTED) { BEGIN(V2_TOKENS); next_node = xmalloc(sizeof(*next_node)); next_node->next = NULL; lexstate = ST_NORMAL; }repeat: token = yylex1(); if (token == 0) return 0; else if (token == FILENAME) { char *file, *e; /* Save the filename and line number for later error messages. */ if (cur_filename) free(cur_filename); file = strchr(yytext, '\"')+1; e = strchr(file, '\"'); *e = '\0'; cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1); cur_line = atoi(yytext+2); goto repeat; } switch (lexstate) { case ST_NORMAL: switch (token) { case IDENT: APP; { const struct resword *r = is_reserved_word(yytext, yyleng); if (r) { switch (token = r->token) { case ATTRIBUTE_KEYW: lexstate = ST_ATTRIBUTE; count = 0; goto repeat; case ASM_KEYW: lexstate = ST_ASM; count = 0; goto repeat; case STRUCT_KEYW: case UNION_KEYW: dont_want_brace_phrase = 3; case ENUM_KEYW: suppress_type_lookup = 2; goto fini; case EXPORT_SYMBOL_KEYW: goto fini; } } if (!suppress_type_lookup) { struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF); if (sym && sym->type == SYM_TYPEDEF) token = TYPE; } } break; case '[': APP; lexstate = ST_BRACKET; count = 1; goto repeat; case '{': APP; if (dont_want_brace_phrase) break; lexstate = ST_BRACE; count = 1; goto repeat; case '=': case ':': APP; lexstate = ST_EXPRESSION; break; case DOTS: default: APP; break; } break; case ST_ATTRIBUTE: APP; switch (token) { case '(': ++count; goto repeat; case ')': if (--count == 0) { lexstate = ST_NORMAL; token = ATTRIBUTE_PHRASE; break; } goto repeat; default: goto repeat; } break; case ST_ASM: APP; switch (token) { case '(': ++count; goto repeat; case ')': if (--count == 0) { lexstate = ST_NORMAL; token = ASM_PHRASE; break; } goto repeat; default: goto repeat; } break; case ST_BRACKET: APP; switch (token) { case '[': ++count; goto repeat; case ']': if (--count == 0) { lexstate = ST_NORMAL; token = BRACKET_PHRASE; break; } goto repeat; default: goto repeat; } break; case ST_BRACE: APP; switch (token) { case '{': ++count; goto repeat; case '}': if (--count == 0) { lexstate = ST_NORMAL; token = BRACE_PHRASE; break; } goto repeat; default: goto repeat; } break; case ST_EXPRESSION: switch (token) { case '(': case '[': case '{': ++count; APP; goto repeat; case ')': case ']': case '}': --count; APP; goto repeat; case ',': case ';': if (count == 0) { /* Put back the token we just read so's we can find it again after registering the expression. */ unput(token); lexstate = ST_NORMAL; token = EXPRESSION_PHRASE; break; } APP; goto repeat; default: APP; goto repeat; } break; case ST_TABLE_1: goto repeat; case ST_TABLE_2: if (token == IDENT && yyleng == 1 && yytext[0] == 'X') { token = EXPORT_SYMBOL_KEYW; lexstate = ST_TABLE_5; APP; break; } lexstate = ST_TABLE_6; /* FALLTHRU */ case ST_TABLE_6: switch (token) { case '{': case '[': case '(': ++count; break; case '}': case ']': case ')': --count; break; case ',': if (count == 0) lexstate = ST_TABLE_2; break; }; goto repeat; case ST_TABLE_3: goto repeat; case ST_TABLE_4: if (token == ';') lexstate = ST_NORMAL; goto repeat; case ST_TABLE_5: switch (token) { case ',': token = ';'; lexstate = ST_TABLE_2; APP; break; default: APP; break; } break; default: exit(1); }fini: if (suppress_type_lookup > 0) --suppress_type_lookup; if (dont_want_brace_phrase > 0) --dont_want_brace_phrase; yylval = &next_node->next; return token;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -