PIPS
tp_lex.l
Go to the documentation of this file.
1 %option nounput
2 %option noinput
3 %{
4 /*
5 
6  $Id: tp_lex.l 23412 2017-08-09 15:07:09Z irigoin $
7 
8  Copyright 1989-2016 MINES ParisTech
9 
10  This file is part of PIPS.
11 
12  PIPS is free software: you can redistribute it and/or modify it
13  under the terms of the GNU General Public License as published by
14  the Free Software Foundation, either version 3 of the License, or
15  any later version.
16 
17  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
18  WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  FITNESS FOR A PARTICULAR PURPOSE.
20 
21  See the GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
25 
26 */
27 #ifdef HAVE_CONFIG_H
28 #include "pips_config.h"
29 #endif
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include "genC.h"
36 #include "misc.h"
37 #include "tpips.h"
38 #include "tp_yacc.h"
39 
40 /* disable echoing unmatched characters */
41 #define ECHO ;
42 
43 /* now get the characters from a string, not from a file */
44 #ifndef FLEX_SCANNER
45 
46 #undef input()
47 #define input() tpips_lex_input()
48 #undef unput()
49 #define unput(c) tpips_lex_unput(c)
50 void yyrestart(FILE *f){ yyin = f;}
51 
52 #else
53 
54 #define YY_INPUT(buf,result,max_size) \
55  { \
56  int c = tpips_lex_input(); \
57  result = (c == '\0') ? YY_NULL : (buf[0] = c, 1); \
58  }
59 
60 #endif
61 
62 string tpips_unknown_string = string_undefined; // For tp_yacc.y
63 static bool cr_not_returned;
64 static char * line_to_parse;
65 static char * line_parsed;
66 
67 void tpips_set_line_to_parse(char * line)
68 {
69  skip_blanks(line);
70  /* store line pointer */
71  line_parsed = line_to_parse = line;
72  cr_not_returned = true;
73 }
74 
75 char * tpips_get_line_to_parse(void)
76 {
77  return line_to_parse;
78 }
79 
80 static int back = 0;
81 
82 void tpips_lex_print_pos(FILE* fout)
83 {
84  int shift = (int)((long) line_to_parse - (long)line_parsed) - back;
85  fprintf(fout,
86  "%s\n"
87  "%*s^\n"
88  "at line %d in \"%s\"\n", line_parsed, shift, "",
89  tpips_current_line(), tpips_current_name());
90 }
91 
92 static int tpips_lex_input (void)
93 {
94  char c = *line_to_parse;
95  pips_debug(9,"input char '%c'(0x%2x) from input\n", c, c);
96  if (c) line_to_parse++;
97  /* a fake \n is provided, to check for nargs in the syntax... */
98  else if (cr_not_returned) { cr_not_returned=false; return (int) '\n'; }
99  return (int) c;
100 }
101 
102 /* string to be processed by some other lexer/parser.
103  */
104 static char unk[2]; /* one char lines are not implicit shells */
105 
106 #define RETURN(x) pips_debug(8, "init %d\n", x); return x
107 #define KEYWORD(x) pips_debug(8, "key %d\n", x); BEGIN INITIAL; return x
108 #define LITTERAL(x) \
109  pips_debug(8, "spc %d\n", x); \
110  BEGIN SPC; \
111  return x
112 #define RESTART(x) pips_debug(8, "rst %d\n", x); BEGIN KEY; return x
113 
114 %}
115 
116 %s KEY STR SPC LIT UNK
117 
118 %%
119 
120 <KEY>setenv { KEYWORD(TK_SET_ENVIRONMENT); }
121 <KEY>getenv { KEYWORD(TK_GET_ENVIRONMENT); }
122 <KEY>unsetenv { KEYWORD(TK_UNSET_ENVIRONMENT); }
123 <KEY>open { KEYWORD(TK_OPEN); }
124 <KEY>create { KEYWORD(TK_CREATE); }
125 <KEY>close { KEYWORD(TK_CLOSE); }
126 <KEY>checkpoint { KEYWORD(TK_CHECKPOINT); }
127 <KEY>delete { KEYWORD(TK_DELETE); }
128 <KEY>module { KEYWORD(TK_MODULE); }
129 <KEY>make { KEYWORD(TK_MAKE); }
130 <KEY>apply { KEYWORD(TK_APPLY); }
131 <KEY>capply { KEYWORD(TK_CAPPLY); }
132 <KEY>display { KEYWORD(TK_DISPLAY); }
133 <KEY>activate { KEYWORD(TK_ACTIVATE); }
134 <KEY>getproperty { KEYWORD(TK_GET_PROPERTY); }
135 <KEY>get { KEYWORD(TK_GET_PROPERTY); }
136 <KEY>info { KEYWORD(TK_INFO); }
137 <KEY>cd { KEYWORD(TK_CDIR); }
138 <KEY>pwd { KEYWORD(TK_PWD); }
139 <KEY>source { KEYWORD(TK_SOURCE); }
140 <KEY>quit { KEYWORD(TK_QUIT); }
141 <KEY>bye { KEYWORD(TK_QUIT); }
142 <KEY>exit { KEYWORD(TK_EXIT); }
143 <KEY>help { KEYWORD(TK_HELP); }
144 <KEY>remove { KEYWORD(TK_REMOVE); }
145 <KEY>show { KEYWORD(TK_SHOW); }
146 <KEY>checkactive { KEYWORD(TK_CHECKACTIVE); }
147 <KEY>version { KEYWORD(TK_VERSION); }
148 <KEY>touch { KEYWORD(TK_TOUCH); }
149 <KEY>timeout { KEYWORD(TK_TIMEOUT); }
150 
151 <KEY>setproperty { LITTERAL(TK_SET_PROPERTY); }
152 <KEY>setprop { LITTERAL(TK_SET_PROPERTY); }
153 <KEY>set { LITTERAL(TK_SET_PROPERTY); }
154 <KEY>echo { LITTERAL(TK_ECHO); }
155 <KEY>shell { LITTERAL(TK_SHELL); }
156 <KEY>sh { LITTERAL(TK_SHELL); }
157 <KEY>! { LITTERAL(TK_SHELL); }
158 
159 <KEY,INITIAL>[ \t]+ /* skip blanks... */
160 
161 <UNK>[^\r\n]* { tp_lval.name = strdup(concatenate(unk, yytext, NULL));
162  tpips_unknown_string=strdup(yytext);
163  KEYWORD(TK_UNKNOWN); }
164 
165 <SPC>[ \t]+ { BEGIN LIT; }
166 <SPC>[^ \t\r\n][^\r\n]* {
167  back = strlen(yytext);
168  tp_error("Space expected after initial keyword.\n");
169  back = 0;
170  }
171 <LIT>[^\r\n]* { tp_lval.name = strdup(yytext); RETURN(TK_LINE); }
172 <INITIAL,KEY>#[^\r\n]* { BEGIN INITIAL;
173  /* skip comments... (not for echo, shell set). */}
174 <KEY>. { unk[0]=yytext[0]; unk[1]='\0'; BEGIN UNK; }
175 
176 <INITIAL>\‍( { RETURN(TK_OPENPAREN); }
177 <INITIAL>\‍) { RETURN(TK_CLOSEPAREN); }
178 
179 <INITIAL>\[ { RETURN(TK_OPENPAREN); }
180 <INITIAL>\] { RETURN(TK_CLOSEPAREN); }
181 
182 <INITIAL>\, { RETURN(TK_COMMA); }
183 <INITIAL>= { RETURN(TK_EQUAL); }
184 
185 <LIT,INITIAL,SPC>(\n|\r|\r\n|;) { RESTART(TK_ENDOFLINE); }
186 <LIT,INITIAL><<EOF>> { RESTART(TK_ENDOFLINE); }
187 
188 <STR>[^\"]*\" {
189  // string contents without surrounding double quotes
190  // no attempt at managing escaping double quotes
191  tp_lval.name = strdup(yytext);
192  tp_lval.name[strlen(yytext)-1] = '\0';
193  BEGIN INITIAL; RETURN(TK_A_STRING);}
194 <INITIAL>\" { BEGIN STR; }
195 
196 <INITIAL>"$ALL" { RETURN(TK_OWNER_ALL); }
197 <INITIAL>"$ALLFUNC" { RETURN(TK_OWNER_ALLFUNC); }
198 <INITIAL>"$ALLCU" { RETURN(TK_OWNER_ALLCU); }
199 <INITIAL>"$PROGRAM" { RETURN(TK_OWNER_PROGRAM); }
200 <INITIAL>"$MAIN" { RETURN(TK_OWNER_MAIN); }
201 <INITIAL>"$MODULE" { RETURN(TK_OWNER_MODULE); }
202 <INITIAL>"$CALLERS" { RETURN(TK_OWNER_CALLERS); }
203 <INITIAL>"$CALLEES" { RETURN(TK_OWNER_CALLEES); }
204 
205 <INITIAL>"%ALL" { RETURN(TK_OWNER_ALL); }
206 <INITIAL>"%ALLFUNC" { RETURN(TK_OWNER_ALLFUNC); }
207 <INITIAL>"%ALLCU" { RETURN(TK_OWNER_ALLCU); }
208 <INITIAL>"%PROGRAM" { RETURN(TK_OWNER_PROGRAM); }
209 <INITIAL>"%MAIN" { RETURN(TK_OWNER_MAIN); }
210 <INITIAL>"%MODULE" { RETURN(TK_OWNER_MODULE); }
211 <INITIAL>"%CALLERS" { RETURN(TK_OWNER_CALLERS); }
212 <INITIAL>"%CALLEES" { RETURN(TK_OWNER_CALLEES); }
213 
214 <INITIAL>[0-9]+ { tp_lval.ival = atoi(yytext); RETURN(TK_INT); }
215 
216 <INITIAL>[/\.0-9A-Za-z_:-][!/\.0-9A-Za-z_:-]* {
217  tp_lval.name = strdup(yytext);
218  RETURN(TK_NAME);
219  }
220 . { pips_user_warning("Unrecognized character \"%s\"\n",yytext); }
221 
222 %%
223 
224 int yywrap(void){ return 1; }
225 
226 void tp_init_lex(void)
227 {
228  BEGIN KEY;
229 #ifdef FLEX_SCANNER
230  yy_init = 1;
231 #endif
232 }
233 
234 void tp_error(const char * s)
235 {
236  tpips_init(); /* needed for user error... */
237  tpips_lex_print_pos(stderr);
238  pips_user_error("%s\n", s);
239 }