@@ -25,6 +25,9 @@ import org.eclipse.core.runtime.Path;
25
25
import fr. cnes. analysis. tools. analyzer. datas. AbstractChecker;
26
26
import fr. cnes. analysis. tools. analyzer. datas. CheckResult;
27
27
import fr. cnes. analysis. tools. analyzer. exception. JFlexException;
28
+ import java. util. EmptyStackException;
29
+ import java. util. Stack;
30
+ import fr. cnes. analysis. tools. shell. metrics. Function;
28
31
29
32
import java. util. logging. Logger;
30
33
@@ -42,7 +45,7 @@ import java.util.logging.Logger;
42
45
%type List<CheckResult>
43
46
44
47
45
- %state COMMENT , NAMING , FILE , STRING
48
+ %state COMMENT , NAMING , FILE , STRING , BEGINFUNC
46
49
47
50
COMMENT_WORD = [ \# ]
48
51
FUNCTION = "function"
@@ -54,6 +57,8 @@ SHELL_VAR = ([0-9]+|[\-\@\?\#\!\_\*\$])
54
57
EXPANDED_VAR = [ \! ] ? {NAME} ( [ \: ] |(( [ \% ] ? [ \% ] )|( [ \# ] ? [ \# ] ))|( [ \: ] ? [ \=\+\?\- ] ))( {NAME} | [ \[ ] {NAME} [ \] ] )|( [ \# ] {NAME} )
55
58
VAR = ( {NAME} |( [ \$ ][ \{ ] ( {NAME} | {SHELL_VAR} | {EXPANDED_VAR} ) [ \} ] )|( [ \$ ] ( {NAME} | {SHELL_VAR} )))
56
59
60
+ FUNCSTART = \{ | \( | \(\( | \[\[ | "if" | "case" | "select" | "for" | "while" | "until"
61
+ FUNCEND = \} | \) | \)\) | \]\] | "fi" | "esac" | "done"
57
62
58
63
OPERATOR_RIGHT = [ \> ] | [ \> ][ \& ] | [ \& ][ \> ] | [ \> ][ \> ] | [ \> ][ \> ][ \> ]
59
64
OPERATOR_LEFT = [ \< ] | [ \< ][ \& ] | [ \& ][ \< ] | [ \< ][ \< ] | [ \< ][ \< ][ \< ]
@@ -92,10 +97,18 @@ IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh"
92
97
93
98
%{
94
99
private static final Logger LOGGER = Logger . getLogger(COMFLOWFileExistence . class. getName());
95
- private String location = " MAIN PROGRAM" ;
96
- private String parsedFileName;
97
-
100
+
101
+ /* MAINPROGRAM: constant for main program localisation */
102
+ private static final String MAINPROGRAM = " MAIN PROGRAM" ;
103
+
104
+ String location = MAINPROGRAM ;
105
+ /* functionLine: the beginning line of the function */
106
+ int functionLine = 0 ;
107
+
108
+ private String parsedFileName;
98
109
110
+ private Stack<Function > functionStack = new Stack<> ();
111
+
99
112
List<String > filesExistence = new ArrayList<String > ();
100
113
101
114
private String stringBeginner = " " ;
@@ -116,6 +129,23 @@ IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh"
116
129
this . zzReader = new FileReader (new Path (file. getAbsolutePath()). toOSString());
117
130
LOGGER . fine(" end method setInputFile" );
118
131
}
132
+
133
+ private void endLocation() throws JFlexException {
134
+ try {
135
+ Function functionFinished = functionStack. pop();
136
+ if (! functionStack. empty()) {
137
+ /* there is a current function: change location to this function */
138
+ location = functionStack. peek(). getName();
139
+ } else {
140
+ /* we are in the main program: change location to main */
141
+ location = MAINPROGRAM ;
142
+ }
143
+ }catch (EmptyStackException e){
144
+ final String errorMessage = e. getMessage();
145
+ throw new JFlexException (this . getClass(). getName(), parsedFileName,
146
+ errorMessage, yytext(), yyline, yycolumn);
147
+ }
148
+ }
119
149
120
150
%}
121
151
@@ -145,9 +175,10 @@ IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh"
145
175
/* ***********************/
146
176
<NAMING>
147
177
{
148
- {FNAME } {location = yytext();
178
+ {FNAME } {location = yytext();
179
+ functionLine = yyline+ 1 ;
149
180
LOGGER . fine(" [" + this . parsedFileName+ " :" + (yyline+ 1 )+ " :" + yycolumn+ " ] - NAMING -> YYINITIAL (Transition : VAR \" " + yytext()+ " \" )" );
150
- yybegin(YYINITIAL );}
181
+ yybegin(BEGINFUNC );}
151
182
\n {
152
183
LOGGER . fine(" [" + this . parsedFileName+ " :" + (yyline+ 1 )+ " :" + yycolumn+ " ] - NAMING -> YYINITIAL (Transition : \\ n )" );
153
184
yybegin(YYINITIAL );}
@@ -165,8 +196,28 @@ IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh"
165
196
yybegin(NAMING );
166
197
}
167
198
{FUNCT } {
199
+ functionLine = yyline+ 1 ;
168
200
location = yytext(). substring(0 ,yytext(). length()- 2 ). trim();
201
+ yybegin(BEGINFUNC );
169
202
}
203
+ {FUNCSTART } {
204
+ if (! functionStack. empty()){
205
+ if (functionStack. peek(). getFinisher(). equals(Function . finisherOf(yytext()))){
206
+ functionStack. peek(). addStarterRepetition();
207
+ }
208
+ }
209
+ }
210
+ {FUNCEND } {
211
+ if (! functionStack. empty()){
212
+ if (functionStack. peek(). isFinisher(yytext())){
213
+ if (functionStack. peek(). getStarterRepetition()> 0 ) {
214
+ functionStack. peek(). removeStarterRepetition();
215
+ } else {
216
+ endLocation();
217
+ }
218
+ }
219
+ }
220
+ }
170
221
{FILEEXIST } {
171
222
int index = yytext(). indexOf(' -' );
172
223
String subfile = yytext(). substring(index);
@@ -266,7 +317,28 @@ IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh"
266
317
}
267
318
. {}
268
319
}
320
+ /* ***********************/
321
+ /* BEGINFUNC STATE */
322
+ /* ***********************/
323
+ /*
324
+ * This state's target is to retrieve the function starter. For more information on fonction starter, have a look on {@link Function} class.
325
+ * Pending this starter, the function ender can be defined.
326
+ *
327
+ */
328
+ <BEGINFUNC>
329
+ {
330
+ \(\) {}
331
+ {FUNCSTART } {
332
+ Function function;
333
+ function = new Function (location, functionLine, yytext());
334
+ functionStack. push(function);
335
+ yybegin(YYINITIAL );
336
+ }
337
+ [^ ]| {SPACE } {}
338
+ }
339
+
269
340
341
+
270
342
271
343
/* ***********************/
272
344
/* ERROR STATE */
0 commit comments