Logo Search packages:      
Sourcecode: antlr version File versions

void antlr::CppCodeGenerator::gen ( RuleRefElement  rr  )  [inline, virtual]

Generate code for the given grammar element.

Parameters:
blk The rule-reference to generate

Implements antlr::CodeGenerator.

Definition at line 513 of file CppCodeGenerator.java.

References _print(), antlr::Grammar::buildAST, antlr::CodeGenerator::DEBUG_CODE_GENERATOR, genErrorCatchForElement(), genErrorTryForElement(), antlr::Grammar::getFilename(), antlr::Grammar::getSymbol(), antlr::CodeGenerator::grammar, antlr::Grammar::hasSyntacticPredicate, println(), antlr::CodeGenerator::printTabs(), and antlr::CodeGenerator::tabs.

      {
            if ( DEBUG_CODE_GENERATOR ) System.out.println("genRR("+rr+")");
            RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
            if (rs == null || !rs.isDefined())
            {
                  // Is this redundant???
                  antlrTool.error("Rule '" + rr.targetRule + "' is not defined", grammar.getFilename(), rr.getLine(), rr.getColumn());
                  return;
            }
            if (!(rs instanceof RuleSymbol))
            {
                  // Is this redundant???
                  antlrTool.error("'" + rr.targetRule + "' does not name a grammar rule", grammar.getFilename(), rr.getLine(), rr.getColumn());
                  return;
            }

            genErrorTryForElement(rr);

            // AST value for labeled rule refs in tree walker.
            // This is not AST construction;  it is just the input tree node value.
            if ( grammar instanceof TreeWalkerGrammar &&
                  rr.getLabel() != null &&
                  syntacticPredLevel == 0 )
            {
                  println(rr.getLabel() + " = (_t == ASTNULL) ? "+labeledElementASTInit+" : "+lt1Value+";");
            }

            // if in lexer and ! on rule ref or alt or rule, save buffer index to
            // kill later
            if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) )
            {
                  println("_saveIndex = text.length();");
            }

            // Process return value assignment if any
            printTabs();
            if (rr.idAssign != null)
            {
                  // Warn if the rule has no return type
                  if (rs.block.returnAction == null)
                  {
                        antlrTool.warning("Rule '" + rr.targetRule + "' has no return type", grammar.getFilename(), rr.getLine(), rr.getColumn());
                  }
                  _print(rr.idAssign + "=");
            } else {
                  // Warn about return value if any, but not inside syntactic predicate
                  if ( !(grammar instanceof LexerGrammar) && syntacticPredLevel == 0 && rs.block.returnAction != null)
                  {
                        antlrTool.warning("Rule '" + rr.targetRule + "' returns a value", grammar.getFilename(), rr.getLine(), rr.getColumn());
                  }
            }

            // Call the rule
            GenRuleInvocation(rr);

            // if in lexer and ! on element or alt or rule, save buffer index to kill later
            if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
                  println("text.erase(_saveIndex);");
            }

            // if not in a syntactic predicate
            if (syntacticPredLevel == 0)
            {
                  boolean doNoGuessTest = (
                        grammar.hasSyntacticPredicate &&
                        (
                              grammar.buildAST && rr.getLabel() != null ||
                              (genAST && rr.getAutoGenType() == GrammarElement.AUTO_GEN_NONE)
                        )
                  );

                  if (doNoGuessTest) {
                        println("if (inputState->guessing==0) {");
                        tabs++;
                  }

                  if (grammar.buildAST && rr.getLabel() != null)
                  {
                        // always gen variable for rule return on labeled rules
                        println(rr.getLabel() + "_AST = returnAST;");
                  }

                  if (genAST)
                  {
                        switch (rr.getAutoGenType())
                        {
                        case GrammarElement.AUTO_GEN_NONE:
                              if( usingCustomAST )
                                    println("astFactory->addASTChild(currentAST, static_cast<"+namespaceAntlr+"RefAST>(returnAST));");
                              else
                                    println("astFactory->addASTChild( currentAST, returnAST );");
                              break;
                        case GrammarElement.AUTO_GEN_CARET:
                              // FIXME: RK: I'm not so sure this should be an error..
                              // I think it might actually work and be usefull at times.
                              antlrTool.error("Internal: encountered ^ after rule reference");
                              break;
                        default:
                              break;
                        }
                  }

                  // if a lexer and labeled, Token label defined at rule level, just set it here
                  if ( grammar instanceof LexerGrammar && rr.getLabel() != null )
                  {
                        println(rr.getLabel()+"=_returnToken;");
                  }

                  if (doNoGuessTest)
                  {
                        tabs--;
                        println("}");
                  }
            }
            genErrorCatchForElement(rr);
      }


Generated by  Doxygen 1.6.0   Back to index