@@ -18,12 +18,15 @@ import java.io.FileNotFoundException;
18
18
import java. io. FileReader;
19
19
import java. io. File;
20
20
import java. util. List;
21
+ import java. util. EmptyStackException;
22
+ import java. util. Stack;
21
23
22
24
import org. eclipse. core. runtime. Path;
23
25
24
26
import fr. cnes. analysis. tools. analyzer. datas. AbstractChecker;
25
27
import fr. cnes. analysis. tools. analyzer. datas. CheckResult;
26
28
import fr. cnes. analysis. tools. analyzer. exception. JFlexException;
29
+ import fr. cnes. analysis. tools. shell. metrics. Function;
27
30
28
31
% %
29
32
@@ -39,7 +42,7 @@ import fr.cnes.analysis.tools.analyzer.exception.JFlexException;
39
42
%type List<CheckResult>
40
43
41
44
42
- %state COMMENT , NAMING , FILE , STRING
45
+ %state COMMENT , NAMING , FILE , STRING , BEGINFUNC
43
46
44
47
COMMENT_WORD = \#
45
48
FUNCTION = "function"
@@ -81,14 +84,25 @@ REDIRECT_IGNORE = ([0-2]({OPERATOR_LEFT}|{OPERATOR_RL})) | (({OPERATOR_RIGHT}|{
81
84
82
85
STRING_ESCAPED = [ \\ ] {STRING}
83
86
IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ( [ \\ ][ \# ] ) | "ssh"
84
-
87
+
88
+ FUNCSTART = \{ | \( | \(\( | \[\[ | "if" | "case" | "select" | "for" | "while" | "until"
89
+ FUNCEND = \} | \) | \)\) | \]\] | "fi" | "esac" | "done"
90
+
85
91
%{
86
- String location = " MAIN PROGRAM" ;
92
+ /* MAINPROGRAM: constant for main program localisation */
93
+ private static final String MAINPROGRAM = " MAIN PROGRAM" ;
94
+
95
+ String location = MAINPROGRAM ;
96
+ /* functionLine: the beginning line of the function */
97
+ int functionLine = 0 ;
98
+
87
99
private String parsedFileName;
88
100
89
101
private String stringBeginner = " " ;
90
102
private boolean escapeNext = false ;
91
103
104
+ private Stack<Function > functionStack = new Stack<> ();
105
+
92
106
93
107
public COMFLOWFilePath() {
94
108
}
@@ -100,7 +114,24 @@ IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh"
100
114
this . parsedFileName = file. toString();
101
115
this . zzReader = new FileReader (new Path (file. getAbsolutePath()). toOSString());
102
116
}
103
-
117
+
118
+ private void endLocation() throws JFlexException {
119
+ try {
120
+ Function functionFinished = functionStack. pop();
121
+ if (! functionStack. empty()) {
122
+ /* there is a current function: change location to this function */
123
+ location = functionStack. peek(). getName();
124
+ } else {
125
+ /* we are in the main program: change location to main */
126
+ location = MAINPROGRAM ;
127
+ }
128
+ }catch (EmptyStackException e){
129
+ final String errorMessage = e. getMessage();
130
+ throw new JFlexException (this . getClass(). getName(), parsedFileName,
131
+ errorMessage, yytext(), yyline, yycolumn);
132
+ }
133
+ }
134
+
104
135
%}
105
136
106
137
%eofval{
@@ -130,7 +161,7 @@ IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh"
130
161
/* ***********************/
131
162
<NAMING>
132
163
{
133
- {FNAME } {location = yytext(); yybegin(YYINITIAL );}
164
+ {FNAME } {location = yytext(); functionLine = yyline + 1 ; yybegin(BEGINFUNC );}
134
165
\n {yybegin(YYINITIAL );}
135
166
. {}
136
167
}
@@ -142,7 +173,28 @@ IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh"
142
173
{
143
174
{COMMENT_WORD } {if (! escapeNext) {yybegin(COMMENT );}}
144
175
{FUNCTION } {yybegin(NAMING );}
145
- {FUNCT } {location = yytext(). substring(0 ,yytext(). length()- 2 ). trim();}
176
+ {FUNCT } {functionLine = yyline+ 1 ;
177
+ location = yytext(). substring(0 ,yytext(). length()- 2 ). trim();
178
+ yybegin(BEGINFUNC );
179
+ }
180
+ {FUNCSTART } {
181
+ if (! functionStack. empty()){
182
+ if (functionStack. peek(). getFinisher(). equals(Function . finisherOf(yytext()))){
183
+ functionStack. peek(). addStarterRepetition();
184
+ }
185
+ }
186
+ }
187
+ {FUNCEND } {
188
+ if (! functionStack. empty()){
189
+ if (functionStack. peek(). isFinisher(yytext())){
190
+ if (functionStack. peek(). getStarterRepetition()> 0 ) {
191
+ functionStack. peek(). removeStarterRepetition();
192
+ } else {
193
+ endLocation();
194
+ }
195
+ }
196
+ }
197
+ }
146
198
{IGNORE } {}
147
199
{FILEEXIST } {
148
200
int index = yytext(). indexOf(' -' );
@@ -210,6 +262,25 @@ IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh"
210
262
[^ ] {escapeNext= false ;}
211
263
}
212
264
265
+ /* ***********************/
266
+ /* BEGINFUNC STATE */
267
+ /* ***********************/
268
+ /*
269
+ * This state target is to retrieve the function starter. For more information on fonction starter, have a look on {@link Function} class.
270
+ * Pending this starter, the function ender can be defined.
271
+ *
272
+ */
273
+ <BEGINFUNC>
274
+ {
275
+ \(\) {}
276
+ {FUNCSTART } {
277
+ Function function;
278
+ function = new Function (location, functionLine, yytext());
279
+ functionStack. push(function);
280
+ yybegin(YYINITIAL );
281
+ }
282
+ [^ ]| {SPACE } {}
283
+ }
213
284
214
285
/* ***********************/
215
286
/* ERROR STATE */
0 commit comments