MFParser.java
package edu.udel.cis.vsl.abc.front.fortran.parse;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.TokenStream;
import edu.udel.cis.vsl.abc.front.IF.ParseException;
import edu.udel.cis.vsl.abc.front.IF.ParseTree;
import edu.udel.cis.vsl.abc.front.IF.Parser;
import edu.udel.cis.vsl.abc.front.fortran.preproc.MFortranLexicalPrepass;
import edu.udel.cis.vsl.abc.front.fortran.preproc.PP2CivlcTokenMFortranConverter;
import edu.udel.cis.vsl.abc.token.IF.CivlcTokenSource;
public class MFParser implements Parser {
/* **************** Constructor **************** */
public MFParser() {
}
/* **************** Public Methods **************** */
@Override
public ParseTree parse(CivlcTokenSource tokenSource) throws ParseException {
TokenStream stream = new CommonTokenStream(tokenSource);
PP2CivlcTokenMFortranConverter converter = new PP2CivlcTokenMFortranConverter();
stream = converter.convert(stream);
MFortranLexicalPrepass prepass = new MFortranLexicalPrepass(stream);
TokenStream fstream = prepass.performPrepass();
MFortranParser2018 parser = new MFortranParser2018(fstream);
parser.initialize();
while (fstream.LA(1) != MFortranParser2018.EOF) {
try {
if (parseProgramUnit(fstream, parser))
throw new ParseException(
"encounter error when parsing the fortran token stream");
} catch (RecognitionException e) {
throw new ParseException(e.getMessage());
}
}
return parser.getAction().getFortranParseTree();
}
/* **************** Private Helper Methods **************** */
private static boolean parseMainProgram(TokenStream tokens,
MFortranParser2018 parser, int start) throws RecognitionException {
// try parsing the main program
parser.main_program();
return parser.hasError();
} // end parseMainProgram()
private static boolean parseModule(TokenStream tokens,
MFortranParser2018 parser, int start) throws RecognitionException {
parser.module();
return parser.hasError();
} // end parseModule()
private static boolean parseSubmodule(TokenStream tokens,
MFortranParser2018 parser, int start) throws RecognitionException {
parser.submodule();
return parser.hasError();
} // end parseSubmodule()
private static boolean parseBlockData(TokenStream tokens,
MFortranParser2018 parser, int start) throws RecognitionException {
parser.block_data();
return parser.hasError();
} // end parseBlockData()
private static boolean parseSubroutine(TokenStream tokens,
MFortranParser2018 parser, int start) throws RecognitionException {
parser.subroutine_subprogram();
return parser.hasError();
} // end parserSubroutine()
private static boolean parseFunction(TokenStream tokens,
MFortranParser2018 parser, int start) throws RecognitionException {
parser.ext_function_subprogram();
return parser.hasError();
} // end parseFunction()
private static boolean parseProgramUnit(TokenStream tokens,
MFortranParser2018 parser) throws RecognitionException {
int firstToken;
int lookAhead = 1;
int start;
boolean error = false;
// check for opening with an include file
parser.checkForInclude();
// first token on the *line*. will check to see if it's
// equal to module, block, etc. to determine what rule of
// the grammar to start with.
try {
lookAhead = 1;
do {
firstToken = tokens.LA(lookAhead);
lookAhead++;
} while (firstToken == MFortranParser2018.LINE_COMMENT
|| firstToken == MFortranParser2018.EOS);
// mark the location of the first token we're looking at
start = tokens.mark();
// attempt to match the program unit
// each of the parse routines called will first try and match
// the unit they represent (function, block, etc.). if that
// fails, they may or may not try and match it as a main
// program; it depends on how it fails.
//
// due to Sale's algorithm, we know that if the token matches
// then the parser should be able to successfully match.
if (firstToken != MFortranParser2018.EOF) {
if (firstToken == MFortranParser2018.MODULE && tokens
.LA(lookAhead) != MFortranParser2018.PROCEDURE) {
// try matching a module
error = parseModule(tokens, parser, start);
} else if (firstToken == MFortranParser2018.SUBMODULE) {
// try matching a submodule
error = parseSubmodule(tokens, parser, start);
} else if (firstToken == MFortranParser2018.BLOCKDATA
|| (firstToken == MFortranParser2018.BLOCK && tokens
.LA(lookAhead) == MFortranParser2018.DATA)) {
// try matching block data
error = parseBlockData(tokens, parser, start);
} else if (lookForToken(tokens,
MFortranParser2018.SUBROUTINE) == true) {
// try matching a subroutine
error = parseSubroutine(tokens, parser, start);
} else if (lookForToken(tokens,
MFortranParser2018.FUNCTION) == true) {
// try matching a function
error = parseFunction(tokens, parser, start);
} else {
// what's left should be a main program
error = parseMainProgram(tokens, parser, start);
} // end else(unhandled token)
} // end if(file had nothing but comments empty)
} catch (RecognitionException e) {
e.printStackTrace();
error = true;
} // end try/catch(parsing program unit)
return error;
} // end parseProgramUnit()
private static boolean lookForToken(TokenStream stream, int tokenType) {
int numLA = 1;
int curType = -1;
do {
curType = stream.LA(numLA++);
} while (curType != MFortranParser2018.EOS
&& curType != MFortranParser2018.EOF && curType != tokenType);
return curType == tokenType;
}
}