source: CIVL/mods/dev.civl.abc/grammar/fortran/FortranLexer.g

main
Last change on this file was aad342c, checked in by Stephen Siegel <siegel@…>, 3 years ago

Performing huge refactor to incorporate ABC, GMC, and SARL into CIVL repo and use Java modules.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5664 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 27.8 KB
Line 
1lexer grammar FortranLexer;
2
3options {
4 tokenVocab=FortranLexer;
5}
6
7@header {
8/**
9 * Copyright (c) 2005, 2006 Los Alamos National Security, LLC. This
10 * material was produced under U.S. Government contract DE-
11 * AC52-06NA25396 for Los Alamos National Laboratory (LANL), which is
12 * operated by the Los Alamos National Security, LLC (LANS) for the
13 * U.S. Department of Energy. The U.S. Government has rights to use,
14 * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR
15 * LANS MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY
16 * LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified to
17 * produce derivative works, such modified software should be clearly
18 * marked, so as not to confuse it with the version available from
19 * LANL.
20 *
21 * Additionally, this program and the accompanying materials are made
22 * available under the terms of the Eclipse Public License v1.0 which
23 * accompanies this distribution, and is available at
24 * http://www.eclipse.org/legal/epl-v10.html
25 */
26
27/**
28 *
29 * @author Craig E Rasmussen, Christopher D. Rickett, Jeffrey Overbey
30 */
31
32
33package dev.civl.abc.front.fortran.old.preproc;
34
35import java.io.File;
36import java.io.IOException;
37import java.util.ArrayList;
38import java.util.Stack;
39import java.util.TreeSet;
40
41import dev.civl.abc.token.IF.CivlcToken;
42import dev.civl.abc.token.IF.CivlcToken.TokenVocabulary;
43import dev.civl.abc.token.IF.Formation;
44import dev.civl.abc.token.IF.SourceFile;
45import dev.civl.abc.token.IF.TokenFactory;
46import dev.civl.abc.token.IF.Tokens;
47}
48
49@members {
50 //Fields:
51 private Token prevToken;
52 private int sourceForm;
53 private boolean continueFlag;
54 private boolean includeLine;
55 private boolean inFormat;
56 private ArrayList<String> includeDirs;
57 private Stack<FortranStream> oldStreams;
58
59 //OFP_ABC
60 private Stack<Integer> oldFileIndexes;
61 private int fileCounter = 0;
62 private Integer fileIndex = Integer.valueOf(fileCounter);
63 private TokenFactory tokenFactory = Tokens.newTokenFactory();
64 private Formation inclusionFormation;
65 //OFP_ABC
66
67 protected StringBuilder whiteText = new StringBuilder();
68
69 //Methods:
70 public Token emit() {
71 int start = state.tokenStartCharIndex;
72 int stop = getCharIndex() - 1;
73 // TODO - this is a start at fixing the line:column information in tokens inserted
74 // by the lexer. In future the stop should at least be the length of token text.
75 if (stop < 0) {
76 stop = start; // for now
77 }
78 this.inclusionFormation = tokenFactory.newInclusion(new SourceFile(new File(this.input.getSourceName()), this.fileIndex.intValue()));
79 CivlcToken t = tokenFactory.newCivlcToken(input, state.type, state.channel, start, stop, inclusionFormation, this.input.getLine(), this.input.getCharPositionInLine(), TokenVocabulary.FORTRAN);
80 t.setLine(state.tokenStartLine);
81 t.setText(state.text);
82 t.setCharPositionInLine(state.tokenStartCharPositionInLine);
83
84 if (state.channel == HIDDEN) {
85 whiteText.append(getText());
86 } else {
87 t.setWhiteText(whiteText.toString());
88 whiteText.delete(0, whiteText.length());
89 }
90
91 emit(t);
92 return t;
93 }
94
95 public boolean isKeyword(Token tk) {
96 return isKeyword(tk.getType());
97 } // end isKeyword()
98
99 public boolean isKeyword(int tokenType) {
100 switch (tokenType) {
101 case T_BEGIN_KEYWORDS:
102 case T_INTEGER:
103 case T_REAL:
104 case T_COMPLEX:
105 case T_CHARACTER:
106 case T_LOGICAL:
107 case T_ABSTRACT:
108 case T_ACQUIRED_LOCK:
109 case T_ALL:
110 case T_ALLOCATABLE:
111 case T_ALLOCATE:
112 case T_ASSIGNMENT:
113 case T_ASSIGN:
114 case T_ASSOCIATE:
115 case T_ASYNCHRONOUS:
116 case T_BACKSPACE:
117 case T_BLOCK:
118 case T_BLOCKDATA:
119 case T_CALL:
120 case T_CASE:
121 case T_CLASS:
122 case T_CLOSE:
123 case T_CODIMENSION:
124 case T_COMMON:
125 case T_CONCURRENT:
126 case T_CONTAINS:
127 case T_CONTIGUOUS:
128 case T_CONTINUE:
129 case T_CRITICAL:
130 case T_CYCLE:
131 case T_DATA:
132 case T_DEFAULT:
133 case T_DEALLOCATE:
134 case T_DEFERRED:
135 case T_DO:
136 case T_DOUBLE:
137 case T_DOUBLEPRECISION:
138 case T_DOUBLECOMPLEX:
139 case T_ELEMENTAL:
140 case T_ELSE:
141 case T_ELSEIF:
142 case T_ELSEWHERE:
143 case T_ENTRY:
144 case T_ENUM:
145 case T_ENUMERATOR:
146 case T_ERROR:
147 case T_EQUIVALENCE:
148 case T_EXIT:
149 case T_EXTENDS:
150 case T_EXTERNAL:
151 case T_FILE:
152 case T_FINAL:
153 case T_FLUSH:
154 case T_FORALL:
155 case T_FORMAT:
156 case T_FORMATTED:
157 case T_FUNCTION:
158 case T_GENERIC:
159 case T_GO:
160 case T_GOTO:
161 case T_IF:
162 case T_IMAGES:
163 case T_IMPLICIT:
164 case T_IMPORT:
165 case T_IN:
166 case T_INOUT:
167 case T_INTENT:
168 case T_INTERFACE:
169 case T_INTRINSIC:
170 case T_INQUIRE:
171 case T_LOCK:
172 case T_MEMORY:
173 case T_MODULE:
174 case T_NAMELIST:
175 case T_NONE:
176 case T_NON_INTRINSIC:
177 case T_NON_OVERRIDABLE:
178 case T_NOPASS:
179 case T_NULLIFY:
180 case T_ONLY:
181 case T_OPEN:
182 case T_OPERATOR:
183 case T_OPTIONAL:
184 case T_OUT:
185 case T_PARAMETER:
186 case T_PASS:
187 case T_PAUSE:
188 case T_POINTER:
189 case T_PRINT:
190 case T_PRECISION:
191 case T_PRIVATE:
192 case T_PROCEDURE:
193 case T_PROGRAM:
194 case T_PROTECTED:
195 case T_PUBLIC:
196 case T_PURE:
197 case T_READ:
198 case T_RECURSIVE:
199 case T_RESULT:
200 case T_RETURN:
201 case T_REWIND:
202 case T_SAVE:
203 case T_SELECT:
204 case T_SELECTCASE:
205 case T_SELECTTYPE:
206 case T_SEQUENCE:
207 case T_STOP:
208 case T_SUBMODULE:
209 case T_SUBROUTINE:
210 case T_SYNC:
211 case T_TARGET:
212 case T_THEN:
213 case T_TO:
214 case T_TYPE:
215 case T_UNFORMATTED:
216 case T_UNLOCK:
217 case T_USE:
218 case T_VALUE:
219 case T_VOLATILE:
220 case T_WAIT:
221 case T_WHERE:
222 case T_WHILE:
223 case T_WRITE:
224 case T_WITHTEAM:
225 case T_WITH:
226 case T_TEAM:
227 case T_TOPOLOGY:
228 case T_EVENT:
229 case T_LOCKSET:
230 case T_FINISH:
231 case T_SPAWN:
232 case T_COPOINTER:
233 case T_COTARGET:
234 case T_ENDASSOCIATE:
235 case T_ENDBLOCK:
236 case T_ENDBLOCKDATA:
237 case T_ENDCRITICAL:
238 case T_ENDDO:
239 case T_ENDENUM:
240 case T_ENDFILE:
241 case T_ENDFORALL:
242 case T_ENDFUNCTION:
243 case T_ENDIF:
244 case T_ENDMODULE:
245 case T_ENDINTERFACE:
246 case T_ENDPROCEDURE:
247 case T_ENDPROGRAM:
248 case T_ENDSELECT:
249 case T_ENDSUBMODULE:
250 case T_ENDSUBROUTINE:
251 case T_ENDTYPE:
252 case T_ENDWHERE:
253 case T_END:
254 case T_DIMENSION:
255 case T_KIND:
256 case T_LEN:
257 case T_BIND:
258 case T_END_KEYWORDS:
259 case T_PRAGMA:
260 return true;
261 default:
262 return false;
263 }
264 // (by Manchun) Commenting out the original tricky implementation because it requires
265 // ANTLR to always generates the constants for tokens in the same order
266 // as they were in the lexer file.
267 // however, this is apparently not true for antlr-3.5, which generates
268 // constants by alphabetic order of the token names.
269 // if (tokenType > T_BEGIN_KEYWORDS && tokenType < T_END_KEYWORDS) {
270 // return true;
271 // } else {
272 // return false;
273 // }
274 } // end isKeyword()
275
276
277
278 /**
279 * This is necessary because the lexer class caches some values from the
280 * input stream. Here we reset them to what the current input stream values
281 * are. This is done when we switch streams for including files.
282 */
283 private void resetLexerState() {
284 state.tokenStartCharIndex = input.index();
285 state.tokenStartCharPositionInLine = input.getCharPositionInLine();
286 state.tokenStartLine = input.getLine();
287 state.token = null;
288 state.text = null;
289 }// end resetLexerState()
290
291 // overrides nextToken in superclass
292 public Token nextToken() {
293 CivlcToken tk = tokenFactory.newCivlcToken(super.nextToken(),
294 inclusionFormation, TokenVocabulary.FORTRAN);
295
296 if (tk.getType() == EOF) {
297 CivlcToken eofToken;
298 FortranStream fs = getInput();
299
300 tk.setChannel(Token.DEFAULT_CHANNEL);
301 this.inclusionFormation = tokenFactory.newInclusion(new SourceFile(
302 new File(this.input.getSourceName()), this.fileIndex
303 .intValue()));
304 eofToken = tokenFactory.newCivlcToken(this.input, T_EOF,
305 Token.DEFAULT_CHANNEL, this.input.index(),
306 this.input.index() + 1, inclusionFormation, this.input.getLine(), this.input.getCharPositionInLine(), TokenVocabulary.FORTRAN);
307
308 if (this.oldStreams != null && this.oldStreams.empty() == false) {
309
310 // TODO - provide better information about the location of this
311 // token
312 // It is probably ok for it to start at last character position
313 // in file but
314 // consider the end position of the token.
315 eofToken.setLine(state.tokenStartLine);
316 eofToken.setCharPositionInLine(state.tokenStartCharPositionInLine);
317
318 eofToken.setText(fs.getFileName() + ":" + fs.getAbsolutePath());
319
320 tk = eofToken;
321 /*
322 * We have at least one previous input stream on the stack,
323 * meaning we should be at the end of an included file. Switch
324 * back to the previous stream and continue.
325 */
326 this.input = this.oldStreams.pop();
327 this.fileIndex = this.oldFileIndexes.pop();
328 /* Is this ok to do?? */
329 resetLexerState();
330 } else {
331 tk.setText(fs.getFileName() + ":" + fs.getAbsolutePath());
332 eofToken = tk;
333 }
334
335 return tk;
336 }
337
338 if (tk.getType() != LINE_COMMENT && tk.getType() != WS
339 && tk.getType() != PREPROCESS_LINE) {
340 prevToken = tk;
341 }
342
343 if (tk.getType() == T_EOS && continueFlag == true) {
344 tk.setChannel(99);
345 } else if (continueFlag == true) {
346 if (tk.getType() != LINE_COMMENT && tk.getType() != WS
347 && tk.getType() != PREPROCESS_LINE
348 && tk.getType() != CONTINUE_CHAR) {
349 // if the token we have is not T_EOS or any kind of WS or
350 // comment, and we have a continue, then this should be the
351 // first token on the line folliwng the '&'. this means that
352 // we only have one '&' (no '&' on the second line) and we
353 // need to clear the flag so we know to process the T_EOS.
354 continueFlag = false;
355 }
356 }
357
358 return tk;
359 } // end nextToken()
360
361 public int getIgnoreChannelNumber() {
362 // return the channel number that antlr uses for ignoring a token
363 return 99;
364 }// end getIgnoreChannelNumber()
365
366 public FortranStream getInput() {
367 return (FortranStream) this.input;
368 }
369
370 public Formation getFormation() {
371 assert this.inclusionFormation != null;
372 return this.inclusionFormation;
373 }
374
375 /**
376 * Do this here because not sure how to get antlr to generate the init code.
377 * It doesn't seem to do anything with the @init block below. This is called
378 * by FortranMain().
379 */
380 public FortranLexer(FortranStream input) {
381 super(input);
382 this.sourceForm = input.getSourceForm();
383 this.prevToken = null;
384 this.continueFlag = false;
385 this.includeLine = false;
386 this.inFormat = false;
387 this.oldStreams = new Stack<FortranStream>();
388 this.oldFileIndexes = new Stack<Integer>();
389 // TODO: idx
390 this.includeDirs = new ArrayList<String>();
391 this.inclusionFormation = tokenFactory
392 .newInclusion(new SourceFile(new File(this.input
393 .getSourceName()), this.fileIndex.intValue()));
394 } // end constructor()
395
396 public void setIncludeDirs(File[] systemIncludePaths, File[] userIncludePaths, File[] sourceUnit) {
397 TreeSet<String> pathSet = new TreeSet<String>();
398
399 if (systemIncludePaths != null)
400 for (File f : systemIncludePaths) {
401 if (f != null && f.getParentFile() != null)
402 pathSet.add(f.getParentFile().getAbsolutePath());
403 }
404 if (userIncludePaths != null)
405 for (File f : userIncludePaths) {
406 if (f != null && f.getParentFile() != null)
407 pathSet.add(f.getParentFile().getAbsolutePath());
408 }
409 if (sourceUnit != null)
410 for (File f : sourceUnit) {
411 if (f != null && f.getParentFile() != null)
412 pathSet.add(f.getParentFile().getAbsolutePath());
413 }
414 for (String s : pathSet) {
415 includeDirs.add(s);
416 }
417
418 }// end setIncludeDirs()
419
420 private File findFile(String fileName) {
421 File tmpFile;
422 String tmpPath;
423 StringBuffer newFileName;
424
425 tmpFile = new File(fileName);
426 if (tmpFile.exists() == false) {
427 /*
428 * the file doesn't exist by the given name from the include line,
429 * so we need to append it to each include dir and search.
430 */
431 for (int i = 0; i < this.includeDirs.size(); i++) {
432 tmpPath = this.includeDirs.get(i);
433
434 newFileName = new StringBuffer();
435
436 /*
437 * Build the new file name with the path. Add separator to end
438 * of path if necessary (unix specific).
439 */
440 newFileName = newFileName.append(tmpPath);
441 if (tmpPath.charAt(tmpPath.length() - 1) != '/') {
442 newFileName = newFileName.append('/');
443 }
444 newFileName = newFileName.append(fileName);
445
446 /* Try opening the new file. */
447 tmpFile = new File(newFileName.toString());
448 if (tmpFile.exists() == true) {
449 return tmpFile;
450 }
451 }
452
453 /* File did not exist. */
454 return null;
455 } else {
456 return tmpFile;
457 }
458 } // end findFile()
459
460 private String includeFile() {
461 String filename = "ERROR: no file name";
462 File includedFile = null;
463
464 if (prevToken != null) {
465 String charConst = null;
466 FortranStream includedStream = null;
467
468 charConst = prevToken.getText();
469 filename = charConst.substring(1, charConst.length() - 1);
470
471 /* Find the file, including it's complete path. */
472 includedFile = findFile(filename);
473 if (includedFile == null) {
474 System.err.println("WARNING: Could not find file '" + filename
475 + "'");
476 return filename + ":ERROR_FILE_NOT_FOUND";
477 }
478
479 /* Create a new stream for the included file. */
480 try {
481 // the included file should have the save source form as
482 // original
483 includedStream = new FortranStream(filename,
484 includedFile.getAbsolutePath(), this.sourceForm);
485 } catch (IOException e) {
486 System.err.println("WARNING: Could not open file '" + filename
487 + "'");
488 e.printStackTrace();
489 return includedFile.getAbsolutePath();
490 }
491
492 /* Save current character stream. */
493 oldStreams.push(getInput());
494 oldFileIndexes.push(fileIndex);
495 this.fileCounter++;
496 this.fileIndex = Integer.valueOf(this.fileCounter);
497 this.input = includedStream;
498 /* Is this ok to do?? */
499 resetLexerState();
500 } else {
501 System.err.println("ERROR: Unable to determine file name from "
502 + "include line");
503 }
504
505 return filename + ":" + includedFile.getAbsolutePath();
506
507 } // end includeFile()
508
509}
510
511@init {
512 prevToken = null;
513}
514
515/*
516 * Lexer rules
517 */
518
519/*
520 * Note: antlr sometimes has LL(*) failures with the grammars, but not always.
521 * it seems that it may be the timeout issue that was mentioned..
522 */
523
524// Support for language extension points
525T_NO_LANGUAGE_EXTENSION : {false}? 'no extension' ; // can't be recognized
526
527
528T_EOS
529@after {
530 // Throw away T_EOS if at beginning of file or after an include,
531 // T_EOS processing by the parser only works after the first statement so
532 // any blank lines before statements in a file must be hidden.
533 if (prevToken == null) {
534 state.channel = HIDDEN;
535 } else if (prevToken.getType() == T_EOS || prevToken.getType() == T_INCLUDE_NAME) {
536 state.channel = HIDDEN;
537 }
538
539 if (includeLine) {
540 // Part of include file handling.
541 state.text = includeFile();
542 state.type = T_INCLUDE_NAME;
543 includeLine = false;
544 }
545
546 // Make sure we clear the flag saying we're in a format-stmt
547 inFormat = false;
548}
549 : ';'
550 | ('\r')? ('\n')
551 ;
552
553
554/* if this is a fragment, the generated code never seems to execute the
555 * action. the action needs to set the flag so T_EOS knows whether it should
556 * be channel 99'ed or not (ignore T_EOS if continuation is true, which is the
557 * case of the & at the end of a line).
558 */
559CONTINUE_CHAR : '&' {
560 continueFlag = !continueFlag;
561 $channel = HIDDEN;
562 }
563 ;
564
565
566// R427 from char-literal-constant
567T_CHAR_CONSTANT
568 : ('\'' ( SQ_Rep_Char )* '\'')+ {
569 if (includeLine)
570 $channel = HIDDEN;
571 }
572 | ('\"' ( DQ_Rep_Char )* '\"')+ {
573 if (includeLine)
574 $channel = HIDDEN;
575 }
576 ;
577
578T_DIGIT_STRING
579 : Digit_String
580 ;
581
582// R412
583BINARY_CONSTANT
584 : ('b'|'B') '\'' ('0'..'1')+ '\''
585 | ('b'|'B') '\"' ('0'..'1')+ '\"'
586 ;
587
588// R413
589OCTAL_CONSTANT
590 : ('o'|'O') '\'' ('0'..'7')+ '\''
591 | ('o'|'O') '\"' ('0'..'7')+ '\"'
592 ;
593
594// R414
595HEX_CONSTANT
596 : ('z'|'Z') '\'' (Digit|'a'..'f'|'A'..'F')+ '\''
597 | ('z'|'Z') '\"' (Digit|'a'..'f'|'A'..'F')+ '\"'
598 ;
599
600
601WS : (' '|'\r'|'\t'|'\u000C') {
602 $channel = HIDDEN;
603 }
604 ;
605
606/*
607 * fragments
608 */
609
610// R409 digit_string
611fragment
612Digit_String : Digit+ ;
613
614
615// R302 alphanumeric_character
616fragment
617Alphanumeric_Character : Letter | Digit | '_' ;
618
619fragment
620Special_Character
621 : ' ' .. '/'
622 | ':' .. '@'
623 | '[' .. '^'
624 | '`'
625 | '{' .. '~'
626 ;
627
628fragment
629Rep_Char : ~('\'' | '\"') ;
630
631fragment
632SQ_Rep_Char : ~('\'') ;
633fragment
634DQ_Rep_Char : ~('\"') ;
635
636fragment
637Letter : ('a'..'z' | 'A'..'Z') ;
638
639fragment
640Digit : '0'..'9' ;
641
642PREPROCESS_LINE : '#' ~('\n'|'\r')* {
643 $channel = HIDDEN;
644 } ;
645
646T_INCLUDE
647options {k=1;} : 'INCLUDE' {
648 includeLine = true;
649 };
650
651
652/*
653 * from fortran03_lexer.g
654 */
655
656T_ASTERISK : '*' ;
657T_COLON : ':' ;
658T_COLON_COLON : '::' ;
659T_COMMA : ',' ;
660T_EQUALS : '=' ;
661T_EQ_EQ : '==' ;
662T_EQ_GT : '=>' ;
663T_GREATERTHAN : '>' ;
664T_GREATERTHAN_EQ: '>=' ;
665T_LESSTHAN : '<' ;
666T_LESSTHAN_EQ : '<=' ;
667T_LBRACKET : '[' ;
668T_LPAREN : '(' ;
669T_MINUS : '-' ;
670T_PERCENT : '%' ;
671T_PLUS : '+' ;
672T_POWER : '**' ;
673T_SLASH : '/' ;
674T_SLASH_EQ : '/=' ;
675T_SLASH_SLASH : '//' ;
676T_RBRACKET : ']' ;
677T_RPAREN : ')' ;
678T_UNDERSCORE : '_' ;
679
680// begin Rice additions --------------------------
681T_AT : '@' ;
682// end Rice additions ----------------------------
683
684T_EQ : '.EQ.' ;
685T_NE : '.NE.' ;
686T_LT : '.LT.' ;
687T_LE : '.LE.' ;
688T_GT : '.GT.' ;
689T_GE : '.GE.' ;
690
691T_TRUE : '.TRUE.' ;
692T_FALSE : '.FALSE.' ;
693
694T_NOT : '.NOT.' ;
695T_AND : '.AND.' ;
696T_OR : '.OR.' ;
697T_EQV : '.EQV.' ;
698T_NEQV : '.NEQV.';
699
700T_PERIOD_EXPONENT
701 : '.' ('0'..'9')+ ('E' | 'e' | 'd' | 'D') ('+' | '-')? ('0'..'9')+
702 | '.' ('E' | 'e' | 'd' | 'D') ('+' | '-')? ('0'..'9')+
703 | '.' ('0'..'9')+
704 | ('0'..'9')+ ('e' | 'E' | 'd' | 'D') ('+' | '-')? ('0'..'9')+
705 ;
706
707T_PERIOD : '.' ;
708
709// begin keyword section (all keywords must appear between
710// T_BEGIN_KEYWORDS and T_END_KEYWORDS)
711//
712T_BEGIN_KEYWORDS: '__BEGIN_KEYWORDS__';
713
714T_INTEGER : 'INTEGER' ;
715T_REAL : 'REAL' ;
716T_COMPLEX : 'COMPLEX' ;
717T_CHARACTER : 'CHARACTER' ;
718T_LOGICAL : 'LOGICAL' ;
719
720T_ABSTRACT : 'ABSTRACT' ;
721T_ACQUIRED_LOCK : 'ACQUIRED_LOCK' ; /* F2008 token */
722T_ALL : 'ALL' ; /* F2008 token (also in F2003?) */
723T_ALLOCATABLE : 'ALLOCATABLE' ;
724T_ALLOCATE : 'ALLOCATE' ;
725T_ASSIGNMENT : 'ASSIGNMENT' ;
726// ASSIGN statements are a deleted feature.
727T_ASSIGN : 'ASSIGN' ;
728T_ASSOCIATE : 'ASSOCIATE' ;
729T_ASYNCHRONOUS : 'ASYNCHRONOUS' ;
730T_BACKSPACE : 'BACKSPACE' ;
731T_BLOCK : 'BLOCK' ;
732T_BLOCKDATA : 'BLOCKDATA' ;
733T_CALL : 'CALL' ;
734T_CASE : 'CASE' ;
735T_CLASS : 'CLASS' ;
736T_CLOSE : 'CLOSE' ;
737T_CODIMENSION : 'CODIMENSION' ;
738T_COMMON : 'COMMON' ;
739T_CONCURRENT : 'CONCURRENT' ;
740T_CONTAINS : 'CONTAINS' ;
741T_CONTIGUOUS : 'CONTIGUOUS' ;
742T_CONTINUE : 'CONTINUE' ;
743T_CRITICAL : 'CRITICAL' ;
744T_CYCLE : 'CYCLE' ;
745T_DATA : 'DATA' ;
746T_DEFAULT : 'DEFAULT' ;
747T_DEALLOCATE : 'DEALLOCATE' ;
748T_DEFERRED : 'DEFERRED' ;
749T_DO : 'DO' ;
750T_DOUBLE : 'DOUBLE' ;
751T_DOUBLEPRECISION: 'DOUBLEPRECISION' ;
752T_DOUBLECOMPLEX: 'DOUBLECOMPLEX' ;
753T_ELEMENTAL : 'ELEMENTAL' ;
754T_ELSE : 'ELSE' ;
755T_ELSEIF : 'ELSEIF' ;
756T_ELSEWHERE : 'ELSEWHERE' ;
757T_ENTRY : 'ENTRY' ;
758T_ENUM : 'ENUM' ;
759T_ENUMERATOR : 'ENUMERATOR' ;
760T_ERROR : 'ERROR' ;
761T_EQUIVALENCE : 'EQUIVALENCE' ;
762T_EXIT : 'EXIT' ;
763T_EXTENDS : 'EXTENDS' ;
764T_EXTERNAL : 'EXTERNAL' ;
765T_FILE : 'FILE' ;
766T_FINAL : 'FINAL' ;
767T_FLUSH : 'FLUSH' ;
768T_FORALL : 'FORALL' ;
769T_FORMAT : 'FORMAT' { inFormat = true; };
770T_FORMATTED : 'FORMATTED' ;
771T_FUNCTION : 'FUNCTION' ;
772T_GENERIC : 'GENERIC' ;
773T_GO : 'GO' ;
774T_GOTO : 'GOTO' ;
775T_IF : 'IF' ;
776T_IMAGES : 'IMAGES' ;
777T_IMPLICIT : 'IMPLICIT' ;
778T_IMPORT : 'IMPORT' ;
779T_IN : 'IN' ;
780T_INOUT : 'INOUT' ;
781T_INTENT : 'INTENT' ;
782T_INTERFACE : 'INTERFACE' ;
783T_INTRINSIC : 'INTRINSIC' ;
784T_INQUIRE : 'INQUIRE' ;
785T_LOCK : 'LOCK' ; /* F2008 token */
786T_MEMORY : 'MEMORY' ;
787T_MODULE : 'MODULE' ;
788T_NAMELIST : 'NAMELIST' ;
789T_NONE : 'NONE' ;
790T_NON_INTRINSIC : 'NON_INTRINSIC' ;
791T_NON_OVERRIDABLE: 'NON_OVERRIDABLE';
792T_NOPASS : 'NOPASS' ;
793T_NULLIFY : 'NULLIFY' ;
794T_ONLY : 'ONLY' ;
795T_OPEN : 'OPEN' ;
796T_OPERATOR : 'OPERATOR' ;
797T_OPTIONAL : 'OPTIONAL' ;
798T_OUT : 'OUT' ;
799T_PARAMETER : 'PARAMETER' ;
800T_PASS : 'PASS' ;
801T_PAUSE : 'PAUSE' ;
802T_POINTER : 'POINTER' ;
803T_PRINT : 'PRINT' ;
804T_PRECISION : 'PRECISION' ;
805T_PRIVATE : 'PRIVATE' ;
806T_PROCEDURE : 'PROCEDURE' ;
807T_PROGRAM : 'PROGRAM' ;
808T_PROTECTED : 'PROTECTED' ;
809T_PUBLIC : 'PUBLIC' ;
810T_PURE : 'PURE' ;
811T_READ : 'READ' ;
812T_RECURSIVE : 'RECURSIVE' ;
813T_RESULT : 'RESULT' ;
814T_RETURN : 'RETURN' ;
815T_REWIND : 'REWIND' ;
816T_SAVE : 'SAVE' ;
817T_SELECT : 'SELECT' ;
818T_SELECTCASE : 'SELECTCASE' ;
819T_SELECTTYPE : 'SELECTTYPE' ;
820T_SEQUENCE : 'SEQUENCE' ;
821T_STOP : 'STOP' ;
822T_SUBMODULE : 'SUBMODULE' ;
823T_SUBROUTINE : 'SUBROUTINE' ;
824T_SYNC : 'SYNC' ; /* F2008 token */
825T_TARGET : 'TARGET' ;
826T_THEN : 'THEN' ;
827T_TO : 'TO' ;
828T_TYPE : 'TYPE' ;
829T_UNFORMATTED : 'UNFORMATTED' ;
830T_UNLOCK : 'UNLOCK' ; /* F2008 token */
831T_USE : 'USE' ;
832T_VALUE : 'VALUE' ;
833T_VOLATILE : 'VOLATILE' ;
834T_WAIT : 'WAIT' ;
835T_WHERE : 'WHERE' ;
836T_WHILE : 'WHILE' ;
837T_WRITE : 'WRITE' ;
838
839// begin Rice additions --------------------------
840T_WITHTEAM : 'WITHTEAM' ;
841T_WITH : 'WITH' ;
842T_TEAM : 'TEAM' ;
843T_TOPOLOGY : 'TOPOLOGY' ;
844T_EVENT : 'EVENT' ;
845T_LOCKSET : 'LOCKSET' ;
846T_FINISH : 'FINISH' ;
847T_SPAWN : 'SPAWN' ;
848T_COPOINTER : 'COPOINTER' ;
849T_COTARGET : 'COTARGET' ;
850// end Rice additions ----------------------------
851
852// these tokens (without blank characters) are from 3.3.2.2
853//
854
855T_ENDASSOCIATE : 'ENDASSOCIATE' ;
856T_ENDBLOCK : 'ENDCOTARGETBLOCK' ;
857T_ENDBLOCKDATA : 'ENDBLOCKDATA' ;
858T_ENDCRITICAL : 'ENDCRITICAL' ;
859T_ENDDO : 'ENDDO' ;
860T_ENDENUM : 'ENDENUM' ;
861T_ENDFILE : 'ENDFILE' ;
862T_ENDFORALL : 'ENDFORALL' ;
863T_ENDFUNCTION : 'ENDFUNCTION' ;
864T_ENDIF : 'ENDIF' ;
865T_ENDMODULE : 'ENDMODULE' ;
866T_ENDINTERFACE : 'ENDINTERFACE' ;
867T_ENDPROCEDURE : 'ENDPROCEDURE' ;
868T_ENDPROGRAM : 'ENDPROGRAM' ;
869T_ENDSELECT : 'ENDSELECT' ;
870T_ENDSUBMODULE : 'ENDSUBMODULE' ;
871T_ENDSUBROUTINE : 'ENDSUBROUTINE' ;
872T_ENDTYPE : 'ENDTYPE' ;
873T_ENDWHERE : 'ENDWHERE' ;
874
875T_END : 'END'
876 ;
877
878T_DIMENSION : 'DIMENSION' ;
879
880T_KIND : 'KIND' ;
881T_LEN : 'LEN' ;
882
883T_BIND : 'BIND' ;
884
885// End keyword section (all keywords must appear between
886// T_BEGIN_KEYWORDS and T_END_KEYWORDS)
887//
888T_END_KEYWORDS : '__END_KEYWORDS__';
889
890//
891// Note: Hollerith constants were deleted in F77; Hollerith edit descriptors
892// deleted in F95.
893//
894T_HOLLERITH : Digit_String 'H'
895 {
896 // If we're inside a format stmt we don't want to process it as
897 // a Hollerith constant because it's most likely an H-edit descriptor.
898 // However, the H-edit descriptor needs processed the same way both
899 // here and in the prepass.
900 StringBuffer hollConst = new StringBuffer();
901 int count = Integer.parseInt($Digit_String.text);
902
903 for(int i = 0; i < count; i++)
904 hollConst = hollConst.append((char)input.LA(i+1));
905 for(int i = 0; i < count; i++)
906 // consume the character so the lexer doesn't try matching it.
907 input.consume();
908 };
909
910// Must come after .EQ. (for example) or will get matched first
911// TODO:: this may have to be done in the parser w/ a rule such as:
912// T_PERIOD T_IDENT T_PERIOD
913T_DEFINED_OP
914 : '.' Letter+ '.'
915 ;
916
917// // used to catch edit descriptors and other situations
918// T_ID_OR_OTHER
919// : 'ID_OR_OTHER'
920// ;
921
922// extra, context-sensitive terminals that require communication between parser and scanner
923// added the underscores so there is no way this could overlap w/ any valid
924// idents in Fortran. we just need this token to be defined so we can
925// create one of them while we're fixing up labeled do stmts.
926T_LABEL_DO_TERMINAL
927 : '__LABEL_DO_TERMINAL__'
928 ;
929
930T_DATA_EDIT_DESC : '__T_DATA_EDIT_DESC__' ;
931T_CONTROL_EDIT_DESC : '__T_CONTROL_EDIT_DESC__' ;
932T_CHAR_STRING_EDIT_DESC : '__T_CHAR_STRING_EDIT_DESC__' ;
933
934T_STMT_FUNCTION
935 : 'STMT_FUNCTION'
936 ;
937
938T_ASSIGNMENT_STMT : '__T_ASSIGNMENT_STMT__' ;
939T_PTR_ASSIGNMENT_STMT : '__T_PTR_ASSIGNMENT_STMT__' ;
940T_ARITHMETIC_IF_STMT : '__T_ARITHMETIC_IF_STMT__' ;
941T_ALLOCATE_STMT_1 : '__T_ALLOCATE_STMT_1__' ;
942T_WHERE_STMT : '__T_WHERE_STMT__' ;
943T_IF_STMT : '__T_IF_STMT__' ;
944T_FORALL_STMT : '__T_FORALL_STMT__' ;
945T_WHERE_CONSTRUCT_STMT : '__T_WHERE_CONSTRUCT_STMT__' ;
946T_FORALL_CONSTRUCT_STMT : '__T_FORALL_CONSTRUCT_STMT__' ;
947T_INQUIRE_STMT_2 : '__T_INQUIRE_STMT_2__' ;
948// text for the real constant will be set when a token of this type is
949// created by the prepass.
950T_REAL_CONSTANT : '__T_REAL_CONSTANT__' ;
951
952T_INCLUDE_NAME: '__T_INCLUDE_NAME__' ;
953T_EOF: '__T_EOF__' ;
954
955// R304
956T_IDENT
957options {k=1;}
958 : Letter ( Alphanumeric_Character )*
959 ;
960
961//
962// Used in format-item processing. This token is replaced by an edit
963// descriptor in the prepass (by FortranLexicalPrepass). It doesn't really
964// matter what this token contains because the format string is parsed
965// as a string in the lexical prepass. The goal is to keep the lexer from
966// bombing on strings like 2es15.6 and also not interfer with real literal
967// constants and Holleriths.
968//
969T_EDIT_DESC_MISC
970 : Digit_String
971 ( ('e'|'E') (('n'|'N') | ('s'|'S')) )
972 ( Alphanumeric_Character )*
973 ;
974
975LINE_COMMENT
976 : '!' ~('\n'|'\r'|'$')*
977 {
978 $channel = HIDDEN;
979 }
980 ;
981
982/* Need a catch-all rule because of fixed-form being allowed to use any
983 character in column 6 to designate a continuation. */
984MISC_CHAR : ~('\n' | '\r') ;
985
986T_PRAGMA
987 : '!$'
988 ;
Note: See TracBrowser for help on using the repository browser.