Source Code Cross Referenced for CSharpCodeGenerator.java in  » Database-ORM » toplink » persistence » antlr » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » toplink » persistence.antlr 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package persistence.antlr;
0002:
0003:        /* ANTLR Translator Generator
0004:         * Project led by Terence Parr at http://www.jGuru.com
0005:         * Software rights: http://www.antlr.org/license.html
0006:         *
0007:         */
0008:
0009:        //
0010:        // ANTLR C# Code Generator by Micheal Jordan
0011:        //                            Kunle Odutola       : kunle UNDERSCORE odutola AT hotmail DOT com
0012:        //                            Anthony Oguntimehin
0013:        //
0014:        // With many thanks to Eric V. Smith from the ANTLR list.
0015:        //
0016:        // HISTORY:
0017:        //
0018:        // 17-May-2002 kunle    Fixed bug in OctalToUnicode() - was processing non-Octal escape sequences
0019:        //                      Also added namespace support based on Cpp version.
0020:        // 07-Jun-2002 kunle    Added Scott Ellis's _saveIndex creation optimizations
0021:        // 09-Sep-2002 richardN Richard Ney's bug-fix for literals table construction.
0022:        //                      [ Hashtable ctor needed instance of hash code provider not it's class name. ]
0023:        // 17-Sep-2002 kunle &  Added all Token ID definitions as data member of every Lexer/Parser/TreeParser
0024:        //             AOg      [ A by-product of problem-solving phase of the hetero-AST changes below
0025:        //                        but, it breaks nothing and restores "normal" ANTLR codegen behaviour. ]
0026:        // 19-Oct-2002 kunle &  Completed the work required to support heterogenous ASTs (many changes)
0027:        //             AOg   &
0028:        //             michealj
0029:        // 14-Nov-2002 michealj Added "initializeASTFactory()" to support flexible ASTFactory initialization.
0030:        //						[ Thanks to Ric Klaren - for suggesting it and implementing it for Cpp. ]
0031:        // 18-Nov-2002 kunle    Added fix to make xx_tokenSet_xx names CLS compliant.
0032:        // 01-Dec-2002 richardN Patch to reduce "unreachable code" warnings
0033:        // 01-Dec-2002 richardN Fix to generate correct TreeParser token-type classnames.
0034:        // 12-Jan-2002 kunle  & Generated Lexers, Parsers and TreeParsers now support ANTLR's tracing option.
0035:        //             michealj
0036:        // 12-Jan-2003 kunle    Fixed issue where initializeASTFactory() was generated when "buildAST=false"
0037:        // 14-Jan-2003 AOg      initializeASTFactory(AST factory) method was modifying the Parser's "astFactory"
0038:        //                      member rather than it's own "factory" parameter. Fixed.
0039:        // 18-Jan-2003 kunle  & Fixed reported issues with ASTFactory create() calls for hetero ASTs
0040:        //             michealj - code generated for LEXER token with hetero-AST option specified does not compile
0041:        //                      - code generated for imaginary tokens with hetero-AST option specified uses default AST type
0042:        //                      - code generated for per-TokenRef hetero-AST option specified does not compile
0043:        // 18-Jan-2003 kunle    initializeASTFactory(AST) method is now a static public member
0044:        // 18-May-2003 kunle    Changes to address outstanding reported issues::
0045:        //                      - Fixed reported issues with support for case-sensitive literals
0046:        //                      - persistence.antlr.SemanticException now imported for all Lexers.
0047:        //                        [ This exception is thrown on predicate failure. ]
0048:        // 12-Jan-2004 kunle    Added fix for reported issue with un-compileable generated lexers
0049:        //
0050:        //
0051:        import java.util.Enumeration;
0052:        import java.util.Hashtable;
0053:        import persistence.antlr.collections.impl.BitSet;
0054:        import persistence.antlr.collections.impl.Vector;
0055:        import java.io.PrintWriter; //SAS: changed for proper text file io
0056:        import java.io.IOException;
0057:        import java.io.FileWriter;
0058:
0059:        /** Generates MyParser.cs, MyLexer.cs and MyParserTokenTypes.cs */
0060:        public class CSharpCodeGenerator extends CodeGenerator {
0061:            // non-zero if inside syntactic predicate generation
0062:            protected int syntacticPredLevel = 0;
0063:
0064:            // Are we generating ASTs (for parsers and tree parsers) right now?
0065:            protected boolean genAST = false;
0066:
0067:            // Are we saving the text consumed (for lexers) right now?
0068:            protected boolean saveText = false;
0069:
0070:            // Grammar parameters set up to handle different grammar classes.
0071:            // These are used to get instanceof tests out of code generation
0072:            boolean usingCustomAST = false;
0073:            String labeledElementType;
0074:            String labeledElementASTType;
0075:            String labeledElementInit;
0076:            String commonExtraArgs;
0077:            String commonExtraParams;
0078:            String commonLocalVars;
0079:            String lt1Value;
0080:            String exceptionThrown;
0081:            String throwNoViable;
0082:
0083:            // Tracks the rule being generated.  Used for mapTreeId
0084:            RuleBlock currentRule;
0085:            // Tracks the rule or labeled subrule being generated.  Used for AST generation.
0086:            String currentASTResult;
0087:
0088:            /** Mapping between the ids used in the current alt, and the
0089:             * names of variables used to represent their AST values.
0090:             */
0091:            Hashtable treeVariableMap = new Hashtable();
0092:
0093:            /** Used to keep track of which AST variables have been defined in a rule
0094:             * (except for the #rule_name and #rule_name_in var's
0095:             */
0096:            Hashtable declaredASTVariables = new Hashtable();
0097:
0098:            /* Count of unnamed generated variables */
0099:            int astVarNumber = 1;
0100:
0101:            /** Special value used to mark duplicate in treeVariableMap */
0102:            protected static final String NONUNIQUE = new String();
0103:
0104:            public static final int caseSizeThreshold = 127; // ascii is max
0105:
0106:            private Vector semPreds;
0107:            // Used to keep track of which (heterogeneous AST types are used)
0108:            // which need to be set in the ASTFactory of the generated parser
0109:            private java.util.Vector astTypes;
0110:
0111:            private static CSharpNameSpace nameSpace = null;
0112:
0113:            // _saveIndex creation optimization -- don't create it unless we need to use it
0114:            boolean bSaveIndexCreated = false;
0115:
0116:            /** Create a CSharp code-generator using the given Grammar.
0117:             * The caller must still call setTool, setBehavior, and setAnalyzer
0118:             * before generating code.
0119:             */
0120:            public CSharpCodeGenerator() {
0121:                super ();
0122:                charFormatter = new CSharpCharFormatter();
0123:            }
0124:
0125:            /** Adds a semantic predicate string to the sem pred vector
0126:                These strings will be used to build an array of sem pred names
0127:                when building a debugging parser.  This method should only be
0128:                called when the debug option is specified
0129:             */
0130:            protected int addSemPred(String predicate) {
0131:                semPreds.appendElement(predicate);
0132:                return semPreds.size() - 1;
0133:            }
0134:
0135:            public void exitIfError() {
0136:                if (antlrTool.hasError()) {
0137:                    antlrTool.fatalError("Exiting due to errors.");
0138:                }
0139:            }
0140:
0141:            /**Generate the parser, lexer, treeparser, and token types in CSharp */
0142:            public void gen() {
0143:                // Do the code generation
0144:                try {
0145:                    // Loop over all grammars
0146:                    Enumeration grammarIter = behavior.grammars.elements();
0147:                    while (grammarIter.hasMoreElements()) {
0148:                        Grammar g = (Grammar) grammarIter.nextElement();
0149:                        // Connect all the components to each other
0150:                        g.setGrammarAnalyzer(analyzer);
0151:                        g.setCodeGenerator(this );
0152:                        analyzer.setGrammar(g);
0153:                        // To get right overloading behavior across heterogeneous grammars
0154:                        setupGrammarParameters(g);
0155:                        g.generate();
0156:                        exitIfError();
0157:                    }
0158:
0159:                    // Loop over all token managers (some of which are lexers)
0160:                    Enumeration tmIter = behavior.tokenManagers.elements();
0161:                    while (tmIter.hasMoreElements()) {
0162:                        TokenManager tm = (TokenManager) tmIter.nextElement();
0163:                        if (!tm.isReadOnly()) {
0164:                            // Write the token manager tokens as CSharp
0165:                            // this must appear before genTokenInterchange so that
0166:                            // labels are set on string literals
0167:                            genTokenTypes(tm);
0168:                            // Write the token manager tokens as plain text
0169:                            genTokenInterchange(tm);
0170:                        }
0171:                        exitIfError();
0172:                    }
0173:                } catch (IOException e) {
0174:                    antlrTool.reportException(e, null);
0175:                }
0176:            }
0177:
0178:            /** Generate code for the given grammar element.
0179:             * @param blk The {...} action to generate
0180:             */
0181:            public void gen(ActionElement action) {
0182:                if (DEBUG_CODE_GENERATOR)
0183:                    System.out.println("genAction(" + action + ")");
0184:                if (action.isSemPred) {
0185:                    genSemPred(action.actionText, action.line);
0186:                } else {
0187:                    if (grammar.hasSyntacticPredicate) {
0188:                        println("if (0==inputState.guessing)");
0189:                        println("{");
0190:                        tabs++;
0191:                    }
0192:
0193:                    ActionTransInfo tInfo = new ActionTransInfo();
0194:                    String actionStr = processActionForSpecialSymbols(
0195:                            action.actionText, action.getLine(), currentRule,
0196:                            tInfo);
0197:
0198:                    if (tInfo.refRuleRoot != null) {
0199:                        // Somebody referenced "#rule", make sure translated var is valid
0200:                        // assignment to #rule is left as a ref also, meaning that assignments
0201:                        // with no other refs like "#rule = foo();" still forces this code to be
0202:                        // generated (unnecessarily).
0203:                        println(tInfo.refRuleRoot + " = ("
0204:                                + labeledElementASTType + ")currentAST.root;");
0205:                    }
0206:
0207:                    // dump the translated action
0208:                    printAction(actionStr);
0209:
0210:                    if (tInfo.assignToRoot) {
0211:                        // Somebody did a "#rule=", reset internal currentAST.root
0212:                        println("currentAST.root = " + tInfo.refRuleRoot + ";");
0213:                        // reset the child pointer too to be last sibling in sibling list
0214:                        println("if ( (null != " + tInfo.refRuleRoot
0215:                                + ") && (null != " + tInfo.refRuleRoot
0216:                                + ".getFirstChild()) )");
0217:                        tabs++;
0218:                        println("currentAST.child = " + tInfo.refRuleRoot
0219:                                + ".getFirstChild();");
0220:                        tabs--;
0221:                        println("else");
0222:                        tabs++;
0223:                        println("currentAST.child = " + tInfo.refRuleRoot + ";");
0224:                        tabs--;
0225:                        println("currentAST.advanceChildToEnd();");
0226:                    }
0227:
0228:                    if (grammar.hasSyntacticPredicate) {
0229:                        tabs--;
0230:                        println("}");
0231:                    }
0232:                }
0233:            }
0234:
0235:            /** Generate code for the given grammar element.
0236:             * @param blk The "x|y|z|..." block to generate
0237:             */
0238:            public void gen(AlternativeBlock blk) {
0239:                if (DEBUG_CODE_GENERATOR)
0240:                    System.out.println("gen(" + blk + ")");
0241:                println("{");
0242:                tabs++;
0243:
0244:                genBlockPreamble(blk);
0245:                genBlockInitAction(blk);
0246:
0247:                // Tell AST generation to build subrule result
0248:                String saveCurrentASTResult = currentASTResult;
0249:                if (blk.getLabel() != null) {
0250:                    currentASTResult = blk.getLabel();
0251:                }
0252:
0253:                boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
0254:
0255:                CSharpBlockFinishingInfo howToFinish = genCommonBlock(blk, true);
0256:                genBlockFinish(howToFinish, throwNoViable);
0257:
0258:                tabs--;
0259:                println("}");
0260:
0261:                // Restore previous AST generation
0262:                currentASTResult = saveCurrentASTResult;
0263:            }
0264:
0265:            /** Generate code for the given grammar element.
0266:             * @param blk The block-end element to generate.  Block-end
0267:             * elements are synthesized by the grammar parser to represent
0268:             * the end of a block.
0269:             */
0270:            public void gen(BlockEndElement end) {
0271:                if (DEBUG_CODE_GENERATOR)
0272:                    System.out.println("genRuleEnd(" + end + ")");
0273:            }
0274:
0275:            /** Generate code for the given grammar element.
0276:             * @param blk The character literal reference to generate
0277:             */
0278:            public void gen(CharLiteralElement atom) {
0279:                if (DEBUG_CODE_GENERATOR)
0280:                    System.out.println("genChar(" + atom + ")");
0281:
0282:                if (atom.getLabel() != null) {
0283:                    println(atom.getLabel() + " = " + lt1Value + ";");
0284:                }
0285:
0286:                boolean oldsaveText = saveText;
0287:                saveText = saveText
0288:                        && atom.getAutoGenType() == GrammarElement.AUTO_GEN_NONE;
0289:                genMatch(atom);
0290:                saveText = oldsaveText;
0291:            }
0292:
0293:            /** Generate code for the given grammar element.
0294:             * @param blk The character-range reference to generate
0295:             */
0296:            public void gen(CharRangeElement r) {
0297:                if (r.getLabel() != null && syntacticPredLevel == 0) {
0298:                    println(r.getLabel() + " = " + lt1Value + ";");
0299:                }
0300:                boolean flag = (grammar instanceof  LexerGrammar && (!saveText || (r
0301:                        .getAutoGenType() == GrammarElement.AUTO_GEN_BANG)));
0302:                if (flag)
0303:                    println("_saveIndex = text.Length;");
0304:
0305:                println("matchRange(" + OctalToUnicode(r.beginText) + ","
0306:                        + OctalToUnicode(r.endText) + ");");
0307:
0308:                if (flag)
0309:                    println("text.Length = _saveIndex;");
0310:            }
0311:
0312:            /** Generate the lexer CSharp file */
0313:            public void gen(LexerGrammar g) throws IOException {
0314:                // If debugging, create a new sempred vector for this grammar
0315:                if (g.debuggingOutput)
0316:                    semPreds = new Vector();
0317:
0318:                setGrammar(g);
0319:                if (!(grammar instanceof  LexerGrammar)) {
0320:                    antlrTool.panic("Internal error generating lexer");
0321:                }
0322:                genBody(g);
0323:            }
0324:
0325:            /** Generate code for the given grammar element.
0326:             * @param blk The (...)+ block to generate
0327:             */
0328:            public void gen(OneOrMoreBlock blk) {
0329:                if (DEBUG_CODE_GENERATOR)
0330:                    System.out.println("gen+(" + blk + ")");
0331:                String label;
0332:                String cnt;
0333:                println("{ // ( ... )+");
0334:                genBlockPreamble(blk);
0335:                if (blk.getLabel() != null) {
0336:                    cnt = "_cnt_" + blk.getLabel();
0337:                } else {
0338:                    cnt = "_cnt" + blk.ID;
0339:                }
0340:                println("int " + cnt + "=0;");
0341:                if (blk.getLabel() != null) {
0342:                    label = blk.getLabel();
0343:                } else {
0344:                    label = "_loop" + blk.ID;
0345:                }
0346:
0347:                println("for (;;)");
0348:                println("{");
0349:                tabs++;
0350:                // generate the init action for ()+ ()* inside the loop
0351:                // this allows us to do usefull EOF checking...
0352:                genBlockInitAction(blk);
0353:
0354:                // Tell AST generation to build subrule result
0355:                String saveCurrentASTResult = currentASTResult;
0356:                if (blk.getLabel() != null) {
0357:                    currentASTResult = blk.getLabel();
0358:                }
0359:
0360:                boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
0361:
0362:                // generate exit test if greedy set to false
0363:                // and an alt is ambiguous with exit branch
0364:                // or when lookahead derived purely from end-of-file
0365:                // Lookahead analysis stops when end-of-file is hit,
0366:                // returning set {epsilon}.  Since {epsilon} is not
0367:                // ambig with any real tokens, no error is reported
0368:                // by deterministic() routines and we have to check
0369:                // for the case where the lookahead depth didn't get
0370:                // set to NONDETERMINISTIC (this only happens when the
0371:                // FOLLOW contains real atoms + epsilon).
0372:                boolean generateNonGreedyExitPath = false;
0373:                int nonGreedyExitDepth = grammar.maxk;
0374:
0375:                if (!blk.greedy
0376:                        && blk.exitLookaheadDepth <= grammar.maxk
0377:                        && blk.exitCache[blk.exitLookaheadDepth]
0378:                                .containsEpsilon()) {
0379:                    generateNonGreedyExitPath = true;
0380:                    nonGreedyExitDepth = blk.exitLookaheadDepth;
0381:                } else if (!blk.greedy
0382:                        && blk.exitLookaheadDepth == LLkGrammarAnalyzer.NONDETERMINISTIC) {
0383:                    generateNonGreedyExitPath = true;
0384:                }
0385:
0386:                // generate exit test if greedy set to false
0387:                // and an alt is ambiguous with exit branch
0388:                if (generateNonGreedyExitPath) {
0389:                    if (DEBUG_CODE_GENERATOR) {
0390:                        System.out
0391:                                .println("nongreedy (...)+ loop; exit depth is "
0392:                                        + blk.exitLookaheadDepth);
0393:                    }
0394:                    String predictExit = getLookaheadTestExpression(
0395:                            blk.exitCache, nonGreedyExitDepth);
0396:                    println("// nongreedy exit test");
0397:                    println("if ((" + cnt + " >= 1) && " + predictExit
0398:                            + ") goto " + label + "_breakloop;");
0399:                }
0400:
0401:                CSharpBlockFinishingInfo howToFinish = genCommonBlock(blk,
0402:                        false);
0403:                genBlockFinish(howToFinish, "if (" + cnt + " >= 1) { goto "
0404:                        + label + "_breakloop; } else { " + throwNoViable
0405:                        + "; }");
0406:
0407:                println(cnt + "++;");
0408:                tabs--;
0409:                println("}");
0410:                _print(label + "_breakloop:");
0411:                println(";");
0412:                println("}    // ( ... )+");
0413:
0414:                // Restore previous AST generation
0415:                currentASTResult = saveCurrentASTResult;
0416:            }
0417:
0418:            /** Generate the parser CSharp file */
0419:            public void gen(ParserGrammar g) throws IOException {
0420:
0421:                // if debugging, set up a new vector to keep track of sempred
0422:                //   strings for this grammar
0423:                if (g.debuggingOutput)
0424:                    semPreds = new Vector();
0425:
0426:                setGrammar(g);
0427:                if (!(grammar instanceof  ParserGrammar)) {
0428:                    antlrTool.panic("Internal error generating parser");
0429:                }
0430:                genBody(g);
0431:            }
0432:
0433:            /** Generate code for the given grammar element.
0434:             * @param blk The rule-reference to generate
0435:             */
0436:            public void gen(RuleRefElement rr) {
0437:                if (DEBUG_CODE_GENERATOR)
0438:                    System.out.println("genRR(" + rr + ")");
0439:                RuleSymbol rs = (RuleSymbol) grammar.getSymbol(rr.targetRule);
0440:                if (rs == null || !rs.isDefined()) {
0441:                    // Is this redundant???
0442:                    antlrTool.error("Rule '" + rr.targetRule
0443:                            + "' is not defined", grammar.getFilename(), rr
0444:                            .getLine(), rr.getColumn());
0445:                    return;
0446:                }
0447:                if (!(rs instanceof  RuleSymbol)) {
0448:                    // Is this redundant???
0449:                    antlrTool.error("'" + rr.targetRule
0450:                            + "' does not name a grammar rule", grammar
0451:                            .getFilename(), rr.getLine(), rr.getColumn());
0452:                    return;
0453:                }
0454:
0455:                genErrorTryForElement(rr);
0456:
0457:                // AST value for labeled rule refs in tree walker.
0458:                // This is not AST construction;  it is just the input tree node value.
0459:                if (grammar instanceof  TreeWalkerGrammar
0460:                        && rr.getLabel() != null && syntacticPredLevel == 0) {
0461:                    println(rr.getLabel() + " = _t==ASTNULL ? null : "
0462:                            + lt1Value + ";");
0463:                }
0464:
0465:                // if in lexer and ! on rule ref or alt or rule, save buffer index to kill later
0466:                if (grammar instanceof  LexerGrammar
0467:                        && (!saveText || rr.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
0468:                    declareSaveIndexVariableIfNeeded();
0469:                    println("_saveIndex = text.Length;");
0470:                }
0471:
0472:                // Process return value assignment if any
0473:                printTabs();
0474:                if (rr.idAssign != null) {
0475:                    // Warn if the rule has no return type
0476:                    if (rs.block.returnAction == null) {
0477:                        antlrTool.warning("Rule '" + rr.targetRule
0478:                                + "' has no return type",
0479:                                grammar.getFilename(), rr.getLine(), rr
0480:                                        .getColumn());
0481:                    }
0482:                    _print(rr.idAssign + "=");
0483:                } else {
0484:                    // Warn about return value if any, but not inside syntactic predicate
0485:                    if (!(grammar instanceof  LexerGrammar)
0486:                            && syntacticPredLevel == 0
0487:                            && rs.block.returnAction != null) {
0488:                        antlrTool.warning("Rule '" + rr.targetRule
0489:                                + "' returns a value", grammar.getFilename(),
0490:                                rr.getLine(), rr.getColumn());
0491:                    }
0492:                }
0493:
0494:                // Call the rule
0495:                GenRuleInvocation(rr);
0496:
0497:                // if in lexer and ! on element or alt or rule, save buffer index to kill later
0498:                if (grammar instanceof  LexerGrammar
0499:                        && (!saveText || rr.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
0500:                    declareSaveIndexVariableIfNeeded();
0501:                    println("text.Length = _saveIndex;");
0502:                }
0503:
0504:                // if not in a syntactic predicate
0505:                if (syntacticPredLevel == 0) {
0506:                    boolean doNoGuessTest = (grammar.hasSyntacticPredicate && (grammar.buildAST
0507:                            && rr.getLabel() != null || (genAST && rr
0508:                            .getAutoGenType() == GrammarElement.AUTO_GEN_NONE)));
0509:                    if (doNoGuessTest) {
0510:                        println("if (0 == inputState.guessing)");
0511:                        println("{");
0512:                        tabs++;
0513:                    }
0514:
0515:                    if (grammar.buildAST && rr.getLabel() != null) {
0516:                        // always gen variable for rule return on labeled rules
0517:                        println(rr.getLabel() + "_AST = ("
0518:                                + labeledElementASTType + ")returnAST;");
0519:                    }
0520:                    if (genAST) {
0521:                        switch (rr.getAutoGenType()) {
0522:                        case GrammarElement.AUTO_GEN_NONE:
0523:                            if (usingCustomAST)
0524:                                println("astFactory.addASTChild(currentAST, (AST)returnAST);");
0525:                            else
0526:                                println("astFactory.addASTChild(currentAST, returnAST);");
0527:                            break;
0528:                        case GrammarElement.AUTO_GEN_CARET:
0529:                            antlrTool
0530:                                    .error("Internal: encountered ^ after rule reference");
0531:                            break;
0532:                        default:
0533:                            break;
0534:                        }
0535:                    }
0536:
0537:                    // if a lexer and labeled, Token label defined at rule level, just set it here
0538:                    if (grammar instanceof  LexerGrammar
0539:                            && rr.getLabel() != null) {
0540:                        println(rr.getLabel() + " = returnToken_;");
0541:                    }
0542:
0543:                    if (doNoGuessTest) {
0544:                        tabs--;
0545:                        println("}");
0546:                    }
0547:                }
0548:                genErrorCatchForElement(rr);
0549:            }
0550:
0551:            /** Generate code for the given grammar element.
0552:             * @param blk The string-literal reference to generate
0553:             */
0554:            public void gen(StringLiteralElement atom) {
0555:                if (DEBUG_CODE_GENERATOR)
0556:                    System.out.println("genString(" + atom + ")");
0557:
0558:                // Variable declarations for labeled elements
0559:                if (atom.getLabel() != null && syntacticPredLevel == 0) {
0560:                    println(atom.getLabel() + " = " + lt1Value + ";");
0561:                }
0562:
0563:                // AST
0564:                genElementAST(atom);
0565:
0566:                // is there a bang on the literal?
0567:                boolean oldsaveText = saveText;
0568:                saveText = saveText
0569:                        && atom.getAutoGenType() == GrammarElement.AUTO_GEN_NONE;
0570:
0571:                // matching
0572:                genMatch(atom);
0573:
0574:                saveText = oldsaveText;
0575:
0576:                // tack on tree cursor motion if doing a tree walker
0577:                if (grammar instanceof  TreeWalkerGrammar) {
0578:                    println("_t = _t.getNextSibling();");
0579:                }
0580:            }
0581:
0582:            /** Generate code for the given grammar element.
0583:             * @param blk The token-range reference to generate
0584:             */
0585:            public void gen(TokenRangeElement r) {
0586:                genErrorTryForElement(r);
0587:                if (r.getLabel() != null && syntacticPredLevel == 0) {
0588:                    println(r.getLabel() + " = " + lt1Value + ";");
0589:                }
0590:
0591:                // AST
0592:                genElementAST(r);
0593:
0594:                // match
0595:                println("matchRange(" + OctalToUnicode(r.beginText) + ","
0596:                        + OctalToUnicode(r.endText) + ");");
0597:                genErrorCatchForElement(r);
0598:            }
0599:
0600:            /** Generate code for the given grammar element.
0601:             * @param blk The token-reference to generate
0602:             */
0603:            public void gen(TokenRefElement atom) {
0604:                if (DEBUG_CODE_GENERATOR)
0605:                    System.out.println("genTokenRef(" + atom + ")");
0606:                if (grammar instanceof  LexerGrammar) {
0607:                    antlrTool.panic("Token reference found in lexer");
0608:                }
0609:                genErrorTryForElement(atom);
0610:                // Assign Token value to token label variable
0611:                if (atom.getLabel() != null && syntacticPredLevel == 0) {
0612:                    println(atom.getLabel() + " = " + lt1Value + ";");
0613:                }
0614:
0615:                // AST
0616:                genElementAST(atom);
0617:                // matching
0618:                genMatch(atom);
0619:                genErrorCatchForElement(atom);
0620:
0621:                // tack on tree cursor motion if doing a tree walker
0622:                if (grammar instanceof  TreeWalkerGrammar) {
0623:                    println("_t = _t.getNextSibling();");
0624:                }
0625:            }
0626:
0627:            public void gen(TreeElement t) {
0628:                // save AST cursor
0629:                println("AST __t" + t.ID + " = _t;");
0630:
0631:                // If there is a label on the root, then assign that to the variable
0632:                if (t.root.getLabel() != null) {
0633:                    println(t.root.getLabel() + " = (ASTNULL == _t) ? null : ("
0634:                            + labeledElementASTType + ")_t;");
0635:                }
0636:
0637:                // check for invalid modifiers ! and ^ on tree element roots
0638:                if (t.root.getAutoGenType() == GrammarElement.AUTO_GEN_BANG) {
0639:                    antlrTool
0640:                            .error(
0641:                                    "Suffixing a root node with '!' is not implemented",
0642:                                    grammar.getFilename(), t.getLine(), t
0643:                                            .getColumn());
0644:                    t.root.setAutoGenType(GrammarElement.AUTO_GEN_NONE);
0645:                }
0646:                if (t.root.getAutoGenType() == GrammarElement.AUTO_GEN_CARET) {
0647:                    antlrTool
0648:                            .warning(
0649:                                    "Suffixing a root node with '^' is redundant; already a root",
0650:                                    grammar.getFilename(), t.getLine(), t
0651:                                            .getColumn());
0652:                    t.root.setAutoGenType(GrammarElement.AUTO_GEN_NONE);
0653:                }
0654:
0655:                // Generate AST variables
0656:                genElementAST(t.root);
0657:                if (grammar.buildAST) {
0658:                    // Save the AST construction state
0659:                    println("ASTPair __currentAST" + t.ID
0660:                            + " = currentAST.copy();");
0661:                    // Make the next item added a child of the TreeElement root
0662:                    println("currentAST.root = currentAST.child;");
0663:                    println("currentAST.child = null;");
0664:                }
0665:
0666:                // match root
0667:                if (t.root instanceof  WildcardElement) {
0668:                    println("if (null == _t) throw new MismatchedTokenException();");
0669:                } else {
0670:                    genMatch(t.root);
0671:                }
0672:                // move to list of children
0673:                println("_t = _t.getFirstChild();");
0674:
0675:                // walk list of children, generating code for each
0676:                for (int i = 0; i < t.getAlternatives().size(); i++) {
0677:                    Alternative a = t.getAlternativeAt(i);
0678:                    AlternativeElement e = a.head;
0679:                    while (e != null) {
0680:                        e.generate();
0681:                        e = e.next;
0682:                    }
0683:                }
0684:
0685:                if (grammar.buildAST) {
0686:                    // restore the AST construction state to that just after the
0687:                    // tree root was added
0688:                    println("currentAST = __currentAST" + t.ID + ";");
0689:                }
0690:                // restore AST cursor
0691:                println("_t = __t" + t.ID + ";");
0692:                // move cursor to sibling of tree just parsed
0693:                println("_t = _t.getNextSibling();");
0694:            }
0695:
0696:            /** Generate the tree-parser CSharp file */
0697:            public void gen(TreeWalkerGrammar g) throws IOException {
0698:                // SAS: debugging stuff removed for now...
0699:                setGrammar(g);
0700:                if (!(grammar instanceof  TreeWalkerGrammar)) {
0701:                    antlrTool.panic("Internal error generating tree-walker");
0702:                }
0703:                genBody(g);
0704:            }
0705:
0706:            /** Generate code for the given grammar element.
0707:             * @param wc The wildcard element to generate
0708:             */
0709:            public void gen(WildcardElement wc) {
0710:                // Variable assignment for labeled elements
0711:                if (wc.getLabel() != null && syntacticPredLevel == 0) {
0712:                    println(wc.getLabel() + " = " + lt1Value + ";");
0713:                }
0714:
0715:                // AST
0716:                genElementAST(wc);
0717:                // Match anything but EOF
0718:                if (grammar instanceof  TreeWalkerGrammar) {
0719:                    println("if (null == _t) throw new MismatchedTokenException();");
0720:                } else if (grammar instanceof  LexerGrammar) {
0721:                    if (grammar instanceof  LexerGrammar
0722:                            && (!saveText || wc.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
0723:                        declareSaveIndexVariableIfNeeded();
0724:                        println("_saveIndex = text.Length;");
0725:                    }
0726:                    println("matchNot(EOF/*_CHAR*/);");
0727:                    if (grammar instanceof  LexerGrammar
0728:                            && (!saveText || wc.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
0729:                        declareSaveIndexVariableIfNeeded();
0730:                        println("text.Length = _saveIndex;"); // kill text atom put in buffer
0731:                    }
0732:                } else {
0733:                    println("matchNot(" + getValueString(Token.EOF_TYPE) + ");");
0734:                }
0735:
0736:                // tack on tree cursor motion if doing a tree walker
0737:                if (grammar instanceof  TreeWalkerGrammar) {
0738:                    println("_t = _t.getNextSibling();");
0739:                }
0740:            }
0741:
0742:            /** Generate code for the given grammar element.
0743:             * @param blk The (...)* block to generate
0744:             */
0745:            public void gen(ZeroOrMoreBlock blk) {
0746:                if (DEBUG_CODE_GENERATOR)
0747:                    System.out.println("gen*(" + blk + ")");
0748:                println("{    // ( ... )*");
0749:                tabs++;
0750:                genBlockPreamble(blk);
0751:                String label;
0752:                if (blk.getLabel() != null) {
0753:                    label = blk.getLabel();
0754:                } else {
0755:                    label = "_loop" + blk.ID;
0756:                }
0757:                println("for (;;)");
0758:                println("{");
0759:                tabs++;
0760:                // generate the init action for ()+ ()* inside the loop
0761:                // this allows us to do usefull EOF checking...
0762:                genBlockInitAction(blk);
0763:
0764:                // Tell AST generation to build subrule result
0765:                String saveCurrentASTResult = currentASTResult;
0766:                if (blk.getLabel() != null) {
0767:                    currentASTResult = blk.getLabel();
0768:                }
0769:
0770:                boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
0771:
0772:                // generate exit test if greedy set to false
0773:                // and an alt is ambiguous with exit branch
0774:                // or when lookahead derived purely from end-of-file
0775:                // Lookahead analysis stops when end-of-file is hit,
0776:                // returning set {epsilon}.  Since {epsilon} is not
0777:                // ambig with any real tokens, no error is reported
0778:                // by deterministic() routines and we have to check
0779:                // for the case where the lookahead depth didn't get
0780:                // set to NONDETERMINISTIC (this only happens when the
0781:                // FOLLOW contains real atoms + epsilon).
0782:                boolean generateNonGreedyExitPath = false;
0783:                int nonGreedyExitDepth = grammar.maxk;
0784:
0785:                if (!blk.greedy
0786:                        && blk.exitLookaheadDepth <= grammar.maxk
0787:                        && blk.exitCache[blk.exitLookaheadDepth]
0788:                                .containsEpsilon()) {
0789:                    generateNonGreedyExitPath = true;
0790:                    nonGreedyExitDepth = blk.exitLookaheadDepth;
0791:                } else if (!blk.greedy
0792:                        && blk.exitLookaheadDepth == LLkGrammarAnalyzer.NONDETERMINISTIC) {
0793:                    generateNonGreedyExitPath = true;
0794:                }
0795:                if (generateNonGreedyExitPath) {
0796:                    if (DEBUG_CODE_GENERATOR) {
0797:                        System.out
0798:                                .println("nongreedy (...)* loop; exit depth is "
0799:                                        + blk.exitLookaheadDepth);
0800:                    }
0801:                    String predictExit = getLookaheadTestExpression(
0802:                            blk.exitCache, nonGreedyExitDepth);
0803:                    println("// nongreedy exit test");
0804:                    println("if (" + predictExit + ") goto " + label
0805:                            + "_breakloop;");
0806:                }
0807:
0808:                CSharpBlockFinishingInfo howToFinish = genCommonBlock(blk,
0809:                        false);
0810:                genBlockFinish(howToFinish, "goto " + label + "_breakloop;");
0811:
0812:                tabs--;
0813:                println("}");
0814:                _print(label + "_breakloop:");
0815:                println(";");
0816:                tabs--;
0817:                println("}    // ( ... )*");
0818:
0819:                // Restore previous AST generation
0820:                currentASTResult = saveCurrentASTResult;
0821:            }
0822:
0823:            /** Generate an alternative.
0824:             * @param alt  The alternative to generate
0825:             * @param blk The block to which the alternative belongs
0826:             */
0827:            protected void genAlt(Alternative alt, AlternativeBlock blk) {
0828:                // Save the AST generation state, and set it to that of the alt
0829:                boolean savegenAST = genAST;
0830:                genAST = genAST && alt.getAutoGen();
0831:
0832:                boolean oldsaveTest = saveText;
0833:                saveText = saveText && alt.getAutoGen();
0834:
0835:                // Reset the variable name map for the alternative
0836:                Hashtable saveMap = treeVariableMap;
0837:                treeVariableMap = new Hashtable();
0838:
0839:                // Generate try block around the alt for  error handling
0840:                if (alt.exceptionSpec != null) {
0841:                    println("try        // for error handling");
0842:                    println("{");
0843:                    tabs++;
0844:                }
0845:
0846:                AlternativeElement elem = alt.head;
0847:                while (!(elem instanceof  BlockEndElement)) {
0848:                    elem.generate(); // alt can begin with anything. Ask target to gen.
0849:                    elem = elem.next;
0850:                }
0851:
0852:                if (genAST) {
0853:                    if (blk instanceof  RuleBlock) {
0854:                        // Set the AST return value for the rule
0855:                        RuleBlock rblk = (RuleBlock) blk;
0856:                        if (usingCustomAST) {
0857:                            println(rblk.getRuleName() + "_AST = ("
0858:                                    + labeledElementASTType
0859:                                    + ")currentAST.root;");
0860:                        } else {
0861:                            println(rblk.getRuleName()
0862:                                    + "_AST = currentAST.root;");
0863:                        }
0864:                    } else if (blk.getLabel() != null) {
0865:                        // ### future: also set AST value for labeled subrules.
0866:                        // println(blk.getLabel() + "_AST = ("+labeledElementASTType+")currentAST.root;");
0867:                        antlrTool.warning("Labeled subrules not yet supported",
0868:                                grammar.getFilename(), blk.getLine(), blk
0869:                                        .getColumn());
0870:                    }
0871:                }
0872:
0873:                if (alt.exceptionSpec != null) {
0874:                    // close try block
0875:                    tabs--;
0876:                    println("}");
0877:                    genErrorHandler(alt.exceptionSpec);
0878:                }
0879:
0880:                genAST = savegenAST;
0881:                saveText = oldsaveTest;
0882:
0883:                treeVariableMap = saveMap;
0884:            }
0885:
0886:            /** Generate all the bitsets to be used in the parser or lexer
0887:             * Generate the raw bitset data like "long _tokenSet1_data[] = {...};"
0888:             * and the BitSet object declarations like "BitSet _tokenSet1 = new BitSet(_tokenSet1_data);"
0889:             * Note that most languages do not support object initialization inside a
0890:             * class definition, so other code-generators may have to separate the
0891:             * bitset declarations from the initializations (e.g., put the initializations
0892:             * in the generated constructor instead).
0893:             * @param bitsetList The list of bitsets to generate.
0894:             * @param maxVocabulary Ensure that each generated bitset can contain at least this value.
0895:             */
0896:            protected void genBitsets(Vector bitsetList, int maxVocabulary) {
0897:                println("");
0898:                for (int i = 0; i < bitsetList.size(); i++) {
0899:                    BitSet p = (BitSet) bitsetList.elementAt(i);
0900:                    // Ensure that generated BitSet is large enough for vocabulary
0901:                    p.growToInclude(maxVocabulary);
0902:                    genBitSet(p, i);
0903:                }
0904:            }
0905:
0906:            /** Do something simple like:
0907:             *  private static final long[] mk_tokenSet_0() {
0908:             *    long[] data = { -2305839160922996736L, 63L, 16777216L, 0L, 0L, 0L };
0909:             *    return data;
0910:             *  }
0911:             *  public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0());
0912:             *
0913:             *  Or, for large bitsets, optimize init so ranges are collapsed into loops.
0914:             *  This is most useful for lexers using unicode.
0915:             */
0916:            private void genBitSet(BitSet p, int id) {
0917:                // initialization data
0918:                println("private static long[] mk_" + getBitsetName(id) + "()");
0919:                println("{");
0920:                tabs++;
0921:                int n = p.lengthInLongWords();
0922:                if (n < BITSET_OPTIMIZE_INIT_THRESHOLD) {
0923:                    println("long[] data = { " + p.toStringOfWords() + "};");
0924:                } else {
0925:                    // will init manually, allocate space then set values
0926:                    println("long[] data = new long[" + n + "];");
0927:                    long[] elems = p.toPackedArray();
0928:                    for (int i = 0; i < elems.length;) {
0929:                        if ((i + 1) == elems.length || elems[i] != elems[i + 1]) {
0930:                            // last number or no run of numbers, just dump assignment
0931:                            println("data[" + i + "]=" + elems[i] + "L;");
0932:                            i++;
0933:                        } else {
0934:                            // scan to find end of run
0935:                            int j;
0936:                            for (j = i + 1; j < elems.length
0937:                                    && elems[j] == elems[i]; j++) {
0938:                                ;
0939:                            }
0940:                            // j-1 is last member of run
0941:                            println("for (int i = " + i + "; i<=" + (j - 1)
0942:                                    + "; i++) { data[i]=" + elems[i] + "L; }");
0943:                            i = j;
0944:                        }
0945:                    }
0946:                }
0947:
0948:                println("return data;");
0949:                tabs--;
0950:                println("}");
0951:                // BitSet object
0952:                println("public static readonly BitSet " + getBitsetName(id)
0953:                        + " = new BitSet(" + "mk_" + getBitsetName(id) + "()"
0954:                        + ");");
0955:            }
0956:
0957:            /** Given the index of a bitset in the bitset list, generate a unique name.
0958:             * Specific code-generators may want to override this
0959:             * if the language does not allow '_' or numerals in identifiers.
0960:             * @param index  The index of the bitset in the bitset list.
0961:             */
0962:            protected String getBitsetName(int index) {
0963:                return "tokenSet_" + index + "_";
0964:            }
0965:
0966:            /** Generate the finish of a block, using a combination of the info
0967:             * returned from genCommonBlock() and the action to perform when
0968:             * no alts were taken
0969:             * @param howToFinish The return of genCommonBlock()
0970:             * @param noViableAction What to generate when no alt is taken
0971:             */
0972:            private void genBlockFinish(CSharpBlockFinishingInfo howToFinish,
0973:                    String noViableAction) {
0974:
0975:                if (howToFinish.needAnErrorClause
0976:                        && (howToFinish.generatedAnIf || howToFinish.generatedSwitch)) {
0977:                    if (howToFinish.generatedAnIf) {
0978:                        println("else");
0979:                        println("{");
0980:                    } else {
0981:                        println("{");
0982:                    }
0983:                    tabs++;
0984:                    println(noViableAction);
0985:                    tabs--;
0986:                    println("}");
0987:                }
0988:
0989:                if (howToFinish.postscript != null) {
0990:                    if (howToFinish.needAnErrorClause
0991:                            && howToFinish.generatedSwitch
0992:                            && !howToFinish.generatedAnIf
0993:                            && noViableAction != null) {
0994:                        // Check to make sure that noViableAction is only a throw statement
0995:                        if (noViableAction.indexOf("throw") == 0
0996:                                || noViableAction.indexOf("goto") == 0) {
0997:                            // Remove the break statement since it isn't reachable with a throw exception
0998:                            int endOfBreak = howToFinish.postscript
0999:                                    .indexOf("break;") + 6;
1000:                            String newPostScript = howToFinish.postscript
1001:                                    .substring(endOfBreak);
1002:                            println(newPostScript);
1003:                        } else {
1004:                            println(howToFinish.postscript);
1005:                        }
1006:                    } else {
1007:                        println(howToFinish.postscript);
1008:                    }
1009:                }
1010:            }
1011:
1012:            /** Generate the init action for a block, which may be a RuleBlock or a
1013:             * plain AlternativeBLock.
1014:             * @blk The block for which the preamble is to be generated.
1015:             */
1016:            protected void genBlockInitAction(AlternativeBlock blk) {
1017:                // dump out init action
1018:                if (blk.initAction != null) {
1019:                    printAction(processActionForSpecialSymbols(blk.initAction,
1020:                            blk.getLine(), currentRule, null));
1021:                }
1022:            }
1023:
1024:            /** Generate the header for a block, which may be a RuleBlock or a
1025:             * plain AlternativeBLock.  This generates any variable declarations
1026:             * and syntactic-predicate-testing variables.
1027:             * @blk The block for which the preamble is to be generated.
1028:             */
1029:            protected void genBlockPreamble(AlternativeBlock blk) {
1030:                // define labels for rule blocks.
1031:                if (blk instanceof  RuleBlock) {
1032:                    RuleBlock rblk = (RuleBlock) blk;
1033:                    if (rblk.labeledElements != null) {
1034:                        for (int i = 0; i < rblk.labeledElements.size(); i++) {
1035:
1036:                            AlternativeElement a = (AlternativeElement) rblk.labeledElements
1037:                                    .elementAt(i);
1038:                            //System.out.println("looking at labeled element: "+a);
1039:                            //Variables for labeled rule refs and
1040:                            //subrules are different than variables for
1041:                            //grammar atoms.  This test is a little tricky
1042:                            //because we want to get all rule refs and ebnf,
1043:                            //but not rule blocks or syntactic predicates
1044:                            if (a instanceof  RuleRefElement
1045:                                    || a instanceof  AlternativeBlock
1046:                                    && !(a instanceof  RuleBlock)
1047:                                    && !(a instanceof  SynPredBlock)) {
1048:
1049:                                if (!(a instanceof  RuleRefElement)
1050:                                        && ((AlternativeBlock) a).not
1051:                                        && analyzer
1052:                                                .subruleCanBeInverted(
1053:                                                        ((AlternativeBlock) a),
1054:                                                        grammar instanceof  LexerGrammar)) {
1055:                                    // Special case for inverted subrules that
1056:                                    // will be inlined.  Treat these like
1057:                                    // token or char literal references
1058:                                    println(labeledElementType + " "
1059:                                            + a.getLabel() + " = "
1060:                                            + labeledElementInit + ";");
1061:                                    if (grammar.buildAST) {
1062:                                        genASTDeclaration(a);
1063:                                    }
1064:                                } else {
1065:                                    if (grammar.buildAST) {
1066:                                        // Always gen AST variables for
1067:                                        // labeled elements, even if the
1068:                                        // element itself is marked with !
1069:                                        genASTDeclaration(a);
1070:                                    }
1071:                                    if (grammar instanceof  LexerGrammar) {
1072:                                        println("Token " + a.getLabel()
1073:                                                + " = null;");
1074:                                    }
1075:                                    if (grammar instanceof  TreeWalkerGrammar) {
1076:                                        // always generate rule-ref variables
1077:                                        // for tree walker
1078:                                        println(labeledElementType + " "
1079:                                                + a.getLabel() + " = "
1080:                                                + labeledElementInit + ";");
1081:                                    }
1082:                                }
1083:                            } else {
1084:                                // It is a token or literal reference.  Generate the
1085:                                // correct variable type for this grammar
1086:                                println(labeledElementType + " " + a.getLabel()
1087:                                        + " = " + labeledElementInit + ";");
1088:                                // In addition, generate *_AST variables if building ASTs
1089:                                if (grammar.buildAST) {
1090:                                    //println(labeledElementASTType+" " + a.getLabel() + "_AST = null;");
1091:                                    if (a instanceof  GrammarAtom
1092:                                            && ((GrammarAtom) a)
1093:                                                    .getASTNodeType() != null) {
1094:                                        GrammarAtom ga = (GrammarAtom) a;
1095:                                        genASTDeclaration(a, ga
1096:                                                .getASTNodeType());
1097:                                    } else {
1098:                                        genASTDeclaration(a);
1099:                                    }
1100:                                }
1101:                            }
1102:                        }
1103:                    }
1104:                }
1105:            }
1106:
1107:            public void genBody(LexerGrammar g) throws IOException {
1108:                // SAS: moved output creation to method so a subclass can change
1109:                //      how the output is generated (for VAJ interface)
1110:                setupOutput(grammar.getClassName());
1111:
1112:                genAST = false; // no way to gen trees.
1113:                saveText = true; // save consumed characters.
1114:
1115:                tabs = 0;
1116:
1117:                // Generate header common to all CSharp output files
1118:                genHeader();
1119:                // Do not use printAction because we assume tabs==0
1120:                println(behavior.getHeaderAction(""));
1121:
1122:                // Generate the CSharp namespace declaration (if specified)
1123:                if (nameSpace != null)
1124:                    nameSpace.emitDeclarations(currentOutput);
1125:                tabs++;
1126:
1127:                // Generate header specific to lexer CSharp file
1128:                // println("import java.io.FileInputStream;");
1129:                println("// Generate header specific to lexer CSharp file");
1130:                println("using System;");
1131:                println("using Stream                          = System.IO.Stream;");
1132:                println("using TextReader                      = System.IO.TextReader;");
1133:                println("using Hashtable                       = System.Collections.Hashtable;");
1134:                println("using Comparer                        = System.Collections.Comparer;");
1135:                if (!(g.caseSensitiveLiterals)) {
1136:                    println("using CaseInsensitiveHashCodeProvider = System.Collections.CaseInsensitiveHashCodeProvider;");
1137:                    println("using CaseInsensitiveComparer         = System.Collections.CaseInsensitiveComparer;");
1138:                }
1139:                println("");
1140:                println("using TokenStreamException            = persistence.antlr.TokenStreamException;");
1141:                println("using TokenStreamIOException          = persistence.antlr.TokenStreamIOException;");
1142:                println("using TokenStreamRecognitionException = persistence.antlr.TokenStreamRecognitionException;");
1143:                println("using CharStreamException             = persistence.antlr.CharStreamException;");
1144:                println("using CharStreamIOException           = persistence.antlr.CharStreamIOException;");
1145:                println("using ANTLRException                  = persistence.antlr.ANTLRException;");
1146:                println("using CharScanner                     = persistence.antlr.CharScanner;");
1147:                println("using InputBuffer                     = persistence.antlr.InputBuffer;");
1148:                println("using ByteBuffer                      = persistence.antlr.ByteBuffer;");
1149:                println("using CharBuffer                      = persistence.antlr.CharBuffer;");
1150:                println("using Token                           = persistence.antlr.Token;");
1151:                println("using CommonToken                     = persistence.antlr.CommonToken;");
1152:                println("using SemanticException               = persistence.antlr.SemanticException;");
1153:                println("using RecognitionException            = persistence.antlr.RecognitionException;");
1154:                println("using NoViableAltForCharException     = persistence.antlr.NoViableAltForCharException;");
1155:                println("using MismatchedCharException         = persistence.antlr.MismatchedCharException;");
1156:                println("using TokenStream                     = persistence.antlr.TokenStream;");
1157:                println("using LexerSharedInputState           = persistence.antlr.LexerSharedInputState;");
1158:                println("using BitSet                          = persistence.antlr.collections.impl.BitSet;");
1159:
1160:                // Generate user-defined lexer file preamble
1161:                println(grammar.preambleAction.getText());
1162:
1163:                // Generate lexer class definition
1164:                String sup = null;
1165:                if (grammar.super Class != null) {
1166:                    sup = grammar.super Class;
1167:                } else {
1168:                    sup = "persistence.antlr." + grammar.getSuperClass();
1169:                }
1170:
1171:                // print javadoc comment if any
1172:                if (grammar.comment != null) {
1173:                    _println(grammar.comment);
1174:                }
1175:
1176:                Token tprefix = (Token) grammar.options
1177:                        .get("classHeaderPrefix");
1178:                if (tprefix == null) {
1179:                    print("public ");
1180:                } else {
1181:                    String p = StringUtils.stripFrontBack(tprefix.getText(),
1182:                            "\"", "\"");
1183:                    if (p == null) {
1184:                        print("public ");
1185:                    } else {
1186:                        print(p + " ");
1187:                    }
1188:                }
1189:
1190:                print("class " + grammar.getClassName() + " : " + sup);
1191:                println(", TokenStream");
1192:                Token tsuffix = (Token) grammar.options
1193:                        .get("classHeaderSuffix");
1194:                if (tsuffix != null) {
1195:                    String suffix = StringUtils.stripFrontBack(tsuffix
1196:                            .getText(), "\"", "\"");
1197:                    if (suffix != null) {
1198:                        print(", " + suffix); // must be an interface name for CSharp
1199:                    }
1200:                }
1201:                println(" {");
1202:                tabs++;
1203:
1204:                // Generate 'const' definitions for Token IDs
1205:                genTokenDefinitions(grammar.tokenManager);
1206:
1207:                // Generate user-defined lexer class members
1208:                print(processActionForSpecialSymbols(grammar.classMemberAction
1209:                        .getText(), grammar.classMemberAction.getLine(),
1210:                        currentRule, null));
1211:
1212:                //
1213:                // Generate the constructor from InputStream, which in turn
1214:                // calls the ByteBuffer constructor
1215:                //
1216:                println("public " + grammar.getClassName()
1217:                        + "(Stream ins) : this(new ByteBuffer(ins))");
1218:                println("{");
1219:                println("}");
1220:                println("");
1221:
1222:                //
1223:                // Generate the constructor from Reader, which in turn
1224:                // calls the CharBuffer constructor
1225:                //
1226:                println("public " + grammar.getClassName()
1227:                        + "(TextReader r) : this(new CharBuffer(r))");
1228:                println("{");
1229:                println("}");
1230:                println("");
1231:
1232:                print("public " + grammar.getClassName() + "(InputBuffer ib)");
1233:                // if debugging, wrap the input buffer in a debugger
1234:                if (grammar.debuggingOutput)
1235:                    println(" : this(new LexerSharedInputState(new persistence.antlr.debug.DebuggingInputBuffer(ib)))");
1236:                else
1237:                    println(" : this(new LexerSharedInputState(ib))");
1238:                println("{");
1239:                println("}");
1240:                println("");
1241:
1242:                //
1243:                // Generate the constructor from InputBuffer (char or byte)
1244:                //
1245:                println("public " + grammar.getClassName()
1246:                        + "(LexerSharedInputState state) : base(state)");
1247:                println("{");
1248:                tabs++;
1249:                println("initialize();");
1250:                tabs--;
1251:                println("}");
1252:
1253:                // Generate the initialize function
1254:                println("private void initialize()");
1255:                println("{");
1256:                tabs++;
1257:
1258:                // if debugging, set up array variables and call user-overridable
1259:                //   debugging setup method
1260:                if (grammar.debuggingOutput) {
1261:                    println("ruleNames  = _ruleNames;");
1262:                    println("semPredNames = _semPredNames;");
1263:                    println("setupDebugging();");
1264:                }
1265:
1266:                // Generate the setting of various generated options.
1267:                // These need to be before the literals since ANTLRHashString depends on
1268:                // the casesensitive stuff.
1269:                println("caseSensitiveLiterals = " + g.caseSensitiveLiterals
1270:                        + ";");
1271:                println("setCaseSensitive(" + g.caseSensitive + ");");
1272:
1273:                // Generate the initialization of a hashtable
1274:                // containing the string literals used in the lexer
1275:                // The literals variable itself is in CharScanner
1276:                if (g.caseSensitiveLiterals)
1277:                    println("literals = new Hashtable(null, Comparer.Default);");
1278:                else
1279:                    println("literals = new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);");
1280:                Enumeration keys = grammar.tokenManager.getTokenSymbolKeys();
1281:                while (keys.hasMoreElements()) {
1282:                    String key = (String) keys.nextElement();
1283:                    if (key.charAt(0) != '"') {
1284:                        continue;
1285:                    }
1286:                    TokenSymbol sym = grammar.tokenManager.getTokenSymbol(key);
1287:                    if (sym instanceof  StringLiteralSymbol) {
1288:                        StringLiteralSymbol s = (StringLiteralSymbol) sym;
1289:                        println("literals.Add(" + s.getId() + ", "
1290:                                + s.getTokenType() + ");");
1291:                    }
1292:                }
1293:
1294:                Enumeration ids;
1295:                tabs--;
1296:                println("}");
1297:
1298:                // generate the rule name array for debugging
1299:                if (grammar.debuggingOutput) {
1300:                    println("private const string[] _ruleNames = {");
1301:
1302:                    ids = grammar.rules.elements();
1303:                    int ruleNum = 0;
1304:                    while (ids.hasMoreElements()) {
1305:                        GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
1306:                        if (sym instanceof  RuleSymbol)
1307:                            println("  \"" + ((RuleSymbol) sym).getId() + "\",");
1308:                    }
1309:                    println("};");
1310:                }
1311:
1312:                // Generate nextToken() rule.
1313:                // nextToken() is a synthetic lexer rule that is the implicit OR of all
1314:                // user-defined lexer rules.
1315:                genNextToken();
1316:
1317:                // Generate code for each rule in the lexer
1318:                ids = grammar.rules.elements();
1319:                int ruleNum = 0;
1320:                while (ids.hasMoreElements()) {
1321:                    RuleSymbol sym = (RuleSymbol) ids.nextElement();
1322:                    // Don't generate the synthetic rules
1323:                    if (!sym.getId().equals("mnextToken")) {
1324:                        genRule(sym, false, ruleNum++, grammar.tokenManager);
1325:                    }
1326:                    exitIfError();
1327:                }
1328:
1329:                // Generate the semantic predicate map for debugging
1330:                if (grammar.debuggingOutput)
1331:                    genSemPredMap();
1332:
1333:                // Generate the bitsets used throughout the lexer
1334:                genBitsets(bitsetsUsed, ((LexerGrammar) grammar).charVocabulary
1335:                        .size());
1336:
1337:                println("");
1338:                tabs--;
1339:                println("}");
1340:
1341:                tabs--;
1342:                // Generate the CSharp namespace closures (if required)
1343:                if (nameSpace != null)
1344:                    nameSpace.emitClosures(currentOutput);
1345:
1346:                // Close the lexer output stream
1347:                currentOutput.close();
1348:                currentOutput = null;
1349:            }
1350:
1351:            public void genInitFactory(Grammar g) {
1352:                if (g.buildAST) {
1353:                    // Generate the method to initialize an ASTFactory when we're
1354:                    // building AST's
1355:                    println("static public void initializeASTFactory( ASTFactory factory )");
1356:                    println("{");
1357:                    tabs++;
1358:
1359:                    println("factory.setMaxNodeType("
1360:                            + g.tokenManager.maxTokenType() + ");");
1361:
1362:                    // Walk the token vocabulary and generate code to register every TokenID->ASTNodeType
1363:                    // mapping specified in the  tokens {...} section with the ASTFactory.
1364:                    Vector v = g.tokenManager.getVocabulary();
1365:                    for (int i = 0; i < v.size(); i++) {
1366:                        String s = (String) v.elementAt(i);
1367:                        if (s != null) {
1368:                            TokenSymbol ts = g.tokenManager.getTokenSymbol(s);
1369:                            if (ts != null && ts.getASTNodeType() != null) {
1370:                                println("factory.setTokenTypeASTNodeType(" + s
1371:                                        + ", \"" + ts.getASTNodeType() + "\");");
1372:                            }
1373:                        }
1374:                    }
1375:
1376:                    tabs--;
1377:                    println("}");
1378:                }
1379:            }
1380:
1381:            public void genBody(ParserGrammar g) throws IOException {
1382:                // Open the output stream for the parser and set the currentOutput
1383:                // SAS: moved file setup so subclass could do it (for VAJ interface)
1384:                setupOutput(grammar.getClassName());
1385:
1386:                genAST = grammar.buildAST;
1387:
1388:                tabs = 0;
1389:
1390:                // Generate the header common to all output files.
1391:                genHeader();
1392:                // Do not use printAction because we assume tabs==0
1393:                println(behavior.getHeaderAction(""));
1394:
1395:                // Generate the CSharp namespace declaration (if specified)
1396:                if (nameSpace != null)
1397:                    nameSpace.emitDeclarations(currentOutput);
1398:                tabs++;
1399:
1400:                // Generate header for the parser
1401:                println("// Generate the header common to all output files.");
1402:                println("using System;");
1403:                println("");
1404:                println("using TokenBuffer              = persistence.antlr.TokenBuffer;");
1405:                println("using TokenStreamException     = persistence.antlr.TokenStreamException;");
1406:                println("using TokenStreamIOException   = persistence.antlr.TokenStreamIOException;");
1407:                println("using ANTLRException           = persistence.antlr.ANTLRException;");
1408:                println("using " + grammar.getSuperClass()
1409:                        + " = persistence.antlr." + grammar.getSuperClass()
1410:                        + ";");
1411:                println("using Token                    = persistence.antlr.Token;");
1412:                println("using TokenStream              = persistence.antlr.TokenStream;");
1413:                println("using RecognitionException     = persistence.antlr.RecognitionException;");
1414:                println("using NoViableAltException     = persistence.antlr.NoViableAltException;");
1415:                println("using MismatchedTokenException = persistence.antlr.MismatchedTokenException;");
1416:                println("using SemanticException        = persistence.antlr.SemanticException;");
1417:                println("using ParserSharedInputState   = persistence.antlr.ParserSharedInputState;");
1418:                println("using BitSet                   = persistence.antlr.collections.impl.BitSet;");
1419:                if (genAST) {
1420:                    println("using AST                      = persistence.antlr.collections.AST;");
1421:                    println("using ASTPair                  = persistence.antlr.ASTPair;");
1422:                    println("using ASTFactory               = persistence.antlr.ASTFactory;");
1423:                    println("using ASTArray                 = persistence.antlr.collections.impl.ASTArray;");
1424:                }
1425:
1426:                // Output the user-defined parser preamble
1427:                println(grammar.preambleAction.getText());
1428:
1429:                // Generate parser class definition
1430:                String sup = null;
1431:                if (grammar.super Class != null)
1432:                    sup = grammar.super Class;
1433:                else
1434:                    sup = "persistence.antlr." + grammar.getSuperClass();
1435:
1436:                // print javadoc comment if any
1437:                if (grammar.comment != null) {
1438:                    _println(grammar.comment);
1439:                }
1440:
1441:                Token tprefix = (Token) grammar.options
1442:                        .get("classHeaderPrefix");
1443:                if (tprefix == null) {
1444:                    print("public ");
1445:                } else {
1446:                    String p = StringUtils.stripFrontBack(tprefix.getText(),
1447:                            "\"", "\"");
1448:                    if (p == null) {
1449:                        print("public ");
1450:                    } else {
1451:                        print(p + " ");
1452:                    }
1453:                }
1454:
1455:                println("class " + grammar.getClassName() + " : " + sup);
1456:
1457:                Token tsuffix = (Token) grammar.options
1458:                        .get("classHeaderSuffix");
1459:                if (tsuffix != null) {
1460:                    String suffix = StringUtils.stripFrontBack(tsuffix
1461:                            .getText(), "\"", "\"");
1462:                    if (suffix != null)
1463:                        print("              , " + suffix); // must be an interface name for CSharp
1464:                }
1465:                println("{");
1466:                tabs++;
1467:
1468:                // Generate 'const' definitions for Token IDs
1469:                genTokenDefinitions(grammar.tokenManager);
1470:
1471:                // set up an array of all the rule names so the debugger can
1472:                // keep track of them only by number -- less to store in tree...
1473:                if (grammar.debuggingOutput) {
1474:                    println("private const string[] _ruleNames = {");
1475:                    tabs++;
1476:
1477:                    Enumeration ids = grammar.rules.elements();
1478:                    int ruleNum = 0;
1479:                    while (ids.hasMoreElements()) {
1480:                        GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
1481:                        if (sym instanceof  RuleSymbol)
1482:                            println("  \"" + ((RuleSymbol) sym).getId() + "\",");
1483:                    }
1484:                    tabs--;
1485:                    println("};");
1486:                }
1487:
1488:                // Generate user-defined parser class members
1489:                print(processActionForSpecialSymbols(grammar.classMemberAction
1490:                        .getText(), grammar.classMemberAction.getLine(),
1491:                        currentRule, null));
1492:
1493:                // Generate parser class constructor from TokenBuffer
1494:                println("");
1495:                println("protected void initialize()");
1496:                println("{");
1497:                tabs++;
1498:                println("tokenNames = tokenNames_;");
1499:
1500:                if (grammar.buildAST)
1501:                    println("initializeFactory();");
1502:
1503:                // if debugging, set up arrays and call the user-overridable
1504:                //   debugging setup method
1505:                if (grammar.debuggingOutput) {
1506:                    println("ruleNames  = _ruleNames;");
1507:                    println("semPredNames = _semPredNames;");
1508:                    println("setupDebugging(tokenBuf);");
1509:                }
1510:                tabs--;
1511:                println("}");
1512:                println("");
1513:
1514:                println("");
1515:                println("protected " + grammar.getClassName()
1516:                        + "(TokenBuffer tokenBuf, int k) : base(tokenBuf, k)");
1517:                println("{");
1518:                tabs++;
1519:                println("initialize();");
1520:                tabs--;
1521:                println("}");
1522:                println("");
1523:
1524:                println("public " + grammar.getClassName()
1525:                        + "(TokenBuffer tokenBuf) : this(tokenBuf,"
1526:                        + grammar.maxk + ")");
1527:                println("{");
1528:                println("}");
1529:                println("");
1530:
1531:                // Generate parser class constructor from TokenStream
1532:                println("protected " + grammar.getClassName()
1533:                        + "(TokenStream lexer, int k) : base(lexer,k)");
1534:                println("{");
1535:                tabs++;
1536:                println("initialize();");
1537:                tabs--;
1538:                println("}");
1539:                println("");
1540:
1541:                println("public " + grammar.getClassName()
1542:                        + "(TokenStream lexer) : this(lexer," + grammar.maxk
1543:                        + ")");
1544:                println("{");
1545:                println("}");
1546:                println("");
1547:
1548:                println("public " + grammar.getClassName()
1549:                        + "(ParserSharedInputState state) : base(state,"
1550:                        + grammar.maxk + ")");
1551:                println("{");
1552:                tabs++;
1553:                println("initialize();");
1554:                tabs--;
1555:                println("}");
1556:                println("");
1557:
1558:                astTypes = new java.util.Vector(100);
1559:
1560:                // Generate code for each rule in the grammar
1561:                Enumeration ids = grammar.rules.elements();
1562:                int ruleNum = 0;
1563:                while (ids.hasMoreElements()) {
1564:                    GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
1565:                    if (sym instanceof  RuleSymbol) {
1566:                        RuleSymbol rs = (RuleSymbol) sym;
1567:                        genRule(rs, rs.references.size() == 0, ruleNum++,
1568:                                grammar.tokenManager);
1569:                    }
1570:                    exitIfError();
1571:                }
1572:                if (usingCustomAST) {
1573:                    // when we are using a custom AST, overload Parser.getAST() to return the
1574:                    // custom AST type
1575:                    println("public new " + labeledElementASTType + " getAST()");
1576:                    println("{");
1577:                    tabs++;
1578:                    println("return (" + labeledElementASTType + ") returnAST;");
1579:                    tabs--;
1580:                    println("}");
1581:                    println("");
1582:                }
1583:
1584:                // Generate the method that initializes the ASTFactory when we're
1585:                // building AST's
1586:                println("private void initializeFactory()");
1587:                println("{");
1588:                tabs++;
1589:                if (grammar.buildAST) {
1590:                    println("if (astFactory == null)");
1591:                    println("{");
1592:                    tabs++;
1593:                    if (usingCustomAST) {
1594:                        println("astFactory = new ASTFactory(\""
1595:                                + labeledElementASTType + "\");");
1596:                    } else
1597:                        println("astFactory = new ASTFactory();");
1598:                    tabs--;
1599:                    println("}");
1600:                    println("initializeASTFactory( astFactory );");
1601:                }
1602:                tabs--;
1603:                println("}");
1604:                genInitFactory(g);
1605:
1606:                // Generate the token names
1607:                genTokenStrings();
1608:
1609:                // Generate the bitsets used throughout the grammar
1610:                genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType());
1611:
1612:                // Generate the semantic predicate map for debugging
1613:                if (grammar.debuggingOutput)
1614:                    genSemPredMap();
1615:
1616:                // Close class definition
1617:                println("");
1618:                tabs--;
1619:                println("}");
1620:
1621:                tabs--;
1622:                // Generate the CSharp namespace closures (if required)
1623:                if (nameSpace != null)
1624:                    nameSpace.emitClosures(currentOutput);
1625:
1626:                // Close the parser output stream
1627:                currentOutput.close();
1628:                currentOutput = null;
1629:            }
1630:
1631:            public void genBody(TreeWalkerGrammar g) throws IOException {
1632:                // Open the output stream for the parser and set the currentOutput
1633:                // SAS: move file open to method so subclass can override it
1634:                //      (mainly for VAJ interface)
1635:                setupOutput(grammar.getClassName());
1636:
1637:                genAST = grammar.buildAST;
1638:                tabs = 0;
1639:
1640:                // Generate the header common to all output files.
1641:                genHeader();
1642:                // Do not use printAction because we assume tabs==0
1643:                println(behavior.getHeaderAction(""));
1644:
1645:                // Generate the CSharp namespace declaration (if specified)
1646:                if (nameSpace != null)
1647:                    nameSpace.emitDeclarations(currentOutput);
1648:                tabs++;
1649:
1650:                // Generate header specific to the tree-parser CSharp file
1651:                println("// Generate header specific to the tree-parser CSharp file");
1652:                println("using System;");
1653:                println("");
1654:                println("using " + grammar.getSuperClass()
1655:                        + " = persistence.antlr." + grammar.getSuperClass()
1656:                        + ";");
1657:                println("using Token                    = persistence.antlr.Token;");
1658:                println("using AST                      = persistence.antlr.collections.AST;");
1659:                println("using RecognitionException     = persistence.antlr.RecognitionException;");
1660:                println("using ANTLRException           = persistence.antlr.ANTLRException;");
1661:                println("using NoViableAltException     = persistence.antlr.NoViableAltException;");
1662:                println("using MismatchedTokenException = persistence.antlr.MismatchedTokenException;");
1663:                println("using SemanticException        = persistence.antlr.SemanticException;");
1664:                println("using BitSet                   = persistence.antlr.collections.impl.BitSet;");
1665:                println("using ASTPair                  = persistence.antlr.ASTPair;");
1666:                println("using ASTFactory               = persistence.antlr.ASTFactory;");
1667:                println("using ASTArray                 = persistence.antlr.collections.impl.ASTArray;");
1668:
1669:                // Output the user-defined parser premamble
1670:                println(grammar.preambleAction.getText());
1671:
1672:                // Generate parser class definition
1673:                String sup = null;
1674:                if (grammar.super Class != null) {
1675:                    sup = grammar.super Class;
1676:                } else {
1677:                    sup = "persistence.antlr." + grammar.getSuperClass();
1678:                }
1679:                println("");
1680:
1681:                // print javadoc comment if any
1682:                if (grammar.comment != null) {
1683:                    _println(grammar.comment);
1684:                }
1685:
1686:                Token tprefix = (Token) grammar.options
1687:                        .get("classHeaderPrefix");
1688:                if (tprefix == null) {
1689:                    print("public ");
1690:                } else {
1691:                    String p = StringUtils.stripFrontBack(tprefix.getText(),
1692:                            "\"", "\"");
1693:                    if (p == null) {
1694:                        print("public ");
1695:                    } else {
1696:                        print(p + " ");
1697:                    }
1698:                }
1699:
1700:                println("class " + grammar.getClassName() + " : " + sup);
1701:                Token tsuffix = (Token) grammar.options
1702:                        .get("classHeaderSuffix");
1703:                if (tsuffix != null) {
1704:                    String suffix = StringUtils.stripFrontBack(tsuffix
1705:                            .getText(), "\"", "\"");
1706:                    if (suffix != null) {
1707:                        print("              , " + suffix); // must be an interface name for CSharp
1708:                    }
1709:                }
1710:                println("{");
1711:                tabs++;
1712:
1713:                // Generate 'const' definitions for Token IDs
1714:                genTokenDefinitions(grammar.tokenManager);
1715:
1716:                // Generate user-defined parser class members
1717:                print(processActionForSpecialSymbols(grammar.classMemberAction
1718:                        .getText(), grammar.classMemberAction.getLine(),
1719:                        currentRule, null));
1720:
1721:                // Generate default parser class constructor
1722:                println("public " + grammar.getClassName() + "()");
1723:                println("{");
1724:                tabs++;
1725:                println("tokenNames = tokenNames_;");
1726:                tabs--;
1727:                println("}");
1728:                println("");
1729:
1730:                astTypes = new java.util.Vector();
1731:                // Generate code for each rule in the grammar
1732:                Enumeration ids = grammar.rules.elements();
1733:                int ruleNum = 0;
1734:                String ruleNameInits = "";
1735:                while (ids.hasMoreElements()) {
1736:                    GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
1737:                    if (sym instanceof  RuleSymbol) {
1738:                        RuleSymbol rs = (RuleSymbol) sym;
1739:                        genRule(rs, rs.references.size() == 0, ruleNum++,
1740:                                grammar.tokenManager);
1741:                    }
1742:                    exitIfError();
1743:                }
1744:
1745:                if (usingCustomAST) {
1746:                    // when we are using a custom ast override Parser.getAST to return the
1747:                    // custom AST type
1748:                    println("public new " + labeledElementASTType + " getAST()");
1749:                    println("{");
1750:                    tabs++;
1751:                    println("return (" + labeledElementASTType + ") returnAST;");
1752:                    tabs--;
1753:                    println("}");
1754:                    println("");
1755:                }
1756:
1757:                // Generate the ASTFactory initialization function
1758:                genInitFactory(grammar);
1759:
1760:                // Generate the token names
1761:                genTokenStrings();
1762:
1763:                // Generate the bitsets used throughout the grammar
1764:                genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType());
1765:
1766:                // Close class definition
1767:                tabs--;
1768:                println("}");
1769:                println("");
1770:
1771:                tabs--;
1772:                // Generate the CSharp namespace closures (if required)
1773:                if (nameSpace != null)
1774:                    nameSpace.emitClosures(currentOutput);
1775:
1776:                // Close the parser output stream
1777:                currentOutput.close();
1778:                currentOutput = null;
1779:            }
1780:
1781:            /** Generate a series of case statements that implement a BitSet test.
1782:             * @param p The Bitset for which cases are to be generated
1783:             */
1784:            protected void genCases(BitSet p) {
1785:                if (DEBUG_CODE_GENERATOR)
1786:                    System.out.println("genCases(" + p + ")");
1787:                int[] elems;
1788:
1789:                elems = p.toArray();
1790:                // Wrap cases four-per-line for lexer, one-per-line for parser
1791:                int wrap = (grammar instanceof  LexerGrammar) ? 4 : 1;
1792:                int j = 1;
1793:                boolean startOfLine = true;
1794:                for (int i = 0; i < elems.length; i++) {
1795:                    if (j == 1) {
1796:                        print("");
1797:                    } else {
1798:                        _print("  ");
1799:                    }
1800:                    _print("case " + getValueString(elems[i]) + ":");
1801:                    if (j == wrap) {
1802:                        _println("");
1803:                        startOfLine = true;
1804:                        j = 1;
1805:                    } else {
1806:                        j++;
1807:                        startOfLine = false;
1808:                    }
1809:                }
1810:                if (!startOfLine) {
1811:                    _println("");
1812:                }
1813:            }
1814:
1815:            /**Generate common code for a block of alternatives; return a
1816:             * postscript that needs to be generated at the end of the
1817:             * block.  Other routines may append else-clauses and such for
1818:             * error checking before the postfix is generated.  If the
1819:             * grammar is a lexer, then generate alternatives in an order
1820:             * where alternatives requiring deeper lookahead are generated
1821:             * first, and EOF in the lookahead set reduces the depth of
1822:             * the lookahead.  @param blk The block to generate @param
1823:             * noTestForSingle If true, then it does not generate a test
1824:             * for a single alternative.
1825:             */
1826:            public CSharpBlockFinishingInfo genCommonBlock(
1827:                    AlternativeBlock blk, boolean noTestForSingle) {
1828:                int nIF = 0;
1829:                boolean createdLL1Switch = false;
1830:                int closingBracesOfIFSequence = 0;
1831:                CSharpBlockFinishingInfo finishingInfo = new CSharpBlockFinishingInfo();
1832:                if (DEBUG_CODE_GENERATOR)
1833:                    System.out.println("genCommonBlock(" + blk + ")");
1834:
1835:                // Save the AST generation state, and set it to that of the block
1836:                boolean savegenAST = genAST;
1837:                genAST = genAST && blk.getAutoGen();
1838:
1839:                boolean oldsaveTest = saveText;
1840:                saveText = saveText && blk.getAutoGen();
1841:
1842:                // Is this block inverted?  If so, generate special-case code
1843:                if (blk.not
1844:                        && analyzer.subruleCanBeInverted(blk,
1845:                                grammar instanceof  LexerGrammar)) {
1846:                    if (DEBUG_CODE_GENERATOR)
1847:                        System.out.println("special case: ~(subrule)");
1848:                    Lookahead p = analyzer.look(1, blk);
1849:                    // Variable assignment for labeled elements
1850:                    if (blk.getLabel() != null && syntacticPredLevel == 0) {
1851:                        println(blk.getLabel() + " = " + lt1Value + ";");
1852:                    }
1853:
1854:                    // AST
1855:                    genElementAST(blk);
1856:
1857:                    String astArgs = "";
1858:                    if (grammar instanceof  TreeWalkerGrammar) {
1859:                        if (usingCustomAST)
1860:                            astArgs = "(AST)_t,";
1861:                        else
1862:                            astArgs = "_t,";
1863:                    }
1864:
1865:                    // match the bitset for the alternative
1866:                    println("match(" + astArgs
1867:                            + getBitsetName(markBitsetForGen(p.fset)) + ");");
1868:
1869:                    // tack on tree cursor motion if doing a tree walker
1870:                    if (grammar instanceof  TreeWalkerGrammar) {
1871:                        println("_t = _t.getNextSibling();");
1872:                    }
1873:                    return finishingInfo;
1874:                }
1875:
1876:                // Special handling for single alt
1877:                if (blk.getAlternatives().size() == 1) {
1878:                    Alternative alt = blk.getAlternativeAt(0);
1879:                    // Generate a warning if there is a synPred for single alt.
1880:                    if (alt.synPred != null) {
1881:                        antlrTool
1882:                                .warning(
1883:                                        "Syntactic predicate superfluous for single alternative",
1884:                                        grammar.getFilename(), blk
1885:                                                .getAlternativeAt(0).synPred
1886:                                                .getLine(), blk
1887:                                                .getAlternativeAt(0).synPred
1888:                                                .getColumn());
1889:                    }
1890:                    if (noTestForSingle) {
1891:                        if (alt.semPred != null) {
1892:                            // Generate validating predicate
1893:                            genSemPred(alt.semPred, blk.line);
1894:                        }
1895:                        genAlt(alt, blk);
1896:                        return finishingInfo;
1897:                    }
1898:                }
1899:
1900:                // count number of simple LL(1) cases; only do switch for
1901:                // many LL(1) cases (no preds, no end of token refs)
1902:                // We don't care about exit paths for (...)*, (...)+
1903:                // because we don't explicitly have a test for them
1904:                // as an alt in the loop.
1905:                //
1906:                // Also, we now count how many unicode lookahead sets
1907:                // there are--they must be moved to DEFAULT or ELSE
1908:                // clause.
1909:                int nLL1 = 0;
1910:                for (int i = 0; i < blk.getAlternatives().size(); i++) {
1911:                    Alternative a = blk.getAlternativeAt(i);
1912:                    if (suitableForCaseExpression(a)) {
1913:                        nLL1++;
1914:                    }
1915:                }
1916:
1917:                // do LL(1) cases
1918:                if (nLL1 >= makeSwitchThreshold) {
1919:                    // Determine the name of the item to be compared
1920:                    String testExpr = lookaheadString(1);
1921:                    createdLL1Switch = true;
1922:                    // when parsing trees, convert null to valid tree node with NULL lookahead
1923:                    if (grammar instanceof  TreeWalkerGrammar) {
1924:                        println("if (null == _t)");
1925:                        tabs++;
1926:                        println("_t = ASTNULL;");
1927:                        tabs--;
1928:                    }
1929:                    println("switch ( " + testExpr + " )");
1930:                    println("{");
1931:                    //tabs++;
1932:                    for (int i = 0; i < blk.alternatives.size(); i++) {
1933:                        Alternative alt = blk.getAlternativeAt(i);
1934:                        // ignore any non-LL(1) alts, predicated alts,
1935:                        // or end-of-token alts for case expressions
1936:                        bSaveIndexCreated = false;
1937:                        if (!suitableForCaseExpression(alt)) {
1938:                            continue;
1939:                        }
1940:                        Lookahead p = alt.cache[1];
1941:                        if (p.fset.degree() == 0 && !p.containsEpsilon()) {
1942:                            antlrTool
1943:                                    .warning(
1944:                                            "Alternate omitted due to empty prediction set",
1945:                                            grammar.getFilename(), alt.head
1946:                                                    .getLine(), alt.head
1947:                                                    .getColumn());
1948:                        } else {
1949:                            genCases(p.fset);
1950:                            println("{");
1951:                            tabs++;
1952:                            genAlt(alt, blk);
1953:                            println("break;");
1954:                            tabs--;
1955:                            println("}");
1956:                        }
1957:                    }
1958:                    println("default:");
1959:                    tabs++;
1960:                }
1961:
1962:                // do non-LL(1) and nondeterministic cases This is tricky in
1963:                // the lexer, because of cases like: STAR : '*' ; ASSIGN_STAR
1964:                // : "*="; Since nextToken is generated without a loop, then
1965:                // the STAR will have end-of-token as it's lookahead set for
1966:                // LA(2).  So, we must generate the alternatives containing
1967:                // trailing end-of-token in their lookahead sets *after* the
1968:                // alternatives without end-of-token.  This implements the
1969:                // usual lexer convention that longer matches come before
1970:                // shorter ones, e.g.  "*=" matches ASSIGN_STAR not STAR
1971:                //
1972:                // For non-lexer grammars, this does not sort the alternates
1973:                // by depth Note that alts whose lookahead is purely
1974:                // end-of-token at k=1 end up as default or else clauses.
1975:                int startDepth = (grammar instanceof  LexerGrammar) ? grammar.maxk
1976:                        : 0;
1977:                for (int altDepth = startDepth; altDepth >= 0; altDepth--) {
1978:                    if (DEBUG_CODE_GENERATOR)
1979:                        System.out.println("checking depth " + altDepth);
1980:                    for (int i = 0; i < blk.alternatives.size(); i++) {
1981:                        Alternative alt = blk.getAlternativeAt(i);
1982:                        if (DEBUG_CODE_GENERATOR)
1983:                            System.out.println("genAlt: " + i);
1984:                        // if we made a switch above, ignore what we already took care
1985:                        // of.  Specifically, LL(1) alts with no preds
1986:                        // that do not have end-of-token in their prediction set
1987:                        // and that are not giant unicode sets.
1988:                        if (createdLL1Switch && suitableForCaseExpression(alt)) {
1989:                            if (DEBUG_CODE_GENERATOR)
1990:                                System.out
1991:                                        .println("ignoring alt because it was in the switch");
1992:                            continue;
1993:                        }
1994:                        String e;
1995:
1996:                        boolean unpredicted = false;
1997:
1998:                        if (grammar instanceof  LexerGrammar) {
1999:                            // Calculate the "effective depth" of the alt,
2000:                            // which is the max depth at which
2001:                            // cache[depth]!=end-of-token
2002:                            int effectiveDepth = alt.lookaheadDepth;
2003:                            if (effectiveDepth == GrammarAnalyzer.NONDETERMINISTIC) {
2004:                                // use maximum lookahead
2005:                                effectiveDepth = grammar.maxk;
2006:                            }
2007:                            while (effectiveDepth >= 1
2008:                                    && alt.cache[effectiveDepth]
2009:                                            .containsEpsilon()) {
2010:                                effectiveDepth--;
2011:                            }
2012:                            // Ignore alts whose effective depth is other than
2013:                            // the ones we are generating for this iteration.
2014:                            if (effectiveDepth != altDepth) {
2015:                                if (DEBUG_CODE_GENERATOR)
2016:                                    System.out
2017:                                            .println("ignoring alt because effectiveDepth!=altDepth;"
2018:                                                    + effectiveDepth
2019:                                                    + "!="
2020:                                                    + altDepth);
2021:                                continue;
2022:                            }
2023:                            unpredicted = lookaheadIsEmpty(alt, effectiveDepth);
2024:                            e = getLookaheadTestExpression(alt, effectiveDepth);
2025:                        } else {
2026:                            unpredicted = lookaheadIsEmpty(alt, grammar.maxk);
2027:                            e = getLookaheadTestExpression(alt, grammar.maxk);
2028:                        }
2029:
2030:                        // Was it a big unicode range that forced unsuitability
2031:                        // for a case expression?
2032:                        if (alt.cache[1].fset.degree() > caseSizeThreshold
2033:                                && suitableForCaseExpression(alt)) {
2034:                            if (nIF == 0) {
2035:                                println("if " + e);
2036:                                println("{");
2037:                            } else {
2038:                                println("else if " + e);
2039:                                println("{");
2040:                            }
2041:                        } else if (unpredicted && alt.semPred == null
2042:                                && alt.synPred == null) {
2043:                            // The alt has empty prediction set and no
2044:                            // predicate to help out.  if we have not
2045:                            // generated a previous if, just put {...} around
2046:                            // the end-of-token clause
2047:                            if (nIF == 0) {
2048:                                println("{");
2049:                            } else {
2050:                                println("else {");
2051:                            }
2052:                            finishingInfo.needAnErrorClause = false;
2053:                        } else {
2054:                            // check for sem and syn preds
2055:                            // Add any semantic predicate expression to the lookahead test
2056:                            if (alt.semPred != null) {
2057:                                // if debugging, wrap the evaluation of the predicate in a method
2058:                                //
2059:                                // translate $ and # references
2060:                                ActionTransInfo tInfo = new ActionTransInfo();
2061:                                String actionStr = processActionForSpecialSymbols(
2062:                                        alt.semPred, blk.line, currentRule,
2063:                                        tInfo);
2064:                                // ignore translation info...we don't need to
2065:                                // do anything with it.  call that will inform
2066:                                // SemanticPredicateListeners of the result
2067:                                if (((grammar instanceof  ParserGrammar) || (grammar instanceof  LexerGrammar))
2068:                                        && grammar.debuggingOutput) {
2069:                                    e = "("
2070:                                            + e
2071:                                            + "&& fireSemanticPredicateEvaluated(persistence.antlr.debug.SemanticPredicateEvent.PREDICTING,"
2072:                                            + //FIXME
2073:                                            addSemPred(charFormatter
2074:                                                    .escapeString(actionStr))
2075:                                            + "," + actionStr + "))";
2076:                                } else {
2077:                                    e = "(" + e + "&&(" + actionStr + "))";
2078:                                }
2079:                            }
2080:
2081:                            // Generate any syntactic predicates
2082:                            if (nIF > 0) {
2083:                                if (alt.synPred != null) {
2084:                                    println("else {");
2085:                                    tabs++;
2086:                                    genSynPred(alt.synPred, e);
2087:                                    closingBracesOfIFSequence++;
2088:                                } else {
2089:                                    println("else if " + e + " {");
2090:                                }
2091:                            } else {
2092:                                if (alt.synPred != null) {
2093:                                    genSynPred(alt.synPred, e);
2094:                                } else {
2095:                                    // when parsing trees, convert null to valid tree node
2096:                                    // with NULL lookahead.
2097:                                    if (grammar instanceof  TreeWalkerGrammar) {
2098:                                        println("if (_t == null)");
2099:                                        tabs++;
2100:                                        println("_t = ASTNULL;");
2101:                                        tabs--;
2102:                                    }
2103:                                    println("if " + e);
2104:                                    println("{");
2105:                                }
2106:                            }
2107:
2108:                        }
2109:
2110:                        nIF++;
2111:                        tabs++;
2112:                        genAlt(alt, blk);
2113:                        tabs--;
2114:                        println("}");
2115:                    }
2116:                }
2117:
2118:                String ps = "";
2119:                for (int i = 1; i <= closingBracesOfIFSequence; i++) {
2120:                    ps += "}";
2121:                }
2122:
2123:                // Restore the AST generation state
2124:                genAST = savegenAST;
2125:
2126:                // restore save text state
2127:                saveText = oldsaveTest;
2128:
2129:                // Return the finishing info.
2130:                if (createdLL1Switch) {
2131:                    tabs--;
2132:                    finishingInfo.postscript = ps + "break; }";
2133:                    finishingInfo.generatedSwitch = true;
2134:                    finishingInfo.generatedAnIf = nIF > 0;
2135:                    //return new CSharpBlockFinishingInfo(ps+"}",true,nIF>0); // close up switch statement
2136:
2137:                } else {
2138:                    finishingInfo.postscript = ps;
2139:                    finishingInfo.generatedSwitch = false;
2140:                    finishingInfo.generatedAnIf = nIF > 0;
2141:                    // return new CSharpBlockFinishingInfo(ps, false,nIF>0);
2142:                }
2143:                return finishingInfo;
2144:            }
2145:
2146:            private static boolean suitableForCaseExpression(Alternative a) {
2147:                return a.lookaheadDepth == 1 && a.semPred == null
2148:                        && !a.cache[1].containsEpsilon()
2149:                        && a.cache[1].fset.degree() <= caseSizeThreshold;
2150:            }
2151:
2152:            /** Generate code to link an element reference into the AST */
2153:            private void genElementAST(AlternativeElement el) {
2154:                // handle case where you're not building trees, but are in tree walker.
2155:                // Just need to get labels set up.
2156:                if (grammar instanceof  TreeWalkerGrammar && !grammar.buildAST) {
2157:                    String elementRef;
2158:                    String astName;
2159:
2160:                    // Generate names and declarations of the AST variable(s)
2161:                    if (el.getLabel() == null) {
2162:                        elementRef = lt1Value;
2163:                        // Generate AST variables for unlabeled stuff
2164:                        astName = "tmp" + astVarNumber + "_AST";
2165:                        astVarNumber++;
2166:                        // Map the generated AST variable in the alternate
2167:                        mapTreeVariable(el, astName);
2168:                        // Generate an "input" AST variable also
2169:                        println(labeledElementASTType + " " + astName
2170:                                + "_in = " + elementRef + ";");
2171:                    }
2172:                    return;
2173:                }
2174:
2175:                if (grammar.buildAST && syntacticPredLevel == 0) {
2176:                    boolean needASTDecl = (genAST && (el.getLabel() != null || (el
2177:                            .getAutoGenType() != GrammarElement.AUTO_GEN_BANG)));
2178:
2179:                    // RK: if we have a grammar element always generate the decl
2180:                    // since some guy can access it from an action and we can't
2181:                    // peek ahead (well not without making a mess).
2182:                    // I'd prefer taking this out.
2183:                    if (el.getAutoGenType() != GrammarElement.AUTO_GEN_BANG
2184:                            && (el instanceof  TokenRefElement))
2185:                        needASTDecl = true;
2186:
2187:                    boolean doNoGuessTest = (grammar.hasSyntacticPredicate && needASTDecl);
2188:
2189:                    String elementRef;
2190:                    String astNameBase;
2191:
2192:                    // Generate names and declarations of the AST variable(s)
2193:                    if (el.getLabel() != null) {
2194:                        // if the element is labeled use that name...
2195:                        elementRef = el.getLabel();
2196:                        astNameBase = el.getLabel();
2197:                    } else {
2198:                        // else generate a temporary name...
2199:                        elementRef = lt1Value;
2200:                        // Generate AST variables for unlabeled stuff
2201:                        astNameBase = "tmp" + astVarNumber;
2202:                        astVarNumber++;
2203:                    }
2204:
2205:                    // Generate the declaration if required.
2206:                    if (needASTDecl) {
2207:                        // Generate the declaration
2208:                        if (el instanceof  GrammarAtom) {
2209:                            GrammarAtom ga = (GrammarAtom) el;
2210:                            if (ga.getASTNodeType() != null) {
2211:                                genASTDeclaration(el, astNameBase, ga
2212:                                        .getASTNodeType());
2213:                                //println(ga.getASTNodeType()+" " + astName+" = null;");
2214:                            } else {
2215:                                genASTDeclaration(el, astNameBase,
2216:                                        labeledElementASTType);
2217:                                //println(labeledElementASTType+" " + astName + " = null;");
2218:                            }
2219:                        } else {
2220:                            genASTDeclaration(el, astNameBase,
2221:                                    labeledElementASTType);
2222:                            //println(labeledElementASTType+" " + astName + " = null;");
2223:                        }
2224:                    }
2225:
2226:                    // for convenience..
2227:                    String astName = astNameBase + "_AST";
2228:
2229:                    // Map the generated AST variable in the alternate
2230:                    mapTreeVariable(el, astName);
2231:                    if (grammar instanceof  TreeWalkerGrammar) {
2232:                        // Generate an "input" AST variable also
2233:                        println(labeledElementASTType + " " + astName
2234:                                + "_in = null;");
2235:                    }
2236:
2237:                    // Enclose actions with !guessing
2238:                    if (doNoGuessTest) {
2239:                        //println("if (0 == inputState.guessing)");
2240:                        //println("{");
2241:                        //tabs++;
2242:                    }
2243:
2244:                    // if something has a label assume it will be used
2245:                    // so we must initialize the RefAST
2246:                    if (el.getLabel() != null) {
2247:                        if (el instanceof  GrammarAtom) {
2248:                            println(astName
2249:                                    + " = "
2250:                                    + getASTCreateString((GrammarAtom) el,
2251:                                            elementRef) + ";");
2252:                        } else {
2253:                            println(astName + " = "
2254:                                    + getASTCreateString(elementRef) + ";");
2255:                        }
2256:                    }
2257:
2258:                    // if it has no label but a declaration exists initialize it.
2259:                    if (el.getLabel() == null && needASTDecl) {
2260:                        elementRef = lt1Value;
2261:                        if (el instanceof  GrammarAtom) {
2262:                            println(astName
2263:                                    + " = "
2264:                                    + getASTCreateString((GrammarAtom) el,
2265:                                            elementRef) + ";");
2266:                        } else {
2267:                            println(astName + " = "
2268:                                    + getASTCreateString(elementRef) + ";");
2269:                        }
2270:                        // Map the generated AST variable in the alternate
2271:                        if (grammar instanceof  TreeWalkerGrammar) {
2272:                            // set "input" AST variable also
2273:                            println(astName + "_in = " + elementRef + ";");
2274:                        }
2275:                    }
2276:
2277:                    if (genAST) {
2278:                        switch (el.getAutoGenType()) {
2279:                        case GrammarElement.AUTO_GEN_NONE:
2280:                            if (usingCustomAST
2281:                                    || ((el instanceof  GrammarAtom) && (((GrammarAtom) el)
2282:                                            .getASTNodeType() != null)))
2283:                                println("astFactory.addASTChild(currentAST, (AST)"
2284:                                        + astName + ");");
2285:                            else
2286:                                println("astFactory.addASTChild(currentAST, "
2287:                                        + astName + ");");
2288:                            break;
2289:                        case GrammarElement.AUTO_GEN_CARET:
2290:                            if (usingCustomAST
2291:                                    || ((el instanceof  GrammarAtom) && (((GrammarAtom) el)
2292:                                            .getASTNodeType() != null)))
2293:                                println("astFactory.makeASTRoot(currentAST, (AST)"
2294:                                        + astName + ");");
2295:                            else
2296:                                println("astFactory.makeASTRoot(currentAST, "
2297:                                        + astName + ");");
2298:                            break;
2299:                        default:
2300:                            break;
2301:                        }
2302:                    }
2303:                    if (doNoGuessTest) {
2304:                        //tabs--;
2305:                        //println("}");
2306:                    }
2307:                }
2308:            }
2309:
2310:            /** Close the try block and generate catch phrases
2311:             * if the element has a labeled handler in the rule
2312:             */
2313:            private void genErrorCatchForElement(AlternativeElement el) {
2314:                if (el.getLabel() == null)
2315:                    return;
2316:                String r = el.enclosingRuleName;
2317:                if (grammar instanceof  LexerGrammar) {
2318:                    r = CodeGenerator.encodeLexerRuleName(el.enclosingRuleName);
2319:                }
2320:                RuleSymbol rs = (RuleSymbol) grammar.getSymbol(r);
2321:                if (rs == null) {
2322:                    antlrTool.panic("Enclosing rule not found!");
2323:                }
2324:                ExceptionSpec ex = rs.block.findExceptionSpec(el.getLabel());
2325:                if (ex != null) {
2326:                    tabs--;
2327:                    println("}");
2328:                    genErrorHandler(ex);
2329:                }
2330:            }
2331:
2332:            /** Generate the catch phrases for a user-specified error handler */
2333:            private void genErrorHandler(ExceptionSpec ex) {
2334:                // Each ExceptionHandler in the ExceptionSpec is a separate catch
2335:                for (int i = 0; i < ex.handlers.size(); i++) {
2336:                    ExceptionHandler handler = (ExceptionHandler) ex.handlers
2337:                            .elementAt(i);
2338:                    // Generate catch phrase
2339:                    println("catch (" + handler.exceptionTypeAndName.getText()
2340:                            + ")");
2341:                    println("{");
2342:                    tabs++;
2343:                    if (grammar.hasSyntacticPredicate) {
2344:                        println("if (0 == inputState.guessing)");
2345:                        println("{");
2346:                        tabs++;
2347:                    }
2348:
2349:                    // When not guessing, execute user handler action
2350:                    ActionTransInfo tInfo = new ActionTransInfo();
2351:                    printAction(processActionForSpecialSymbols(handler.action
2352:                            .getText(), handler.action.getLine(), currentRule,
2353:                            tInfo));
2354:
2355:                    if (grammar.hasSyntacticPredicate) {
2356:                        tabs--;
2357:                        println("}");
2358:                        println("else");
2359:                        println("{");
2360:                        tabs++;
2361:                        // When guessing, rethrow exception
2362:                        //println("throw " + extractIdOfAction(handler.exceptionTypeAndName) + ";");
2363:                        println("throw;");
2364:                        tabs--;
2365:                        println("}");
2366:                    }
2367:                    // Close catch phrase
2368:                    tabs--;
2369:                    println("}");
2370:                }
2371:            }
2372:
2373:            /** Generate a try { opening if the element has a labeled handler in the rule */
2374:            private void genErrorTryForElement(AlternativeElement el) {
2375:                if (el.getLabel() == null)
2376:                    return;
2377:                String r = el.enclosingRuleName;
2378:                if (grammar instanceof  LexerGrammar) {
2379:                    r = CodeGenerator.encodeLexerRuleName(el.enclosingRuleName);
2380:                }
2381:                RuleSymbol rs = (RuleSymbol) grammar.getSymbol(r);
2382:                if (rs == null) {
2383:                    antlrTool.panic("Enclosing rule not found!");
2384:                }
2385:                ExceptionSpec ex = rs.block.findExceptionSpec(el.getLabel());
2386:                if (ex != null) {
2387:                    println("try   // for error handling");
2388:                    println("{");
2389:                    tabs++;
2390:                }
2391:            }
2392:
2393:            protected void genASTDeclaration(AlternativeElement el) {
2394:                genASTDeclaration(el, labeledElementASTType);
2395:            }
2396:
2397:            protected void genASTDeclaration(AlternativeElement el,
2398:                    String node_type) {
2399:                genASTDeclaration(el, el.getLabel(), node_type);
2400:            }
2401:
2402:            protected void genASTDeclaration(AlternativeElement el,
2403:                    String var_name, String node_type) {
2404:                // already declared?
2405:                if (declaredASTVariables.contains(el))
2406:                    return;
2407:
2408:                // emit code
2409:                //String s = StringUtils.stripFrontBack(node_type, "\"", "\"");
2410:                //println(s + " " + var_name + "_AST = null;");
2411:                println(node_type + " " + var_name + "_AST = null;");
2412:
2413:                // mark as declared
2414:                declaredASTVariables.put(el, el);
2415:            }
2416:
2417:            /** Generate a header that is common to all CSharp files */
2418:            protected void genHeader() {
2419:                println("// $ANTLR " + Tool.version + ": " + "\""
2420:                        + antlrTool.fileMinusPath(antlrTool.grammarFile) + "\""
2421:                        + " -> " + "\"" + grammar.getClassName() + ".cs\"$");
2422:            }
2423:
2424:            private void genLiteralsTest() {
2425:                println("_ttype = testLiteralsTable(_ttype);");
2426:            }
2427:
2428:            private void genLiteralsTestForPartialToken() {
2429:                println("_ttype = testLiteralsTable(text.ToString(_begin, text.Length-_begin), _ttype);");
2430:            }
2431:
2432:            protected void genMatch(BitSet b) {
2433:            }
2434:
2435:            protected void genMatch(GrammarAtom atom) {
2436:                if (atom instanceof  StringLiteralElement) {
2437:                    if (grammar instanceof  LexerGrammar) {
2438:                        genMatchUsingAtomText(atom);
2439:                    } else {
2440:                        genMatchUsingAtomTokenType(atom);
2441:                    }
2442:                } else if (atom instanceof  CharLiteralElement) {
2443:                    if (grammar instanceof  LexerGrammar) {
2444:                        genMatchUsingAtomText(atom);
2445:                    } else {
2446:                        antlrTool
2447:                                .error("cannot ref character literals in grammar: "
2448:                                        + atom);
2449:                    }
2450:                } else if (atom instanceof  TokenRefElement) {
2451:                    genMatchUsingAtomText(atom);
2452:                } else if (atom instanceof  WildcardElement) {
2453:                    gen((WildcardElement) atom);
2454:                }
2455:            }
2456:
2457:            protected void genMatchUsingAtomText(GrammarAtom atom) {
2458:                // match() for trees needs the _t cursor
2459:                String astArgs = "";
2460:                if (grammar instanceof  TreeWalkerGrammar) {
2461:                    if (usingCustomAST)
2462:                        astArgs = "(AST)_t,";
2463:                    else
2464:                        astArgs = "_t,";
2465:                }
2466:
2467:                // if in lexer and ! on element, save buffer index to kill later
2468:                if (grammar instanceof  LexerGrammar
2469:                        && (!saveText || atom.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
2470:                    declareSaveIndexVariableIfNeeded();
2471:                    println("_saveIndex = text.Length;");
2472:                }
2473:
2474:                print(atom.not ? "matchNot(" : "match(");
2475:                _print(astArgs);
2476:
2477:                // print out what to match
2478:                if (atom.atomText.equals("EOF")) {
2479:                    // horrible hack to handle EOF case
2480:                    _print("Token.EOF_TYPE");
2481:                } else {
2482:                    _print(atom.atomText);
2483:                }
2484:                _println(");");
2485:
2486:                if (grammar instanceof  LexerGrammar
2487:                        && (!saveText || atom.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
2488:                    declareSaveIndexVariableIfNeeded();
2489:                    println("text.Length = _saveIndex;"); // kill text atom put in buffer
2490:                }
2491:            }
2492:
2493:            protected void genMatchUsingAtomTokenType(GrammarAtom atom) {
2494:                // match() for trees needs the _t cursor
2495:                String astArgs = "";
2496:                if (grammar instanceof  TreeWalkerGrammar) {
2497:                    if (usingCustomAST)
2498:                        astArgs = "(AST)_t,";
2499:                    else
2500:                        astArgs = "_t,";
2501:                }
2502:
2503:                // If the literal can be mangled, generate the symbolic constant instead
2504:                String mangledName = null;
2505:                String s = astArgs + getValueString(atom.getType());
2506:
2507:                // matching
2508:                println((atom.not ? "matchNot(" : "match(") + s + ");");
2509:            }
2510:
2511:            /** Generate the nextToken() rule.  nextToken() is a synthetic
2512:             * lexer rule that is the implicit OR of all user-defined
2513:             * lexer rules.
2514:             */
2515:            public void genNextToken() {
2516:                // Are there any public rules?  If not, then just generate a
2517:                // fake nextToken().
2518:                boolean hasPublicRules = false;
2519:                for (int i = 0; i < grammar.rules.size(); i++) {
2520:                    RuleSymbol rs = (RuleSymbol) grammar.rules.elementAt(i);
2521:                    if (rs.isDefined() && rs.access.equals("public")) {
2522:                        hasPublicRules = true;
2523:                        break;
2524:                    }
2525:                }
2526:                if (!hasPublicRules) {
2527:                    println("");
2528:                    println("override public Token nextToken()\t\t\t//throws TokenStreamException");
2529:                    println("{");
2530:                    tabs++;
2531:                    println("try");
2532:                    println("{");
2533:                    tabs++;
2534:                    println("uponEOF();");
2535:                    tabs--;
2536:                    println("}");
2537:                    println("catch(CharStreamIOException csioe)");
2538:                    println("{");
2539:                    tabs++;
2540:                    println("throw new TokenStreamIOException(csioe.io);");
2541:                    tabs--;
2542:                    println("}");
2543:                    println("catch(CharStreamException cse)");
2544:                    println("{");
2545:                    tabs++;
2546:                    println("throw new TokenStreamException(cse.Message);");
2547:                    tabs--;
2548:                    println("}");
2549:                    println("return new CommonToken(Token.EOF_TYPE, \"\");");
2550:                    tabs--;
2551:                    println("}");
2552:                    println("");
2553:                    return;
2554:                }
2555:
2556:                // Create the synthesized nextToken() rule
2557:                RuleBlock nextTokenBlk = MakeGrammar.createNextTokenRule(
2558:                        grammar, grammar.rules, "nextToken");
2559:                // Define the nextToken rule symbol
2560:                RuleSymbol nextTokenRs = new RuleSymbol("mnextToken");
2561:                nextTokenRs.setDefined();
2562:                nextTokenRs.setBlock(nextTokenBlk);
2563:                nextTokenRs.access = "private";
2564:                grammar.define(nextTokenRs);
2565:                // Analyze the nextToken rule
2566:                boolean ok = grammar.theLLkAnalyzer.deterministic(nextTokenBlk);
2567:
2568:                // Generate the next token rule
2569:                String filterRule = null;
2570:                if (((LexerGrammar) grammar).filterMode) {
2571:                    filterRule = ((LexerGrammar) grammar).filterRule;
2572:                }
2573:
2574:                println("");
2575:                println("override public Token nextToken()\t\t\t//throws TokenStreamException");
2576:                println("{");
2577:                tabs++;
2578:                println("Token theRetToken = null;");
2579:                _println("tryAgain:");
2580:                println("for (;;)");
2581:                println("{");
2582:                tabs++;
2583:                println("Token _token = null;");
2584:                println("int _ttype = Token.INVALID_TYPE;");
2585:                if (((LexerGrammar) grammar).filterMode) {
2586:                    println("setCommitToPath(false);");
2587:                    if (filterRule != null) {
2588:                        // Here's a good place to ensure that the filter rule actually exists
2589:                        if (!grammar.isDefined(CodeGenerator
2590:                                .encodeLexerRuleName(filterRule))) {
2591:                            grammar.antlrTool.error("Filter rule " + filterRule
2592:                                    + " does not exist in this lexer");
2593:                        } else {
2594:                            RuleSymbol rs = (RuleSymbol) grammar
2595:                                    .getSymbol(CodeGenerator
2596:                                            .encodeLexerRuleName(filterRule));
2597:                            if (!rs.isDefined()) {
2598:                                grammar.antlrTool.error("Filter rule "
2599:                                        + filterRule
2600:                                        + " does not exist in this lexer");
2601:                            } else if (rs.access.equals("public")) {
2602:                                grammar.antlrTool.error("Filter rule "
2603:                                        + filterRule + " must be protected");
2604:                            }
2605:                        }
2606:                        println("int _m;");
2607:                        println("_m = mark();");
2608:                    }
2609:                }
2610:                println("resetText();");
2611:
2612:                println("try     // for char stream error handling");
2613:                println("{");
2614:                tabs++;
2615:
2616:                // Generate try around whole thing to trap scanner errors
2617:                println("try     // for lexical error handling");
2618:                println("{");
2619:                tabs++;
2620:
2621:                // Test for public lexical rules with empty paths
2622:                for (int i = 0; i < nextTokenBlk.getAlternatives().size(); i++) {
2623:                    Alternative a = nextTokenBlk.getAlternativeAt(i);
2624:                    if (a.cache[1].containsEpsilon()) {
2625:                        //String r = a.head.toString();
2626:                        RuleRefElement rr = (RuleRefElement) a.head;
2627:                        String r = CodeGenerator
2628:                                .decodeLexerRuleName(rr.targetRule);
2629:                        antlrTool.warning("public lexical rule " + r
2630:                                + " is optional (can match \"nothing\")");
2631:                    }
2632:                }
2633:
2634:                // Generate the block
2635:                String newline = System.getProperty("line.separator");
2636:                CSharpBlockFinishingInfo howToFinish = genCommonBlock(
2637:                        nextTokenBlk, false);
2638:                String errFinish = "if (LA(1)==EOF_CHAR) { uponEOF(); returnToken_ = makeToken(Token.EOF_TYPE); }";
2639:                errFinish += newline + "\t\t\t\t";
2640:                if (((LexerGrammar) grammar).filterMode) {
2641:                    if (filterRule == null) {
2642:                        //kunle: errFinish += "else { consume(); continue tryAgain; }";
2643:                        errFinish += "\t\t\t\telse";
2644:                        errFinish += "\t\t\t\t{";
2645:                        errFinish += "\t\t\t\t\tconsume();";
2646:                        errFinish += "\t\t\t\t\tgoto tryAgain;";
2647:                        errFinish += "\t\t\t\t}";
2648:                    } else {
2649:                        errFinish += "\t\t\t\t\telse" + newline + "\t\t\t\t\t{"
2650:                                + newline + "\t\t\t\t\tcommit();" + newline
2651:                                + "\t\t\t\t\ttry {m" + filterRule + "(false);}"
2652:                                + newline
2653:                                + "\t\t\t\t\tcatch(RecognitionException e)"
2654:                                + newline + "\t\t\t\t\t{" + newline
2655:                                + "\t\t\t\t\t	// catastrophic failure"
2656:                                + newline + "\t\t\t\t\t	reportError(e);"
2657:                                + newline + "\t\t\t\t\t	consume();" + newline
2658:                                + "\t\t\t\t\t}" + newline
2659:                                + "\t\t\t\t\tgoto tryAgain;" + newline
2660:                                + "\t\t\t\t}";
2661:                    }
2662:                } else {
2663:                    errFinish += "else {" + throwNoViable + "}";
2664:                }
2665:                genBlockFinish(howToFinish, errFinish);
2666:
2667:                // at this point a valid token has been matched, undo "mark" that was done
2668:                if (((LexerGrammar) grammar).filterMode && filterRule != null) {
2669:                    println("commit();");
2670:                }
2671:
2672:                // Generate literals test if desired
2673:                // make sure _ttype is set first; note returnToken_ must be
2674:                // non-null as the rule was required to create it.
2675:                println("if ( null==returnToken_ ) goto tryAgain; // found SKIP token");
2676:                println("_ttype = returnToken_.Type;");
2677:                if (((LexerGrammar) grammar).getTestLiterals()) {
2678:                    genLiteralsTest();
2679:                }
2680:
2681:                // return token created by rule reference in switch
2682:                println("returnToken_.Type = _ttype;");
2683:                println("return returnToken_;");
2684:
2685:                // Close try block
2686:                tabs--;
2687:                println("}");
2688:                println("catch (RecognitionException e) {");
2689:                tabs++;
2690:                if (((LexerGrammar) grammar).filterMode) {
2691:                    if (filterRule == null) {
2692:                        println("if (!getCommitToPath())");
2693:                        println("{");
2694:                        tabs++;
2695:                        println("consume();");
2696:                        println("goto tryAgain;");
2697:                        tabs--;
2698:                        println("}");
2699:                    } else {
2700:                        println("if (!getCommitToPath())");
2701:                        println("{");
2702:                        tabs++;
2703:                        println("rewind(_m);");
2704:                        println("resetText();");
2705:                        println("try {m" + filterRule + "(false);}");
2706:                        println("catch(RecognitionException ee) {");
2707:                        println("	// horrendous failure: error in filter rule");
2708:                        println("	reportError(ee);");
2709:                        println("	consume();");
2710:                        println("}");
2711:                        //println("goto tryAgain;");
2712:                        tabs--;
2713:                        println("}");
2714:                        println("else");
2715:                    }
2716:                }
2717:                if (nextTokenBlk.getDefaultErrorHandler()) {
2718:                    println("{");
2719:                    tabs++;
2720:                    println("reportError(e);");
2721:                    println("consume();");
2722:                    tabs--;
2723:                    println("}");
2724:                } else {
2725:                    // pass on to invoking routine
2726:                    tabs++;
2727:                    println("throw new TokenStreamRecognitionException(e);");
2728:                    tabs--;
2729:                }
2730:                tabs--;
2731:                println("}");
2732:
2733:                // close CharStreamException try
2734:                tabs--;
2735:                println("}");
2736:                println("catch (CharStreamException cse) {");
2737:                println("	if ( cse is CharStreamIOException ) {");
2738:                println("		throw new TokenStreamIOException(((CharStreamIOException)cse).io);");
2739:                println("	}");
2740:                println("	else {");
2741:                println("		throw new TokenStreamException(cse.Message);");
2742:                println("	}");
2743:                println("}");
2744:
2745:                // close for-loop
2746:                tabs--;
2747:                println("}");
2748:
2749:                // close method nextToken
2750:                tabs--;
2751:                println("}");
2752:                println("");
2753:            }
2754:
2755:            /** Gen a named rule block.
2756:             * ASTs are generated for each element of an alternative unless
2757:             * the rule or the alternative have a '!' modifier.
2758:             *
2759:             * If an alternative defeats the default tree construction, it
2760:             * must set <rule>_AST to the root of the returned AST.
2761:             *
2762:             * Each alternative that does automatic tree construction, builds
2763:             * up root and child list pointers in an ASTPair structure.
2764:             *
2765:             * A rule finishes by setting the returnAST variable from the
2766:             * ASTPair.
2767:             *
2768:             * @param rule The name of the rule to generate
2769:             * @param startSymbol true if the rule is a start symbol (i.e., not referenced elsewhere)
2770:             */
2771:            public void genRule(RuleSymbol s, boolean startSymbol, int ruleNum,
2772:                    TokenManager tm) {
2773:                tabs = 1;
2774:                if (DEBUG_CODE_GENERATOR)
2775:                    System.out.println("genRule(" + s.getId() + ")");
2776:                if (!s.isDefined()) {
2777:                    antlrTool.error("undefined rule: " + s.getId());
2778:                    return;
2779:                }
2780:
2781:                // Generate rule return type, name, arguments
2782:                RuleBlock rblk = s.getBlock();
2783:                currentRule = rblk;
2784:                currentASTResult = s.getId();
2785:
2786:                // clear list of declared ast variables..
2787:                declaredASTVariables.clear();
2788:
2789:                // Save the AST generation state, and set it to that of the rule
2790:                boolean savegenAST = genAST;
2791:                genAST = genAST && rblk.getAutoGen();
2792:
2793:                // boolean oldsaveTest = saveText;
2794:                saveText = rblk.getAutoGen();
2795:
2796:                // print javadoc comment if any
2797:                if (s.comment != null) {
2798:                    _println(s.comment);
2799:                }
2800:
2801:                // Gen method access and final qualifier
2802:                //print(s.access + " final ");
2803:                print(s.access + " ");
2804:
2805:                // Gen method return type (note lexer return action set at rule creation)
2806:                if (rblk.returnAction != null) {
2807:                    // Has specified return value
2808:                    _print(extractTypeOfAction(rblk.returnAction, rblk
2809:                            .getLine(), rblk.getColumn())
2810:                            + " ");
2811:                } else {
2812:                    // No specified return value
2813:                    _print("void ");
2814:                }
2815:
2816:                // Gen method name
2817:                _print(s.getId() + "(");
2818:
2819:                // Additional rule parameters common to all rules for this grammar
2820:                _print(commonExtraParams);
2821:                if (commonExtraParams.length() != 0 && rblk.argAction != null) {
2822:                    _print(",");
2823:                }
2824:
2825:                // Gen arguments
2826:                if (rblk.argAction != null) {
2827:                    // Has specified arguments
2828:                    _println("");
2829:                    tabs++;
2830:                    println(rblk.argAction);
2831:                    tabs--;
2832:                    print(")");
2833:                } else {
2834:                    // No specified arguments
2835:                    _print(")");
2836:                }
2837:
2838:                // Gen throws clause and open curly
2839:                _print(" //throws " + exceptionThrown);
2840:                if (grammar instanceof  ParserGrammar) {
2841:                    _print(", TokenStreamException");
2842:                } else if (grammar instanceof  LexerGrammar) {
2843:                    _print(", CharStreamException, TokenStreamException");
2844:                }
2845:                // Add user-defined exceptions unless lexer (for now)
2846:                if (rblk.throwsSpec != null) {
2847:                    if (grammar instanceof  LexerGrammar) {
2848:                        antlrTool
2849:                                .error("user-defined throws spec not allowed (yet) for lexer rule "
2850:                                        + rblk.ruleName);
2851:                    } else {
2852:                        _print(", " + rblk.throwsSpec);
2853:                    }
2854:                }
2855:
2856:                _println("");
2857:                _println("{");
2858:                tabs++;
2859:
2860:                // Convert return action to variable declaration
2861:                if (rblk.returnAction != null)
2862:                    println(rblk.returnAction + ";");
2863:
2864:                // print out definitions needed by rules for various grammar types
2865:                println(commonLocalVars);
2866:
2867:                if (grammar.traceRules) {
2868:                    if (grammar instanceof  TreeWalkerGrammar) {
2869:                        if (usingCustomAST)
2870:                            println("traceIn(\"" + s.getId() + "\",(AST)_t);");
2871:                        else
2872:                            println("traceIn(\"" + s.getId() + "\",_t);");
2873:                    } else {
2874:                        println("traceIn(\"" + s.getId() + "\");");
2875:                    }
2876:                }
2877:
2878:                if (grammar instanceof  LexerGrammar) {
2879:                    // lexer rule default return value is the rule's token name
2880:                    // This is a horrible hack to support the built-in EOF lexer rule.
2881:                    if (s.getId().equals("mEOF"))
2882:                        println("_ttype = Token.EOF_TYPE;");
2883:                    else
2884:                        println("_ttype = " + s.getId().substring(1) + ";");
2885:
2886:                    // delay creation of _saveIndex until we need it OK?
2887:                    bSaveIndexCreated = false;
2888:
2889:                    /*
2890:                          println("boolean old_saveConsumedInput=saveConsumedInput;");
2891:                          if ( !rblk.getAutoGen() ) {		// turn off "save input" if ! on rule
2892:                          println("saveConsumedInput=false;");
2893:                          }
2894:                     */
2895:                }
2896:
2897:                // if debugging, write code to mark entry to the rule
2898:                if (grammar.debuggingOutput)
2899:                    if (grammar instanceof  ParserGrammar)
2900:                        println("fireEnterRule(" + ruleNum + ",0);");
2901:                    else if (grammar instanceof  LexerGrammar)
2902:                        println("fireEnterRule(" + ruleNum + ",_ttype);");
2903:
2904:                // Generate trace code if desired
2905:                if (grammar.debuggingOutput || grammar.traceRules) {
2906:                    println("try { // debugging");
2907:                    tabs++;
2908:                }
2909:
2910:                // Initialize AST variables
2911:                if (grammar instanceof  TreeWalkerGrammar) {
2912:                    // "Input" value for rule
2913:                    println(labeledElementASTType + " " + s.getId()
2914:                            + "_AST_in = (" + labeledElementASTType + ")_t;");
2915:                }
2916:                if (grammar.buildAST) {
2917:                    // Parser member used to pass AST returns from rule invocations
2918:                    println("returnAST = null;");
2919:                    // Tracks AST construction
2920:                    // println("ASTPair currentAST = (inputState.guessing==0) ? new ASTPair() : null;");
2921:                    println("ASTPair currentAST = new ASTPair();");
2922:                    // User-settable return value for rule.
2923:                    println(labeledElementASTType + " " + s.getId()
2924:                            + "_AST = null;");
2925:                }
2926:
2927:                genBlockPreamble(rblk);
2928:                genBlockInitAction(rblk);
2929:                println("");
2930:
2931:                // Search for an unlabeled exception specification attached to the rule
2932:                ExceptionSpec unlabeledUserSpec = rblk.findExceptionSpec("");
2933:
2934:                // Generate try block around the entire rule for  error handling
2935:                if (unlabeledUserSpec != null || rblk.getDefaultErrorHandler()) {
2936:                    println("try {      // for error handling");
2937:                    tabs++;
2938:                }
2939:
2940:                // Generate the alternatives
2941:                if (rblk.alternatives.size() == 1) {
2942:                    // One alternative -- use simple form
2943:                    Alternative alt = rblk.getAlternativeAt(0);
2944:                    String pred = alt.semPred;
2945:                    if (pred != null)
2946:                        genSemPred(pred, currentRule.line);
2947:                    if (alt.synPred != null) {
2948:                        antlrTool
2949:                                .warning(
2950:                                        "Syntactic predicate ignored for single alternative",
2951:                                        grammar.getFilename(), alt.synPred
2952:                                                .getLine(), alt.synPred
2953:                                                .getColumn());
2954:                    }
2955:                    genAlt(alt, rblk);
2956:                } else {
2957:                    // Multiple alternatives -- generate complex form
2958:                    boolean ok = grammar.theLLkAnalyzer.deterministic(rblk);
2959:
2960:                    CSharpBlockFinishingInfo howToFinish = genCommonBlock(rblk,
2961:                            false);
2962:                    genBlockFinish(howToFinish, throwNoViable);
2963:                }
2964:
2965:                // Generate catch phrase for error handling
2966:                if (unlabeledUserSpec != null || rblk.getDefaultErrorHandler()) {
2967:                    // Close the try block
2968:                    tabs--;
2969:                    println("}");
2970:                }
2971:
2972:                // Generate user-defined or default catch phrases
2973:                if (unlabeledUserSpec != null) {
2974:                    genErrorHandler(unlabeledUserSpec);
2975:                } else if (rblk.getDefaultErrorHandler()) {
2976:                    // Generate default catch phrase
2977:                    println("catch (" + exceptionThrown + " ex)");
2978:                    println("{");
2979:                    tabs++;
2980:                    // Generate code to handle error if not guessing
2981:                    if (grammar.hasSyntacticPredicate) {
2982:                        println("if (0 == inputState.guessing)");
2983:                        println("{");
2984:                        tabs++;
2985:                    }
2986:                    println("reportError(ex);");
2987:                    if (!(grammar instanceof  TreeWalkerGrammar)) {
2988:                        // Generate code to consume until token in k==1 follow set
2989:                        Lookahead follow = grammar.theLLkAnalyzer.FOLLOW(1,
2990:                                rblk.endNode);
2991:                        String followSetName = getBitsetName(markBitsetForGen(follow.fset));
2992:                        println("consume();");
2993:                        println("consumeUntil(" + followSetName + ");");
2994:                    } else {
2995:                        // Just consume one token
2996:                        println("if (null != _t)");
2997:                        println("{");
2998:                        tabs++;
2999:                        println("_t = _t.getNextSibling();");
3000:                        tabs--;
3001:                        println("}");
3002:                    }
3003:                    if (grammar.hasSyntacticPredicate) {
3004:                        tabs--;
3005:                        // When guessing, rethrow exception
3006:                        println("}");
3007:                        println("else");
3008:                        println("{");
3009:                        tabs++;
3010:                        //println("throw ex;");
3011:                        println("throw;");
3012:                        tabs--;
3013:                        println("}");
3014:                    }
3015:                    // Close catch phrase
3016:                    tabs--;
3017:                    println("}");
3018:                }
3019:
3020:                // Squirrel away the AST "return" value
3021:                if (grammar.buildAST) {
3022:                    println("returnAST = " + s.getId() + "_AST;");
3023:                }
3024:
3025:                // Set return tree value for tree walkers
3026:                if (grammar instanceof  TreeWalkerGrammar) {
3027:                    println("retTree_ = _t;");
3028:                }
3029:
3030:                // Generate literals test for lexer rules so marked
3031:                if (rblk.getTestLiterals()) {
3032:                    if (s.access.equals("protected")) {
3033:                        genLiteralsTestForPartialToken();
3034:                    } else {
3035:                        genLiteralsTest();
3036:                    }
3037:                }
3038:
3039:                // if doing a lexer rule, dump code to create token if necessary
3040:                if (grammar instanceof  LexerGrammar) {
3041:                    println("if (_createToken && (null == _token) && (_ttype != Token.SKIP))");
3042:                    println("{");
3043:                    tabs++;
3044:                    println("_token = makeToken(_ttype);");
3045:                    println("_token.setText(text.ToString(_begin, text.Length-_begin));");
3046:                    tabs--;
3047:                    println("}");
3048:                    println("returnToken_ = _token;");
3049:                }
3050:
3051:                // Gen the return statement if there is one (lexer has hard-wired return action)
3052:                if (rblk.returnAction != null) {
3053:                    println("return "
3054:                            + extractIdOfAction(rblk.returnAction, rblk
3055:                                    .getLine(), rblk.getColumn()) + ";");
3056:                }
3057:
3058:                if (grammar.debuggingOutput || grammar.traceRules) {
3059:                    tabs--;
3060:                    println("}");
3061:                    println("finally");
3062:                    println("{ // debugging");
3063:                    tabs++;
3064:
3065:                    // If debugging, generate calls to mark exit of rule
3066:                    if (grammar.debuggingOutput)
3067:                        if (grammar instanceof  ParserGrammar)
3068:                            println("fireExitRule(" + ruleNum + ",0);");
3069:                        else if (grammar instanceof  LexerGrammar)
3070:                            println("fireExitRule(" + ruleNum + ",_ttype);");
3071:
3072:                    if (grammar.traceRules) {
3073:                        if (grammar instanceof  TreeWalkerGrammar) {
3074:                            println("traceOut(\"" + s.getId() + "\",_t);");
3075:                        } else {
3076:                            println("traceOut(\"" + s.getId() + "\");");
3077:                        }
3078:                    }
3079:
3080:                    tabs--;
3081:                    println("}");
3082:                }
3083:
3084:                tabs--;
3085:                println("}");
3086:                println("");
3087:
3088:                // Restore the AST generation state
3089:                genAST = savegenAST;
3090:
3091:                // restore char save state
3092:                // saveText = oldsaveTest;
3093:            }
3094:
3095:            private void GenRuleInvocation(RuleRefElement rr) {
3096:                // dump rule name
3097:                _print(rr.targetRule + "(");
3098:
3099:                // lexers must tell rule if it should set returnToken_
3100:                if (grammar instanceof  LexerGrammar) {
3101:                    // if labeled, could access Token, so tell rule to create
3102:                    if (rr.getLabel() != null) {
3103:                        _print("true");
3104:                    } else {
3105:                        _print("false");
3106:                    }
3107:                    if (commonExtraArgs.length() != 0 || rr.args != null) {
3108:                        _print(",");
3109:                    }
3110:                }
3111:
3112:                // Extra arguments common to all rules for this grammar
3113:                _print(commonExtraArgs);
3114:                if (commonExtraArgs.length() != 0 && rr.args != null) {
3115:                    _print(",");
3116:                }
3117:
3118:                // Process arguments to method, if any
3119:                RuleSymbol rs = (RuleSymbol) grammar.getSymbol(rr.targetRule);
3120:                if (rr.args != null) {
3121:                    // When not guessing, execute user arg action
3122:                    ActionTransInfo tInfo = new ActionTransInfo();
3123:                    String args = processActionForSpecialSymbols(rr.args, 0,
3124:                            currentRule, tInfo);
3125:                    if (tInfo.assignToRoot || tInfo.refRuleRoot != null) {
3126:                        antlrTool.error("Arguments of rule reference '"
3127:                                + rr.targetRule + "' cannot set or ref #"
3128:                                + currentRule.getRuleName(), grammar
3129:                                .getFilename(), rr.getLine(), rr.getColumn());
3130:                    }
3131:                    _print(args);
3132:
3133:                    // Warn if the rule accepts no arguments
3134:                    if (rs.block.argAction == null) {
3135:                        antlrTool.warning("Rule '" + rr.targetRule
3136:                                + "' accepts no arguments", grammar
3137:                                .getFilename(), rr.getLine(), rr.getColumn());
3138:                    }
3139:                } else {
3140:                    // For C++, no warning if rule has parameters, because there may be default
3141:                    // values for all of the parameters
3142:                    if (rs.block.argAction != null) {
3143:                        antlrTool.warning(
3144:                                "Missing parameters on reference to rule "
3145:                                        + rr.targetRule, grammar.getFilename(),
3146:                                rr.getLine(), rr.getColumn());
3147:                    }
3148:                }
3149:                _println(");");
3150:
3151:                // move down to the first child while parsing
3152:                if (grammar instanceof  TreeWalkerGrammar) {
3153:                    println("_t = retTree_;");
3154:                }
3155:            }
3156:
3157:            protected void genSemPred(String pred, int line) {
3158:                // translate $ and # references
3159:                ActionTransInfo tInfo = new ActionTransInfo();
3160:                pred = processActionForSpecialSymbols(pred, line, currentRule,
3161:                        tInfo);
3162:                // ignore translation info...we don't need to do anything with it.
3163:                String escapedPred = charFormatter.escapeString(pred);
3164:
3165:                // if debugging, wrap the semantic predicate evaluation in a method
3166:                // that can tell SemanticPredicateListeners the result
3167:                if (grammar.debuggingOutput
3168:                        && ((grammar instanceof  ParserGrammar) || (grammar instanceof  LexerGrammar)))
3169:                    pred = "fireSemanticPredicateEvaluated(persistence.antlr.debug.SemanticPredicateEvent.VALIDATING,"
3170:                            + addSemPred(escapedPred) + "," + pred + ")";
3171:                println("if (!(" + pred + "))");
3172:                println("  throw new SemanticException(\"" + escapedPred
3173:                        + "\");");
3174:            }
3175:
3176:            /** Write an array of Strings which are the semantic predicate
3177:             *  expressions.  The debugger will reference them by number only
3178:             */
3179:            protected void genSemPredMap() {
3180:                Enumeration e = semPreds.elements();
3181:                println("private string[] _semPredNames = {");
3182:                tabs++;
3183:                while (e.hasMoreElements())
3184:                    println("\"" + e.nextElement() + "\",");
3185:                tabs--;
3186:                println("};");
3187:            }
3188:
3189:            protected void genSynPred(SynPredBlock blk, String lookaheadExpr) {
3190:                if (DEBUG_CODE_GENERATOR)
3191:                    System.out.println("gen=>(" + blk + ")");
3192:
3193:                // Dump synpred result variable
3194:                println("bool synPredMatched" + blk.ID + " = false;");
3195:                // Gen normal lookahead test
3196:                println("if (" + lookaheadExpr + ")");
3197:                println("{");
3198:                tabs++;
3199:
3200:                // Save input state
3201:                if (grammar instanceof  TreeWalkerGrammar) {
3202:                    println("AST __t" + blk.ID + " = _t;");
3203:                } else {
3204:                    println("int _m" + blk.ID + " = mark();");
3205:                }
3206:
3207:                // Once inside the try, assume synpred works unless exception caught
3208:                println("synPredMatched" + blk.ID + " = true;");
3209:                println("inputState.guessing++;");
3210:
3211:                // if debugging, tell listeners that a synpred has started
3212:                if (grammar.debuggingOutput
3213:                        && ((grammar instanceof  ParserGrammar) || (grammar instanceof  LexerGrammar))) {
3214:                    println("fireSyntacticPredicateStarted();");
3215:                }
3216:
3217:                syntacticPredLevel++;
3218:                println("try {");
3219:                tabs++;
3220:                gen((AlternativeBlock) blk); // gen code to test predicate
3221:                tabs--;
3222:                //println("System.out.println(\"pred "+blk+" succeeded\");");
3223:                println("}");
3224:                //kunle: lose a few warnings cheaply
3225:                //  println("catch (" + exceptionThrown + " pe)");
3226:                println("catch (" + exceptionThrown + ")");
3227:                println("{");
3228:                tabs++;
3229:                println("synPredMatched" + blk.ID + " = false;");
3230:                //println("System.out.println(\"pred "+blk+" failed\");");
3231:                tabs--;
3232:                println("}");
3233:
3234:                // Restore input state
3235:                if (grammar instanceof  TreeWalkerGrammar) {
3236:                    println("_t = __t" + blk.ID + ";");
3237:                } else {
3238:                    println("rewind(_m" + blk.ID + ");");
3239:                }
3240:
3241:                println("inputState.guessing--;");
3242:
3243:                // if debugging, tell listeners how the synpred turned out
3244:                if (grammar.debuggingOutput
3245:                        && ((grammar instanceof  ParserGrammar) || (grammar instanceof  LexerGrammar))) {
3246:                    println("if (synPredMatched" + blk.ID + ")");
3247:                    println("  fireSyntacticPredicateSucceeded();");
3248:                    println("else");
3249:                    println("  fireSyntacticPredicateFailed();");
3250:                }
3251:
3252:                syntacticPredLevel--;
3253:                tabs--;
3254:
3255:                // Close lookahead test
3256:                println("}");
3257:
3258:                // Test synred result
3259:                println("if ( synPredMatched" + blk.ID + " )");
3260:                println("{");
3261:            }
3262:
3263:            /** Generate a static array containing the names of the tokens,
3264:             * indexed by the token type values.  This static array is used
3265:             * to format error messages so that the token identifers or literal
3266:             * strings are displayed instead of the token numbers.
3267:             *
3268:             * If a lexical rule has a paraphrase, use it rather than the
3269:             * token label.
3270:             */
3271:            public void genTokenStrings() {
3272:                // Generate a string for each token.  This creates a static
3273:                // array of Strings indexed by token type.
3274:                println("");
3275:                println("public static readonly string[] tokenNames_ = new string[] {");
3276:                tabs++;
3277:
3278:                // Walk the token vocabulary and generate a Vector of strings
3279:                // from the tokens.
3280:                Vector v = grammar.tokenManager.getVocabulary();
3281:                for (int i = 0; i < v.size(); i++) {
3282:                    String s = (String) v.elementAt(i);
3283:                    if (s == null) {
3284:                        s = "<" + String.valueOf(i) + ">";
3285:                    }
3286:                    if (!s.startsWith("\"") && !s.startsWith("<")) {
3287:                        TokenSymbol ts = (TokenSymbol) grammar.tokenManager
3288:                                .getTokenSymbol(s);
3289:                        if (ts != null && ts.getParaphrase() != null) {
3290:                            s = StringUtils.stripFrontBack(ts.getParaphrase(),
3291:                                    "\"", "\"");
3292:                        }
3293:                    } else if (s.startsWith("\"")) {
3294:                        s = StringUtils.stripFrontBack(s, "\"", "\"");
3295:                    }
3296:                    print(charFormatter.literalString(s));
3297:                    if (i != v.size() - 1) {
3298:                        _print(",");
3299:                    }
3300:                    _println("");
3301:                }
3302:
3303:                // Close the string array initailizer
3304:                tabs--;
3305:                println("};");
3306:            }
3307:
3308:            /** Generate the token types CSharp file */
3309:            protected void genTokenTypes(TokenManager tm) throws IOException {
3310:                // Open the token output CSharp file and set the currentOutput stream
3311:                // SAS: file open was moved to a method so a subclass can override
3312:                //      This was mainly for the VAJ interface
3313:                setupOutput(tm.getName() + TokenTypesFileSuffix);
3314:
3315:                tabs = 0;
3316:
3317:                // Generate the header common to all CSharp files
3318:                genHeader();
3319:                // Do not use printAction because we assume tabs==0
3320:                println(behavior.getHeaderAction(""));
3321:
3322:                // Generate the CSharp namespace declaration (if specified)
3323:                if (nameSpace != null)
3324:                    nameSpace.emitDeclarations(currentOutput);
3325:                tabs++;
3326:
3327:                // Encapsulate the definitions in a class.  This has to be done as a class because
3328:                // they are all constants and CSharp inteface  types cannot contain constants.
3329:                println("public class " + tm.getName() + TokenTypesFileSuffix);
3330:                //println("public class " + getTokenTypesClassName());
3331:                println("{");
3332:                tabs++;
3333:
3334:                genTokenDefinitions(tm);
3335:
3336:                // Close the interface
3337:                tabs--;
3338:                println("}");
3339:
3340:                tabs--;
3341:                // Generate the CSharp namespace closures (if required)
3342:                if (nameSpace != null)
3343:                    nameSpace.emitClosures(currentOutput);
3344:
3345:                // Close the tokens output file
3346:                currentOutput.close();
3347:                currentOutput = null;
3348:                exitIfError();
3349:            }
3350:
3351:            protected void genTokenDefinitions(TokenManager tm)
3352:                    throws IOException {
3353:                // Generate a definition for each token type
3354:                Vector v = tm.getVocabulary();
3355:
3356:                // Do special tokens manually
3357:                println("public const int EOF = " + Token.EOF_TYPE + ";");
3358:                println("public const int NULL_TREE_LOOKAHEAD = "
3359:                        + Token.NULL_TREE_LOOKAHEAD + ";");
3360:
3361:                for (int i = Token.MIN_USER_TYPE; i < v.size(); i++) {
3362:                    String s = (String) v.elementAt(i);
3363:                    if (s != null) {
3364:                        if (s.startsWith("\"")) {
3365:                            // a string literal
3366:                            StringLiteralSymbol sl = (StringLiteralSymbol) tm
3367:                                    .getTokenSymbol(s);
3368:                            if (sl == null) {
3369:                                antlrTool.panic("String literal " + s
3370:                                        + " not in symbol table");
3371:                            } else if (sl.label != null) {
3372:                                println("public const int " + sl.label + " = "
3373:                                        + i + ";");
3374:                            } else {
3375:                                String mangledName = mangleLiteral(s);
3376:                                if (mangledName != null) {
3377:                                    // We were able to create a meaningful mangled token name
3378:                                    println("public const int " + mangledName
3379:                                            + " = " + i + ";");
3380:                                    // if no label specified, make the label equal to the mangled name
3381:                                    sl.label = mangledName;
3382:                                } else {
3383:                                    println("// " + s + " = " + i);
3384:                                }
3385:                            }
3386:                        } else if (!s.startsWith("<")) {
3387:                            println("public const int " + s + " = " + i + ";");
3388:                        }
3389:                    }
3390:                }
3391:                println("");
3392:            }
3393:
3394:            /** Process a string for an simple expression for use in xx/action.g
3395:             * it is used to cast simple tokens/references to the right type for
3396:             * the generated language. Basically called for every element in
3397:             * the vector to getASTCreateString(vector V)
3398:             * @param str A String.
3399:             */
3400:            public String processStringForASTConstructor(String str) {
3401:                /*
3402:                System.out.println("processStringForASTConstructor: str = "+str+
3403:                                   ", custom = "+(new Boolean(usingCustomAST)).toString()+
3404:                                   ", tree = "+(new Boolean((grammar instanceof TreeWalkerGrammar))).toString()+
3405:                                   ", parser = "+(new Boolean((grammar instanceof ParserGrammar))).toString()+
3406:                                   ", notDefined = "+(new Boolean((!(grammar.tokenManager.tokenDefined(str))))).toString()
3407:                                   );
3408:                 */
3409:                if (usingCustomAST
3410:                        && ((grammar instanceof  TreeWalkerGrammar) || (grammar instanceof  ParserGrammar))
3411:                        && !(grammar.tokenManager.tokenDefined(str))) {
3412:                    //System.out.println("processStringForASTConstructor: "+str+" with cast");
3413:                    return "(AST)" + str;
3414:                } else {
3415:                    //System.out.println("processStringForASTConstructor: "+str);
3416:                    return str;
3417:                }
3418:            }
3419:
3420:            /** Get a string for an expression to generate creation of an AST subtree.
3421:             * @param v A Vector of String, where each element is an expression
3422:             *          in the target language yielding an AST node.
3423:             */
3424:            public String getASTCreateString(Vector v) {
3425:                if (v.size() == 0) {
3426:                    return "";
3427:                }
3428:                StringBuffer buf = new StringBuffer();
3429:                buf.append("(" + labeledElementASTType
3430:                        + ")astFactory.make( (new ASTArray(" + v.size() + "))");
3431:                for (int i = 0; i < v.size(); i++) {
3432:                    buf.append(".add(" + v.elementAt(i) + ")");
3433:                }
3434:                buf.append(")");
3435:                return buf.toString();
3436:            }
3437:
3438:            /** Get a string for an expression to generate creating of an AST node
3439:             * @param atom The grammar node for which you are creating the node
3440:             * @param str The arguments to the AST constructor
3441:             */
3442:            public String getASTCreateString(GrammarAtom atom,
3443:                    String astCtorArgs) {
3444:                String astCreateString = "astFactory.create(" + astCtorArgs
3445:                        + ")";
3446:
3447:                if (atom == null)
3448:                    return getASTCreateString(astCtorArgs);
3449:                else {
3450:                    if (atom.getASTNodeType() != null) {
3451:                        // this Atom was instantiated from a Token that had an "AST" option - associating
3452:                        // it with a specific heterogeneous AST type - applied to either:
3453:                        // 1) it's underlying TokenSymbol (in the "tokens {} section" or,
3454:                        // 2) a particular token reference in the grammar
3455:                        //
3456:                        // For option (1), we simply generate a cast to hetero-AST type
3457:                        // For option (2), we generate a call to factory.create(Token, ASTNodeType) and cast it too
3458:                        TokenSymbol ts = grammar.tokenManager
3459:                                .getTokenSymbol(atom.getText());
3460:                        if ((ts == null)
3461:                                || (ts.getASTNodeType() != atom
3462:                                        .getASTNodeType()))
3463:                            astCreateString = "(" + atom.getASTNodeType()
3464:                                    + ") astFactory.create(" + astCtorArgs
3465:                                    + ", \"" + atom.getASTNodeType() + "\")";
3466:                        else if ((ts != null) && (ts.getASTNodeType() != null))
3467:                            astCreateString = "(" + ts.getASTNodeType() + ") "
3468:                                    + astCreateString;
3469:                    } else if (usingCustomAST)
3470:                        astCreateString = "(" + labeledElementASTType + ") "
3471:                                + astCreateString;
3472:                }
3473:                return astCreateString;
3474:            }
3475:
3476:            /** Returns a string expression that creates an AST node using the specified
3477:             *  AST constructor argument string.
3478:             *  Parses the first (possibly only) argument in the supplied AST ctor argument
3479:             *	string to obtain the token type -- ctorID.
3480:             *
3481:             *  IF the token type is a valid token symbol AND
3482:             *	   it has an associated AST node type     AND
3483:             *	   this is not a #[ID, "T", "ASTType"] constructor
3484:             *	THEN
3485:             *	   generate a call to factory.create(ID, Text, token.ASTNodeType())
3486:             *
3487:             *  #[ID, "T", "ASTType"] constructors are mapped to astFactory.create(ID, "T", "ASTType")
3488:             *
3489:             *  The supported AST constructor forms are:
3490:             *		#[ID]
3491:             *		#[ID, "text"]
3492:             *  	#[ID, "text", ASTclassname]	-- introduced in 2.7.2
3493:             *
3494:             * @param astCtorArgs The arguments to the AST constructor
3495:             */
3496:            public String getASTCreateString(String astCtorArgs) {
3497:                // kunle: 19-Aug-2002
3498:                // This AST creation string is almost certainly[*1] a manual tree construction request.
3499:                // From the manual [I couldn't read ALL of the code ;-)], this can only be one of:
3500:                // 1) #[ID]                     -- 'astCtorArgs' contains: 'ID'                     (without quotes)    or,
3501:                // 2) #[ID, "T"]                -- 'astCtorArgs' contains: 'ID, "Text"'             (without single quotes) or,
3502:                // kunle: 08-Dec-2002 - 2.7.2a6
3503:                // 3) #[ID, "T", "ASTTypeName"] -- 'astCtorArgs' contains: 'ID, "T", "ASTTypeName"' (without single quotes)
3504:                //
3505:                // [*1]  In my tests, 'atom' was '== null' only for manual tree construction requests
3506:
3507:                if (astCtorArgs == null) {
3508:                    astCtorArgs = "";
3509:                }
3510:                String astCreateString = "astFactory.create(" + astCtorArgs
3511:                        + ")";
3512:                String ctorID = astCtorArgs;
3513:                String ctorText = null;
3514:                int commaIndex;
3515:                boolean ctorIncludesCustomType = false; // Is this a #[ID, "t", "ASTType"] constructor?
3516:
3517:                commaIndex = astCtorArgs.indexOf(',');
3518:                if (commaIndex != -1) {
3519:                    ctorID = astCtorArgs.substring(0, commaIndex); // the 'ID'   portion of #[ID, "Text"]
3520:                    ctorText = astCtorArgs.substring(commaIndex + 1,
3521:                            astCtorArgs.length()); // the 'Text' portion of #[ID, "Text"]
3522:                    commaIndex = ctorText.indexOf(',');
3523:                    if (commaIndex != -1) {
3524:                        // This is an AST creation of the form: #[ID, "Text", "ASTTypename"]
3525:                        // Support for this was introduced with 2.7.2a6
3526:                        // create default type or (since 2.7.2) 3rd arg is classname
3527:                        ctorIncludesCustomType = true;
3528:                    }
3529:                }
3530:                TokenSymbol ts = grammar.tokenManager.getTokenSymbol(ctorID);
3531:                if ((null != ts) && (null != ts.getASTNodeType()))
3532:                    astCreateString = "(" + ts.getASTNodeType() + ") "
3533:                            + astCreateString;
3534:                else if (usingCustomAST)
3535:                    astCreateString = "(" + labeledElementASTType + ") "
3536:                            + astCreateString;
3537:
3538:                return astCreateString;
3539:            }
3540:
3541:            protected String getLookaheadTestExpression(Lookahead[] look, int k) {
3542:                StringBuffer e = new StringBuffer(100);
3543:                boolean first = true;
3544:
3545:                e.append("(");
3546:                for (int i = 1; i <= k; i++) {
3547:                    BitSet p = look[i].fset;
3548:                    if (!first) {
3549:                        e.append(") && (");
3550:                    }
3551:                    first = false;
3552:
3553:                    // Syn preds can yield <end-of-syn-pred> (epsilon) lookahead.
3554:                    // There is no way to predict what that token would be.  Just
3555:                    // allow anything instead.
3556:                    if (look[i].containsEpsilon()) {
3557:                        e.append("true");
3558:                    } else {
3559:                        e.append(getLookaheadTestTerm(i, p));
3560:                    }
3561:                }
3562:                e.append(")");
3563:
3564:                return e.toString();
3565:            }
3566:
3567:            /**Generate a lookahead test expression for an alternate.  This
3568:             * will be a series of tests joined by '&&' and enclosed by '()',
3569:             * the number of such tests being determined by the depth of the lookahead.
3570:             */
3571:            protected String getLookaheadTestExpression(Alternative alt,
3572:                    int maxDepth) {
3573:                int depth = alt.lookaheadDepth;
3574:                if (depth == GrammarAnalyzer.NONDETERMINISTIC) {
3575:                    // if the decision is nondeterministic, do the best we can: LL(k)
3576:                    // any predicates that are around will be generated later.
3577:                    depth = grammar.maxk;
3578:                }
3579:
3580:                if (maxDepth == 0) {
3581:                    // empty lookahead can result from alt with sem pred
3582:                    // that can see end of token.  E.g., A : {pred}? ('a')? ;
3583:                    return "( true )";
3584:                }
3585:                return "(" + getLookaheadTestExpression(alt.cache, depth) + ")";
3586:            }
3587:
3588:            /**Generate a depth==1 lookahead test expression given the BitSet.
3589:             * This may be one of:
3590:             * 1) a series of 'x==X||' tests
3591:             * 2) a range test using >= && <= where possible,
3592:             * 3) a bitset membership test for complex comparisons
3593:             * @param k The lookahead level
3594:             * @param p The lookahead set for level k
3595:             */
3596:            protected String getLookaheadTestTerm(int k, BitSet p) {
3597:                // Determine the name of the item to be compared
3598:                String ts = lookaheadString(k);
3599:
3600:                // Generate a range expression if possible
3601:                int[] elems = p.toArray();
3602:                if (elementsAreRange(elems)) {
3603:                    return getRangeExpression(k, elems);
3604:                }
3605:
3606:                // Generate a bitset membership test if possible
3607:                StringBuffer e;
3608:                int degree = p.degree();
3609:                if (degree == 0) {
3610:                    return "true";
3611:                }
3612:
3613:                if (degree >= bitsetTestThreshold) {
3614:                    int bitsetIdx = markBitsetForGen(p);
3615:                    return getBitsetName(bitsetIdx) + ".member(" + ts + ")";
3616:                }
3617:
3618:                // Otherwise, generate the long-winded series of "x==X||" tests
3619:                e = new StringBuffer();
3620:                for (int i = 0; i < elems.length; i++) {
3621:                    // Get the compared-to item (token or character value)
3622:                    String cs = getValueString(elems[i]);
3623:
3624:                    // Generate the element comparison
3625:                    if (i > 0)
3626:                        e.append("||");
3627:                    e.append(ts);
3628:                    e.append("==");
3629:                    e.append(cs);
3630:                }
3631:                return e.toString();
3632:            }
3633:
3634:            /** Return an expression for testing a contiguous renage of elements
3635:             * @param k The lookahead level
3636:             * @param elems The elements representing the set, usually from BitSet.toArray().
3637:             * @return String containing test expression.
3638:             */
3639:            public String getRangeExpression(int k, int[] elems) {
3640:                if (!elementsAreRange(elems)) {
3641:                    antlrTool.panic("getRangeExpression called with non-range");
3642:                }
3643:                int begin = elems[0];
3644:                int end = elems[elems.length - 1];
3645:
3646:                return "(" + lookaheadString(k) + " >= "
3647:                        + getValueString(begin) + " && " + lookaheadString(k)
3648:                        + " <= " + getValueString(end) + ")";
3649:            }
3650:
3651:            /** getValueString: get a string representation of a token or char value
3652:             * @param value The token or char value
3653:             */
3654:            private String getValueString(int value) {
3655:                String cs;
3656:                if (grammar instanceof  LexerGrammar) {
3657:                    cs = charFormatter.literalChar(value);
3658:                } else {
3659:                    TokenSymbol ts = grammar.tokenManager
3660:                            .getTokenSymbolAt(value);
3661:                    if (ts == null) {
3662:                        return "" + value; // return token type as string
3663:                        // antlrTool.panic("vocabulary for token type " + value + " is null");
3664:                    }
3665:                    String tId = ts.getId();
3666:                    if (ts instanceof  StringLiteralSymbol) {
3667:                        // if string literal, use predefined label if any
3668:                        // if no predefined, try to mangle into LITERAL_xxx.
3669:                        // if can't mangle, use int value as last resort
3670:                        StringLiteralSymbol sl = (StringLiteralSymbol) ts;
3671:                        String label = sl.getLabel();
3672:                        if (label != null) {
3673:                            cs = label;
3674:                        } else {
3675:                            cs = mangleLiteral(tId);
3676:                            if (cs == null) {
3677:                                cs = String.valueOf(value);
3678:                            }
3679:                        }
3680:                    } else {
3681:                        cs = tId;
3682:                    }
3683:                }
3684:                return cs;
3685:            }
3686:
3687:            /**Is the lookahead for this alt empty? */
3688:            protected boolean lookaheadIsEmpty(Alternative alt, int maxDepth) {
3689:                int depth = alt.lookaheadDepth;
3690:                if (depth == GrammarAnalyzer.NONDETERMINISTIC) {
3691:                    depth = grammar.maxk;
3692:                }
3693:                for (int i = 1; i <= depth && i <= maxDepth; i++) {
3694:                    BitSet p = alt.cache[i].fset;
3695:                    if (p.degree() != 0) {
3696:                        return false;
3697:                    }
3698:                }
3699:                return true;
3700:            }
3701:
3702:            private String lookaheadString(int k) {
3703:                if (grammar instanceof  TreeWalkerGrammar) {
3704:                    return "_t.Type";
3705:                }
3706:                return "LA(" + k + ")";
3707:            }
3708:
3709:            /** Mangle a string literal into a meaningful token name.  This is
3710:             * only possible for literals that are all characters.  The resulting
3711:             * mangled literal name is literalsPrefix with the text of the literal
3712:             * appended.
3713:             * @return A string representing the mangled literal, or null if not possible.
3714:             */
3715:            private String mangleLiteral(String s) {
3716:                String mangled = antlrTool.literalsPrefix;
3717:                for (int i = 1; i < s.length() - 1; i++) {
3718:                    if (!Character.isLetter(s.charAt(i)) && s.charAt(i) != '_') {
3719:                        return null;
3720:                    }
3721:                    mangled += s.charAt(i);
3722:                }
3723:                if (antlrTool.upperCaseMangledLiterals) {
3724:                    mangled = mangled.toUpperCase();
3725:                }
3726:                return mangled;
3727:            }
3728:
3729:            /** Map an identifier to it's corresponding tree-node variable.
3730:             * This is context-sensitive, depending on the rule and alternative
3731:             * being generated
3732:             * @param idParam The identifier name to map
3733:             * @return The mapped id (which may be the same as the input), or null if the mapping is invalid due to duplicates
3734:             */
3735:            public String mapTreeId(String idParam, ActionTransInfo transInfo) {
3736:                // if not in an action of a rule, nothing to map.
3737:                if (currentRule == null)
3738:                    return idParam;
3739:
3740:                boolean in_var = false;
3741:                String id = idParam;
3742:                if (grammar instanceof  TreeWalkerGrammar) {
3743:                    if (!grammar.buildAST) {
3744:                        in_var = true;
3745:                    }
3746:                    // If the id ends with "_in", then map it to the input variable
3747:                    else if (id.length() > 3
3748:                            && id.lastIndexOf("_in") == id.length() - 3) {
3749:                        // Strip off the "_in"
3750:                        id = id.substring(0, id.length() - 3);
3751:                        in_var = true;
3752:                    }
3753:                }
3754:
3755:                // Check the rule labels.  If id is a label, then the output
3756:                // variable is label_AST, and the input variable is plain label.
3757:                for (int i = 0; i < currentRule.labeledElements.size(); i++) {
3758:                    AlternativeElement elt = (AlternativeElement) currentRule.labeledElements
3759:                            .elementAt(i);
3760:                    if (elt.getLabel().equals(id)) {
3761:                        return in_var ? id : id + "_AST";
3762:                    }
3763:                }
3764:
3765:                // Failing that, check the id-to-variable map for the alternative.
3766:                // If the id is in the map, then output variable is the name in the
3767:                // map, and input variable is name_in
3768:                String s = (String) treeVariableMap.get(id);
3769:                if (s != null) {
3770:                    if (s == NONUNIQUE) {
3771:                        // There is more than one element with this id
3772:                        antlrTool.error("Ambiguous reference to AST element "
3773:                                + id + " in rule " + currentRule.getRuleName());
3774:                        return null;
3775:                    } else if (s.equals(currentRule.getRuleName())) {
3776:                        // a recursive call to the enclosing rule is
3777:                        // ambiguous with the rule itself.
3778:                        //				if( in_var )
3779:                        //					System.out.println("returning null (rulename)");
3780:                        antlrTool.error("Ambiguous reference to AST element "
3781:                                + id + " in rule " + currentRule.getRuleName());
3782:                        return null;
3783:                    } else {
3784:                        return in_var ? s + "_in" : s;
3785:                    }
3786:                }
3787:
3788:                // Failing that, check the rule name itself.  Output variable
3789:                // is rule_AST; input variable is rule_AST_in (treeparsers).
3790:                if (id.equals(currentRule.getRuleName())) {
3791:                    String r = in_var ? id + "_AST_in" : id + "_AST";
3792:                    if (transInfo != null) {
3793:                        if (!in_var) {
3794:                            transInfo.refRuleRoot = r;
3795:                        }
3796:                    }
3797:                    return r;
3798:                } else {
3799:                    // id does not map to anything -- return itself.
3800:                    return id;
3801:                }
3802:            }
3803:
3804:            /** Given an element and the name of an associated AST variable,
3805:             * create a mapping between the element "name" and the variable name.
3806:             */
3807:            private void mapTreeVariable(AlternativeElement e, String name) {
3808:                // For tree elements, defer to the root
3809:                if (e instanceof  TreeElement) {
3810:                    mapTreeVariable(((TreeElement) e).root, name);
3811:                    return;
3812:                }
3813:
3814:                // Determine the name of the element, if any, for mapping purposes
3815:                String elName = null;
3816:
3817:                // Don't map labeled items
3818:                if (e.getLabel() == null) {
3819:                    if (e instanceof  TokenRefElement) {
3820:                        // use the token id
3821:                        elName = ((TokenRefElement) e).atomText;
3822:                    } else if (e instanceof  RuleRefElement) {
3823:                        // use the rule name
3824:                        elName = ((RuleRefElement) e).targetRule;
3825:                    }
3826:                }
3827:                // Add the element to the tree variable map if it has a name
3828:                if (elName != null) {
3829:                    if (treeVariableMap.get(elName) != null) {
3830:                        // Name is already in the map -- mark it as duplicate
3831:                        treeVariableMap.remove(elName);
3832:                        treeVariableMap.put(elName, NONUNIQUE);
3833:                    } else {
3834:                        treeVariableMap.put(elName, name);
3835:                    }
3836:                }
3837:            }
3838:
3839:            /** Lexically process tree-specifiers in the action.
3840:             *  This will replace #id and #(...) with the appropriate
3841:             *  function calls and/or variables.
3842:             */
3843:            protected String processActionForSpecialSymbols(String actionStr,
3844:                    int line, RuleBlock currentRule, ActionTransInfo tInfo) {
3845:                if (actionStr == null || actionStr.length() == 0)
3846:                    return null;
3847:
3848:                // The action trans info tells us (at the moment) whether an
3849:                // assignment was done to the rule's tree root.
3850:                if (grammar == null)
3851:                    return actionStr;
3852:
3853:                // see if we have anything to do...
3854:                if ((grammar.buildAST && actionStr.indexOf('#') != -1)
3855:                        || grammar instanceof  TreeWalkerGrammar
3856:                        || ((grammar instanceof  LexerGrammar || grammar instanceof  ParserGrammar) && actionStr
3857:                                .indexOf('$') != -1)) {
3858:                    // Create a lexer to read an action and return the translated version
3859:                    persistence.antlr.actions.csharp.ActionLexer lexer = new persistence.antlr.actions.csharp.ActionLexer(
3860:                            actionStr, currentRule, this , tInfo);
3861:
3862:                    lexer.setLineOffset(line);
3863:                    lexer.setFilename(grammar.getFilename());
3864:                    lexer.setTool(antlrTool);
3865:
3866:                    try {
3867:                        lexer.mACTION(true);
3868:                        actionStr = lexer.getTokenObject().getText();
3869:                        // System.out.println("action translated: "+actionStr);
3870:                        // System.out.println("trans info is "+tInfo);
3871:                    } catch (RecognitionException ex) {
3872:                        lexer.reportError(ex);
3873:                        return actionStr;
3874:                    } catch (TokenStreamException tex) {
3875:                        antlrTool.panic("Error reading action:" + actionStr);
3876:                        return actionStr;
3877:                    } catch (CharStreamException io) {
3878:                        antlrTool.panic("Error reading action:" + actionStr);
3879:                        return actionStr;
3880:                    }
3881:                }
3882:                return actionStr;
3883:            }
3884:
3885:            private void setupGrammarParameters(Grammar g) {
3886:                if (g instanceof  ParserGrammar || g instanceof  LexerGrammar
3887:                        || g instanceof  TreeWalkerGrammar) {
3888:                    /* RK: options also have to be added to Grammar.java and for options
3889:                     * on the file level entries have to be defined in
3890:                     * DefineGrammarSymbols.java and passed around via 'globals' in antlrTool.java
3891:                     */
3892:                    if (antlrTool.nameSpace != null)
3893:                        nameSpace = new CSharpNameSpace(antlrTool.nameSpace
3894:                                .getName());
3895:                    //genHashLines = antlrTool.genHashLines;
3896:
3897:                    /* let grammar level options override filelevel ones...
3898:                     */
3899:                    if (g.hasOption("namespace")) {
3900:                        Token t = g.getOption("namespace");
3901:                        if (t != null) {
3902:                            nameSpace = new CSharpNameSpace(t.getText());
3903:                        }
3904:                    }
3905:                    /*
3906:                    if( g.hasOption("genHashLines") ) {
3907:                    	Token t = g.getOption("genHashLines");
3908:                    	if( t != null )  {
3909:                    		String val = StringUtils.stripFrontBack(t.getText(),"\"","\"");
3910:                    		genHashLines = val.equals("true");
3911:                    	}
3912:                    }
3913:                     */
3914:                }
3915:
3916:                if (g instanceof  ParserGrammar) {
3917:                    labeledElementASTType = "AST";
3918:                    if (g.hasOption("ASTLabelType")) {
3919:                        Token tsuffix = g.getOption("ASTLabelType");
3920:                        if (tsuffix != null) {
3921:                            String suffix = StringUtils.stripFrontBack(tsuffix
3922:                                    .getText(), "\"", "\"");
3923:                            if (suffix != null) {
3924:                                usingCustomAST = true;
3925:                                labeledElementASTType = suffix;
3926:                            }
3927:                        }
3928:                    }
3929:                    labeledElementType = "Token ";
3930:                    labeledElementInit = "null";
3931:                    commonExtraArgs = "";
3932:                    commonExtraParams = "";
3933:                    commonLocalVars = "";
3934:                    lt1Value = "LT(1)";
3935:                    exceptionThrown = "RecognitionException";
3936:                    throwNoViable = "throw new NoViableAltException(LT(1), getFilename());";
3937:                } else if (g instanceof  LexerGrammar) {
3938:                    labeledElementType = "char ";
3939:                    labeledElementInit = "'\\0'";
3940:                    commonExtraArgs = "";
3941:                    commonExtraParams = "bool _createToken";
3942:                    commonLocalVars = "int _ttype; Token _token=null; int _begin=text.Length;";
3943:                    lt1Value = "LA(1)";
3944:                    exceptionThrown = "RecognitionException";
3945:                    throwNoViable = "throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());";
3946:                } else if (g instanceof  TreeWalkerGrammar) {
3947:                    labeledElementASTType = "AST";
3948:                    labeledElementType = "AST";
3949:                    if (g.hasOption("ASTLabelType")) {
3950:                        Token tsuffix = g.getOption("ASTLabelType");
3951:                        if (tsuffix != null) {
3952:                            String suffix = StringUtils.stripFrontBack(tsuffix
3953:                                    .getText(), "\"", "\"");
3954:                            if (suffix != null) {
3955:                                usingCustomAST = true;
3956:                                labeledElementASTType = suffix;
3957:                                labeledElementType = suffix;
3958:                            }
3959:                        }
3960:                    }
3961:                    if (!g.hasOption("ASTLabelType")) {
3962:                        g.setOption("ASTLabelType", new Token(
3963:                                ANTLRTokenTypes.STRING_LITERAL, "AST"));
3964:                    }
3965:                    labeledElementInit = "null";
3966:                    commonExtraArgs = "_t";
3967:                    commonExtraParams = "AST _t";
3968:                    commonLocalVars = "";
3969:                    if (usingCustomAST)
3970:                        lt1Value = "(_t==ASTNULL) ? null : ("
3971:                                + labeledElementASTType + ")_t";
3972:                    else
3973:                        lt1Value = "_t";
3974:                    exceptionThrown = "RecognitionException";
3975:                    throwNoViable = "throw new NoViableAltException(_t);";
3976:                } else {
3977:                    antlrTool.panic("Unknown grammar type");
3978:                }
3979:            }
3980:
3981:            /** This method exists so a subclass, namely VAJCodeGenerator,
3982:             *  can open the file in its own evil way.  JavaCodeGenerator
3983:             *  simply opens a text file...
3984:             */
3985:            public void setupOutput(String className) throws IOException {
3986:                currentOutput = antlrTool.openOutputFile(className + ".cs");
3987:            }
3988:
3989:            /** Helper method from Eric Smith's version of CSharpCodeGenerator.*/
3990:            private static String OctalToUnicode(String str) {
3991:                // only do any conversion if the string looks like "'\003'"
3992:                if ((4 <= str.length()) && ('\'' == str.charAt(0))
3993:                        && ('\\' == str.charAt(1))
3994:                        && (('0' <= str.charAt(2)) && ('7' >= str.charAt(2)))
3995:                        && ('\'' == str.charAt(str.length() - 1))) {
3996:                    // convert octal representation to decimal, then to hex
3997:                    Integer x = Integer.valueOf(str.substring(2,
3998:                            str.length() - 1), 8);
3999:
4000:                    return "'\\x" + Integer.toHexString(x.intValue()) + "'";
4001:                } else {
4002:                    return str;
4003:                }
4004:            }
4005:
4006:            /** Helper method that returns the name of the interface/class/enum type for
4007:                token type constants.
4008:             */
4009:            public String getTokenTypesClassName() {
4010:                TokenManager tm = grammar.tokenManager;
4011:                return new String(tm.getName() + TokenTypesFileSuffix);
4012:            }
4013:
4014:            private void declareSaveIndexVariableIfNeeded() {
4015:                if (!bSaveIndexCreated) {
4016:                    println("int _saveIndex = 0;");
4017:                    bSaveIndexCreated = true;
4018:                }
4019:            }
4020:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.