📄 javacodegenerator.java
字号:
int ruleNum=0;
while ( ids.hasMoreElements() ) {
RuleSymbol sym = (RuleSymbol) ids.nextElement();
// Don't generate the synthetic rules
if (!sym.getId().equals("mnextToken")) {
genRule(sym, false, ruleNum++);
}
exitIfError();
}
// Generate the semantic predicate map for debugging
if (grammar.debuggingOutput)
genSemPredMap();
// Generate the bitsets used throughout the lexer
genBitsets(bitsetsUsed, ((LexerGrammar)grammar).charVocabulary.size());
println("");
println("}");
// Close the lexer output stream
currentOutput.close();
currentOutput = null;
}
/** Generate code for the given grammar element.
* @param blk The (...)+ block to generate
*/
public void gen(OneOrMoreBlock blk) {
if ( DEBUG_CODE_GENERATOR ) System.out.println("gen+("+blk+")");
String label;
String cnt;
println("{");
genBlockPreamble(blk);
if ( blk.getLabel() != null ) {
cnt = "_cnt_"+blk.getLabel();
}
else {
cnt = "_cnt" + blk.ID;
}
println("int "+cnt+"=0;");
if ( blk.getLabel() != null ) {
label = blk.getLabel();
}
else {
label = "_loop" + blk.ID;
}
println(label+":");
println("do {");
tabs++;
// Tell AST generation to build subrule result
String saveCurrentASTResult = currentASTResult;
if (blk.getLabel() != null) {
currentASTResult = blk.getLabel();
}
boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
// generate exit test if greedy set to false
// and an alt is ambiguous with exit branch
// or when lookahead derived purely from end-of-file
// Lookahead analysis stops when end-of-file is hit,
// returning set {epsilon}. Since {epsilon} is not
// ambig with any real tokens, no error is reported
// by deterministic() routines and we have to check
// for the case where the lookahead depth didn't get
// set to NONDETERMINISTIC (this only happens when the
// FOLLOW contains real atoms + epsilon).
boolean generateNonGreedyExitPath = false;
int nonGreedyExitDepth = grammar.maxk;
if ( !blk.greedy &&
blk.exitLookaheadDepth<=grammar.maxk &&
blk.exitCache[blk.exitLookaheadDepth].containsEpsilon() )
{
generateNonGreedyExitPath = true;
nonGreedyExitDepth = blk.exitLookaheadDepth;
}
else if ( !blk.greedy &&
blk.exitLookaheadDepth==LLkGrammarAnalyzer.NONDETERMINISTIC )
{
generateNonGreedyExitPath = true;
}
// generate exit test if greedy set to false
// and an alt is ambiguous with exit branch
if ( generateNonGreedyExitPath ) {
if ( DEBUG_CODE_GENERATOR ) {
System.out.println("nongreedy (...)+ loop; exit depth is "+
blk.exitLookaheadDepth);
}
String predictExit =
getLookaheadTestExpression(blk.exitCache,
nonGreedyExitDepth);
println("// nongreedy exit test");
println("if ( "+cnt+">=1 && "+predictExit+") break "+label+";");
}
JavaBlockFinishingInfo howToFinish = genCommonBlock(blk, false);
genBlockFinish(
howToFinish,
"if ( "+cnt+">=1 ) { break "+label+"; } else {" + throwNoViable + "}"
);
println(cnt+"++;");
tabs--;
println("} while (true);");
println("}");
// Restore previous AST generation
currentASTResult = saveCurrentASTResult;
}
/** Generate the parser Java file */
public void gen(ParserGrammar g) throws IOException {
// if debugging, set up a new vector to keep track of sempred
// strings for this grammar
if (g.debuggingOutput)
semPreds = new Vector();
setGrammar(g);
if (!(grammar instanceof ParserGrammar)) {
tool.panic("Internal error generating parser");
}
// Open the output stream for the parser and set the currentOutput
// SAS: moved file setup so subclass could do it (for VAJ interface)
setupOutput(grammar.getClassName());
genAST = grammar.buildAST;
tabs = 0;
// Generate the header common to all output files.
genHeader();
// Do not use printAction because we assume tabs==0
println(behavior.getHeaderAction(""));
// Generate header for the parser
println("import antlr_oaa.TokenBuffer;");
println("import antlr_oaa.TokenStreamException;");
println("import antlr_oaa.TokenStreamIOException;");
println("import antlr_oaa.ANTLRException;");
println("import antlr_oaa." + grammar.getSuperClass() + ";");
println("import antlr_oaa.Token;");
println("import antlr_oaa.TokenStream;");
println("import antlr_oaa.RecognitionException;");
println("import antlr_oaa.NoViableAltException;");
println("import antlr_oaa.MismatchedTokenException;");
println("import antlr_oaa.SemanticException;");
println("import antlr_oaa.ParserSharedInputState;");
println("import antlr_oaa.collections.impl.BitSet;");
println("import antlr_oaa.collections.AST;");
println("import antlr_oaa.ASTPair;");
println("import antlr_oaa.collections.impl.ASTArray;");
// Output the user-defined parser preamble
println(grammar.preambleAction.getText());
// Generate parser class definition
String sup=null;
if ( grammar.superClass != null )
sup = grammar.superClass;
else
sup = "antlr_oaa." + grammar.getSuperClass();
// print javadoc comment if any
if ( grammar.comment!=null ) {
_println(grammar.comment);
}
println("public class " + grammar.getClassName() + " extends "+sup);
println(" implements " + grammar.tokenManager.getName() + TokenTypesFileSuffix);
Token tsuffix = (Token)grammar.options.get("classHeaderSuffix");
if ( tsuffix != null ) {
String suffix = Tool.stripFrontBack(tsuffix.getText(),"\"","\"");
if ( suffix != null )
print(", "+suffix); // must be an interface name for Java
}
println(" {");
// set up an array of all the rule names so the debugger can
// keep track of them only by number -- less to store in tree...
if (grammar.debuggingOutput) {
println("private static final String _ruleNames[] = {");
Enumeration ids = grammar.rules.elements();
int ruleNum=0;
while ( ids.hasMoreElements() ) {
GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
if ( sym instanceof RuleSymbol)
println(" \""+((RuleSymbol)sym).getId()+"\",");
}
println("};");
}
// Generate user-defined parser class members
print(
processActionForTreeSpecifiers(grammar.classMemberAction.getText(), 0, currentRule, null)
);
// Generate parser class constructor from TokenBuffer
println("");
println("protected " + grammar.getClassName() + "(TokenBuffer tokenBuf, int k) {");
println(" super(tokenBuf,k);");
println(" tokenNames = _tokenNames;");
// if debugging, set up arrays and call the user-overridable
// debugging setup method
if ( grammar.debuggingOutput ) {
println(" ruleNames = _ruleNames;");
println(" semPredNames = _semPredNames;");
println(" setupDebugging(tokenBuf);");
}
println("}");
println("");
println("public " + grammar.getClassName() + "(TokenBuffer tokenBuf) {");
println(" this(tokenBuf," + grammar.maxk + ");");
println("}");
println("");
// Generate parser class constructor from TokenStream
println("protected " + grammar.getClassName()+"(TokenStream lexer, int k) {");
println(" super(lexer,k);");
println(" tokenNames = _tokenNames;");
// if debugging, set up arrays and call the user-overridable
// debugging setup method
if ( grammar.debuggingOutput ) {
println(" ruleNames = _ruleNames;");
println(" semPredNames = _semPredNames;");
println(" setupDebugging(lexer);");
}
println("}");
println("");
println("public " + grammar.getClassName()+"(TokenStream lexer) {");
println(" this(lexer," + grammar.maxk + ");");
println("}");
println("");
println("public " + grammar.getClassName()+"(ParserSharedInputState state) {");
println(" super(state," + grammar.maxk + ");");
println(" tokenNames = _tokenNames;");
println("}");
println("");
// Generate code for each rule in the grammar
Enumeration ids = grammar.rules.elements();
int ruleNum=0;
while ( ids.hasMoreElements() ) {
GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
if ( sym instanceof RuleSymbol) {
RuleSymbol rs = (RuleSymbol)sym;
genRule(rs, rs.references.size()==0, ruleNum++);
}
exitIfError();
}
// Generate the token names
genTokenStrings();
// Generate the bitsets used throughout the grammar
genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType());
// Generate the semantic predicate map for debugging
if (grammar.debuggingOutput)
genSemPredMap();
// Close class definition
println("");
println("}");
// Close the parser output stream
currentOutput.close();
currentOutput = null;
}
/** Generate code for the given grammar element.
* @param blk The rule-reference to generate
*/
public void gen(RuleRefElement rr) {
if ( DEBUG_CODE_GENERATOR ) System.out.println("genRR("+rr+")");
RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
if (rs == null || !rs.isDefined())
{
// Is this redundant???
tool.error("Rule '" + rr.targetRule + "' is not defined", grammar.getFilename(), rr.getLine());
return;
}
if (!(rs instanceof RuleSymbol))
{
// Is this redundant???
tool.error("'" + rr.targetRule + "' does not name a grammar rule", grammar.getFilename(), rr.getLine());
return;
}
genErrorTryForElement(rr);
// AST value for labeled rule refs in tree walker.
// This is not AST construction; it is just the input tree node value.
if ( grammar instanceof TreeWalkerGrammar &&
rr.getLabel() != null &&
syntacticPredLevel == 0 )
{
println(rr.getLabel() + " = _t==ASTNULL ? null : "+lt1Value+";");
}
// if in lexer and ! on rule ref or alt or rule, save buffer index to kill later
if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
println("_saveIndex=text.length();");
}
// Process return value assignment if any
printTabs();
if (rr.idAssign != null)
{
// Warn if the rule has no return type
if (rs.block.returnAction == null)
{
tool.warning("Rule '" + rr.targetRule + "' has no return type", grammar.getFilename(), rr.getLine());
}
_print(rr.idAssign + "=");
} else {
// Warn about return value if any, but not inside syntactic predicate
if ( !(grammar instanceof LexerGrammar) && syntacticPredLevel == 0 && rs.block.returnAction != null)
{
tool.warning("Rule '" + rr.targetRule + "' returns a value", grammar.getFilename(), rr.getLine());
}
}
// Call the rule
GenRuleInvocation(rr);
// if in lexer and ! on element or alt or rule, save buffer index to kill later
if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
println("text.setLength(_saveIndex);");
}
// if not in a syntactic predicate
if (syntacticPredLevel == 0) {
boolean doNoGuessTest = (
grammar.hasSyntacticPredicate &&
(
grammar.buildAST && rr.getLabel() != null ||
(genAST && rr.getAutoGenType() == GrammarElement.AUTO_GEN_NONE)
)
);
if (doNoGuessTest) {
println("if (inputState.guessing==0) {");
tabs++;
}
if (grammar.buildAST && rr.getLabel() != null) {
// always gen variable for rule return on labeled rules
println(rr.getLabel() + "_AST = ("+labeledElementASTType+")returnAST;");
}
if (genAST) {
switch (rr.getAutoGenType()) {
case GrammarElement.AUTO_GEN_NONE:
// println("theASTFactory.addASTChild(currentAST, returnAST);");
println("astFactory.addASTChild(currentAST, returnAST);");
break;
case GrammarElement.AUTO_GEN_CARET:
tool.error("Internal: encountered ^ after rule reference");
break;
default:
break;
}
}
// if a lexer and labeled, Token label defined at rule level, just set it here
if ( grammar instanceof LexerGrammar && rr.getLabel() != null ) {
println(rr.getLabel()+"=_returnToken;");
}
if (doNoGuessTest) {
tabs--;
println("}");
}
}
genErrorCatchForElement(rr);
}
/** Generate code for the given grammar element.
* @param blk The string-literal reference to generate
*/
public void gen(StringLiteralElement atom) {
if ( DEBUG_CODE_GENERATOR ) System.out.println("genString("+atom+")");
// Variable declarations for labeled elements
if (atom.getLabel()!=null && syntacticPredLevel == 0) {
println(atom.getLabel() + " = " + lt1Value + ";");
}
// AST
genElementAST(atom);
// is there a bang on the literal?
boolean oldsaveText = saveText;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -