1 %option yylineno 2 3 %{ 4 #include "pscan.h" 5 static void skip_strings(char literal); 6 %} 7 8 %x comment 9 %x strings 10 11 reserved "default"|"struct"|"void"|"for"|"if"|"else"|"while"|"do"|"return"|"case"|"switch"|"break"|"auto"|"continue"|"goto"|"sizeof"|"static"|"typedef"|"union"|"volatile" 12 13 vartype "char"|"double"|"enum"|"extern"|"float"|"int"|"long"|"register"|"short"|"signed"|"unsigned"|"const" 14 15 cprep "include"|"define"|"if"|"else"|"endif"|"ifdef"|"ifndef" 16 17 %% 18 {reserved} state->last_token = NOT_PROBLEMATIC; 19 20 {vartype} state->last_token = NOT_PROBLEMATIC; 21 22 23 "#"{cprep} state->last_token = NOT_PROBLEMATIC; 24 25 NULL { if ((state->last_token == PROBLEMATIC) && 26 (state->constant_string < 0)) { 27 state->constant_string = state->args; 28 } 29 } 30 31 \" { 32 if (state->last_token == PROBLEMATIC) { 33 if (state->constant_string < 0) { 34 state->constant_string = state->args; 35 } 36 } 37 skip_strings('"'); 38 } 39 40 \' skip_strings('\''); 41 42 \/\/.*$ /* skip C++ style comments */ 43 44 [a-zA-Z_][_a-zA-Z0-9]* state = setup_checks(yytext, state); 45 46 [ \t]+ /* eat up whitespace */ 47 48 \( { 49 if (state->args < 0) state->args = 0; 50 state->braces++; 51 if (state->braces > 1) { 52 state = push_stack(state); 53 state->last_token = NOT_PROBLEMATIC; 54 state->braces = 1; 55 state->args = -1; 56 } 57 } 58 59 \, if (state->last_token == PROBLEMATIC) { 60 if (state->braces != 0) { 61 state->args++; 62 } else { 63 state->last_token = NOT_PROBLEMATIC; 64 } 65 } 66 67 \) if (state->last_token == PROBLEMATIC) { 68 check_function(state); 69 state->last_token = NOT_PROBLEMATIC; 70 } else if (state->braces != 0) { 71 state->braces--; 72 if (state->braces == 0) { 73 state = pop_stack(); 74 } 75 } 76 77 . { 78 if ((state->last_token == PROBLEMATIC) && 79 (state->braces == 0)) { 80 state->last_token = NOT_PROBLEMATIC; 81 } 82 } 83 84 85 "\n"|"\r" /* ignore LF's and CR's */ 86 87 88 "/*" BEGIN(comment); 89 90 <comment>[^*\n]* /* eat anything that's not a '*' */ 91 <comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ 92 <comment>\n /* do nothing */ 93 <comment>"*"+"/" BEGIN(INITIAL); 94 95 %% 96 /********************************************************************** 97 * pscan: http://www.striker.ottawa.on.ca/~aland/pscan/ 98 * 99 * Copyright (C) 2000 Alan DeKok <aland@ox.org> 100 * 101 * This program is free software; you can redistribute it and/or modify 102 * it under the terms of the GNU General Public License as published by 103 * the Free Software Foundation; either version 2 of the License, or 104 * (at your option) any later version. 105 * 106 * This program is distributed in the hope that it will be useful, 107 * but WITHOUT ANY WARRANTY; without even the implied warranty of 108 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 109 * GNU General Public License for more details. 110 * 111 * You should have received a copy of the GNU General Public License 112 * along with this program; if not, write to the Free Software 113 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 114 * 115 **********************************************************************/ 116 static const char rcsid[] = "$Id: scanner.l,v 1.4 2000/07/17 18:51:45 aland Exp $"; 117 118 /* static */ 119 void skip_strings(char literal) 120 { 121 int c; 122 123 while ((c = input()) != literal) 124 { 125 switch (c) { 126 127 case '\\': 128 c = input(); 129 if (c == '\\') continue; 130 if (c == EOF) return; 131 if (c != literal) 132 unput(c); 133 break; 134 case EOF: 135 return; 136 137 default: 138 break; 139 } 140 } 141 } 142