📄 javacodegenerator.java
字号:
if ( alt.synPred != null ) {
println("else {");
tabs++;
genSynPred( alt.synPred, e );
closingBracesOfIFSequence++;
}
else {
println("else if " + e + " {");
}
}
else {
if ( alt.synPred != null ) {
genSynPred( alt.synPred, e );
}
else {
// when parsing trees, convert null to
// valid tree node with NULL lookahead.
if ( grammar instanceof TreeWalkerGrammar ) {
println("if (_t==null) _t=ASTNULL;");
}
println("if " + e + " {");
}
}
}
nIF++;
tabs++;
genAlt(alt, blk);
tabs--;
println("}");
}
}
String ps = "";
for (int i=1; i<=closingBracesOfIFSequence; i++) {
ps+="}";
}
// Restore the AST generation state
genAST = savegenAST;
// restore save text state
saveText=oldsaveTest;
// Return the finishing info.
if ( createdLL1Switch ) {
tabs--;
finishingInfo.postscript = ps+"}";
finishingInfo.generatedSwitch = true;
finishingInfo.generatedAnIf = nIF>0;
//return new JavaBlockFinishingInfo(ps+"}",true,nIF>0); // close up switch statement
}
else {
finishingInfo.postscript = ps;
finishingInfo.generatedSwitch = false;
finishingInfo.generatedAnIf = nIF>0;
// return new JavaBlockFinishingInfo(ps, false,nIF>0);
}
return finishingInfo;
}
private static boolean suitableForCaseExpression(Alternative a) {
return
a.lookaheadDepth == 1 &&
a.semPred == null &&
!a.cache[1].containsEpsilon() &&
a.cache[1].fset.degree()<=caseSizeThreshold;
}
/** Generate code to link an element reference into the AST */
private void genElementAST(AlternativeElement el) {
// handle case where you're not building trees, but are in tree walker.
// Just need to get labels set up.
if ( grammar instanceof TreeWalkerGrammar && !grammar.buildAST ) {
String elementRef;
String astName;
// Generate names and declarations of the AST variable(s)
if (el.getLabel() == null) {
elementRef = lt1Value;
// Generate AST variables for unlabeled stuff
astName = "tmp" + astVarNumber + "_AST";
astVarNumber++;
// Map the generated AST variable in the alternate
mapTreeVariable(el, astName);
// Generate an "input" AST variable also
println(labeledElementASTType+" "+astName+"_in = "+elementRef+";");
}
return;
}
if (grammar.buildAST && syntacticPredLevel == 0) {
boolean doNoGuessTest = (
grammar.hasSyntacticPredicate &&
(
el.getLabel() != null ||
el.getAutoGenType() != GrammarElement.AUTO_GEN_BANG
)
);
String elementRef;
String astName;
boolean willUseAST = true;
willUseAST = ((genAST && (el.getAutoGenType() == GrammarElement.AUTO_GEN_NONE)) ||
((el instanceof GrammarAtom) && (el.getAutoGenType() == GrammarElement.AUTO_GEN_CARET)) ||
el.getLabel() != null);
// Generate names and declarations of the AST variable(s)
if (el.getLabel() != null) {
elementRef = el.getLabel();
astName = el.getLabel() + "_AST";
} else {
elementRef = lt1Value;
// Generate AST variables for unlabeled stuff
astName = "tmp" + astVarNumber + "_AST";
astVarNumber++;
if(willUseAST) {
// Generate the declaration
if ( el instanceof GrammarAtom ) {
GrammarAtom ga = (GrammarAtom)el;
if ( ga.getASTNodeType()!=null ) {
println(ga.getASTNodeType()+" " + astName+" = null;");
}
else {
println(labeledElementASTType+" " + astName + " = null;");
}
}
else {
println(labeledElementASTType+" " + astName + " = null;");
}
}
// Map the generated AST variable in the alternate
mapTreeVariable(el, astName);
if (grammar instanceof TreeWalkerGrammar) {
// Generate an "input" AST variable also
println(labeledElementASTType+" " + astName + "_in = null;");
}
}
// Enclose actions with !guessing
if (doNoGuessTest) {
println("if (inputState.guessing==0) {");
tabs++;
}
if(willUseAST) {
if (el.getLabel() != null) {
if ( el instanceof GrammarAtom ) {
println(astName + " = "+ getASTCreateString((GrammarAtom)el, elementRef) + ";");
}
else {
println(astName + " = "+ getASTCreateString(elementRef) + ";");
}
} else {
elementRef = lt1Value;
if ( el instanceof GrammarAtom ) {
println(astName + " = "+ getASTCreateString((GrammarAtom)el, elementRef) + ";");
}
else {
println(astName + " = "+ getASTCreateString(elementRef) + ";");
}
// Map the generated AST variable in the alternate
if (grammar instanceof TreeWalkerGrammar) {
// set "input" AST variable also
println(astName + "_in = " + elementRef + ";");
}
}
}
else {
println(elementRef + ";");
}
if (genAST) {
switch (el.getAutoGenType()) {
case GrammarElement.AUTO_GEN_NONE:
println("astFactory.addASTChild(currentAST, " + astName + ");");
break;
case GrammarElement.AUTO_GEN_CARET:
println("astFactory.makeASTRoot(currentAST, " + astName + ");");
break;
default:
break;
}
}
if (doNoGuessTest) {
tabs--;
println("}");
}
}
}
/** Close the try block and generate catch phrases
* if the element has a labeled handler in the rule
*/
private void genErrorCatchForElement(AlternativeElement el) {
if (el.getLabel() == null) return;
String r = el.enclosingRuleName;
if ( grammar instanceof LexerGrammar ) {
r = CodeGenerator.lexerRuleName(el.enclosingRuleName);
}
RuleSymbol rs = (RuleSymbol)grammar.getSymbol(r);
if (rs == null) {
tool.panic("Enclosing rule not found!");
}
ExceptionSpec ex = rs.block.findExceptionSpec(el.getLabel());
if (ex != null) {
tabs--;
println("}");
genErrorHandler(ex);
}
}
/** Generate the catch phrases for a user-specified error handler */
private void genErrorHandler(ExceptionSpec ex) {
// Each ExceptionHandler in the ExceptionSpec is a separate catch
for (int i = 0; i < ex.handlers.size(); i++)
{
ExceptionHandler handler = (ExceptionHandler)ex.handlers.elementAt(i);
// Generate catch phrase
println("catch (" + handler.exceptionTypeAndName.getText() + ") {");
tabs++;
if (grammar.hasSyntacticPredicate) {
println("if (inputState.guessing==0) {");
tabs++;
}
// When not guessing, execute user handler action
printAction(
processActionForTreeSpecifiers(handler.action.getText(), 0, currentRule, null)
);
if (grammar.hasSyntacticPredicate) {
tabs--;
println("} else {");
tabs++;
// When guessing, rethrow exception
println(
"throw " +
extractIdOfAction(handler.exceptionTypeAndName) +
";"
);
tabs--;
println("}");
}
// Close catch phrase
tabs--;
println("}");
}
}
/** Generate a try { opening if the element has a labeled handler in the rule */
private void genErrorTryForElement(AlternativeElement el) {
if (el.getLabel() == null) return;
String r = el.enclosingRuleName;
if ( grammar instanceof LexerGrammar ) {
r = CodeGenerator.lexerRuleName(el.enclosingRuleName);
}
RuleSymbol rs = (RuleSymbol)grammar.getSymbol(r);
if (rs == null) {
tool.panic("Enclosing rule not found!");
}
ExceptionSpec ex = rs.block.findExceptionSpec(el.getLabel());
if (ex != null) {
println("try { // for error handling");
tabs++;
}
}
/** Generate a header that is common to all Java files */
protected void genHeader() {
println("// $ANTLR "+Tool.version+": "+
"\""+Tool.fileMinusPath(tool.grammarFile)+"\""+
" -> "+
"\""+grammar.getClassName()+".java\"$");
}
private void genLiteralsTest() {
println("_ttype = testLiteralsTable(_ttype);");
}
private void genLiteralsTestForPartialToken() {
println("_ttype = testLiteralsTable(new String(text.getBuffer(),_begin,text.length()-_begin),_ttype);");
}
protected void genMatch(BitSet b) {
}
protected void genMatch(GrammarAtom atom) {
if ( atom instanceof StringLiteralElement ) {
if ( grammar instanceof LexerGrammar ) {
genMatchUsingAtomText(atom);
}
else {
genMatchUsingAtomTokenType(atom);
}
}
else if ( atom instanceof CharLiteralElement ) {
if ( grammar instanceof LexerGrammar ) {
genMatchUsingAtomText(atom);
}
else {
tool.error("cannot ref character literals in grammar: "+atom);
}
}
else if ( atom instanceof TokenRefElement ) {
genMatchUsingAtomText(atom);
}
}
protected void genMatchUsingAtomText(GrammarAtom atom) {
// match() for trees needs the _t cursor
String astArgs="";
if (grammar instanceof TreeWalkerGrammar) {
astArgs="_t,";
}
// if in lexer and ! on element, save buffer index to kill later
if ( grammar instanceof LexerGrammar && (!saveText||atom.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
println("_saveIndex=text.length();");
}
print(atom.not ? "matchNot(" : "match(");
_print(astArgs);
// print out what to match
if (atom.atomText.equals("EOF")) {
// horrible hack to handle EOF case
_print("Token.EOF_TYPE");
}
else {
_print(atom.atomText);
}
_println(");");
if ( grammar instanceof LexerGrammar && (!saveText||atom.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
println("text.setLength(_saveIndex);"); // kill text atom put in buffer
}
}
protected void genMatchUsingAtomTokenType(GrammarAtom atom) {
// match() for trees needs the _t cursor
String astArgs="";
if (grammar instanceof TreeWalkerGrammar) {
astArgs="_t,";
}
// If the literal can be mangled, generate the symbolic constant instead
String mangledName = null;
String s = astArgs + getValueString(atom.getType());
// matching
println( (atom.not ? "matchNot(" : "match(") + s + ");");
}
/** Generate the nextToken() rule. nextToken() is a synthetic
* lexer rule that is the implicit OR of all user-defined
* lexer rules.
*/
public void genNextToken() {
// Are there any public rules? If not, then just generate a
// fake nextToken().
boolean hasPublicRules = false;
for (int i = 0; i < grammar.rules.size(); i++) {
RuleSymbol rs = (RuleSymbol)grammar.rules.elementAt(i);
if ( rs.isDefined() && rs.access.equals("public") ) {
hasPublicRules = true;
break;
}
}
if (!hasPublicRules) {
println("");
println("public Token nextToken() throws TokenStreamException {");
println("\ttry {uponEOF();}");
println("\tcatch(CharStreamIOException csioe) {");
println("\t\tthrow new TokenStreamIOException(csioe.io);");
println("\t}");
println("\tcatch(CharStreamException cse) {");
println("\t\tthrow new TokenStreamException(cse.getMessage());");
println("\t}");
println("\treturn new CommonToken(Token.EOF_TYPE, \"\");");
println("}");
println("");
return;
}
// Create the synthesized nextToken() rule
RuleBlock nextTokenBlk = MakeGrammar.createNextTokenRule(grammar, grammar.rules, "nextToken");
// Define the nextToken rule symbol
RuleSymbol nextTokenRs = new RuleSymbol("mnextToken");
nextTokenRs.setDefined();
nextTokenRs.setBlock(nextTokenBlk);
nextTokenRs.access = "private";
grammar.define(nextTokenRs);
// Analyze the nextToken rule
boolean ok = grammar.theLLkAnalyzer.deterministic(nextTokenBlk);
// Generate the next token rule
String filterRule=null;
if ( ((LexerGrammar
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -