| 
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectcom.ph.pr.parser.ASTBuilder
public class ASTBuilder
A singleton class providing capabilities for creating a class hierarchy for an AST for a supplied grammar, and creating the tree of AST objects, each one corresponding to a non-terminal, upon parsing. This is based on GOLD Parsing System and its Java engine .
parse(ClassLoader, String, String), 
generateClasses(String, String, String, String)| Field Summary | |
|---|---|
static java.lang.String | 
AST_SUFFIX
 | 
private  java.util.Map | 
ast2Comments
 | 
private  boolean | 
caseInsensitive
 | 
private  java.util.Map | 
childMap
 | 
private  ASTNode | 
curAst
Current AST node (eventually this is returned by parse(ClassLoader, String, String)). | 
private  java.lang.String | 
curComment
 | 
static java.lang.String | 
GOLD_NON_TERMINAL_END
 | 
static java.lang.String | 
GOLD_NON_TERMINAL_START
 | 
static java.lang.String | 
GOLD_PROD_SYMB
 | 
private  java.lang.String | 
grammar
 | 
private  boolean | 
grammarLoaded
 | 
private  java.lang.String | 
input
 | 
private static ASTBuilder | 
instance
The singleton instance  | 
private  java.io.PrintWriter | 
out
 | 
private  goldengine.java.GOLDParser | 
parser
 | 
private  java.util.Map | 
prodMap
Map of namesof
 rule non-terminalsto an
 ArrayList of productions, as Strings. | 
private  java.util.Map | 
red2Ast
Map of Reductionto corresponding ASTNode. | 
private  java.util.Map | 
terminalMap
 | 
| Fields inherited from interface goldengine.java.GPMessageConstants | 
|---|
gpMsgAccept, gpMsgCommentError, gpMsgCommentLineRead, gpMsgInternalError, gpMsgLexicalError, gpMsgNotLoadedError, gpMsgReduction, gpMsgSyntaxError, gpMsgTokenRead | 
| Constructor Summary | |
|---|---|
private  | 
ASTBuilder()
 | 
| Method Summary | |
|---|---|
 void | 
generateClasses(java.lang.String root,
                java.lang.String pkg,
                java.lang.String visitorPkg,
                java.lang.String visitorName)
Generate the classes implementing ASTNodefor each
 non-terminal. | 
 java.util.Collection | 
getAllAsts()
 | 
 java.util.Map | 
getAst2Comments()
 | 
 ASTNode | 
getStart()
 | 
 java.util.Map | 
getTerminalMap()
 | 
private  boolean | 
isNonTerminal(java.lang.String s)
 | 
static void | 
main(java.lang.String[] argv)
 | 
private  java.lang.String | 
nonTerminalName(java.lang.String s)
 | 
 ASTNode | 
parse(java.lang.ClassLoader loader,
      java.lang.String pkg,
      java.lang.String input)
Parse the input.  | 
static java.lang.String | 
pkg2Dir(java.lang.String pkg)
 | 
private  void | 
processReduction(java.lang.ClassLoader myLoader,
                 java.lang.String pkg,
                 goldengine.java.Reduction reduction)
 | 
private  void | 
readRules()
Read the GOLD's .cgt file (provided in #setGrammar(String)) and
 initialize childMapand prodMap. | 
 void | 
setGrammar(java.lang.String g,
           boolean force)
Loads the grammar.  | 
static ASTBuilder | 
singleton()
 | 
| Methods inherited from class java.lang.Object | 
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait | 
| Field Detail | 
|---|
public static final java.lang.String AST_SUFFIX
private static ASTBuilder instance
public static final java.lang.String GOLD_NON_TERMINAL_START
public static final java.lang.String GOLD_NON_TERMINAL_END
public static final java.lang.String GOLD_PROD_SYMB
private java.lang.String curComment
private final java.util.Map childMap
private final java.util.Map prodMap
namesof
 rule non-terminalsto an
 ArrayList of productions, as Strings.
private java.io.PrintWriter out
private java.lang.String grammar
private java.lang.String input
private final goldengine.java.GOLDParser parser
private boolean grammarLoaded
private java.util.Map red2Ast
Reductionto corresponding ASTNode.
private java.util.Map ast2Comments
private ASTNode curAst
parse(ClassLoader, String, String)).
private java.util.Map terminalMap
private boolean caseInsensitive
| Constructor Detail | 
|---|
private ASTBuilder()
| Method Detail | 
|---|
public static ASTBuilder singleton()
private java.lang.String nonTerminalName(java.lang.String s)
private boolean isNonTerminal(java.lang.String s)
private void readRules()
#setGrammar(String)) and
 initialize childMapand prodMap.
public void setGrammar(java.lang.String g,
                       boolean force)
                throws goldengine.java.ParserException
g - path to GOLD compiled grammar (.cgt file).force - if true, the grammar is reloaded, otherwise, if
            the grammar points to the same one loaded previously, it is
            ignored.
goldengine.java.ParserException - whenever {GOLDParser#loadCompiledGrammar} does.GOLDParser.loadCompiledGrammar(String)
public void generateClasses(java.lang.String root,
                            java.lang.String pkg,
                            java.lang.String visitorPkg,
                            java.lang.String visitorName)
                     throws goldengine.java.ParserException,
                            java.io.IOException
ASTNodefor each
 non-terminal. They will be named by the name of the non-terminal with a
 suffix AST_SUFFIXand structure as explained below. The
 parse(ClassLoader, String, String)method will instantiate and
 populate appropriate objects from this hierarchy during parsing, using
 setters as described here. Thus, for the following production 
 
 
 
 
  
   
    
     
      
       
        
         
          
           
            
             
              <ext_statement> ::= 
                        SUB tkName <formal_list_opt> tkEol <statement_list> END SUB tkEol
                |       DECLARE FUNCTION tkName LIB tkString <formal_list_opt> <as_opt> tkEol
                |
              
             
            
           
          
         
        
       
      
     
    
   
  
 
 
 
 
 a ext_statement_AST class will be generated, containing the
 following:
 
ASTNode.getProduction(), which will be set by
 parse(ClassLoader, String, String)to one of the
 PROD_n constants, as above.
 
suffix-- since there will be a class generated for
 that non-terminal, in turn, and accessors (getters and setters).
 Depending on the actual reduction, not all such fields, obviously, will
 be set. In our example, thus, one of the fields will be
 private formal_list_opt_AST inst_formal_list_opt (and its
 accessors will be set_formal_list_opt_AST(ASTNode) and
 get_formal_list_opt_AST(). Another such field will be
 inst_as_opt_AST. It's easy to see that if an instance of
 ext_statement_AST is created as a result of first reduction (
 SUB tkName..., or, in other words, when
 getProduction() returns a String that's equal to
 PROD_1) the inst_as_opt_AST will not be set; while
 inst_formal_list_opt will be set in cases of both
 PROD_1 and PROD_2. Notice that:
- The _inst prefix not part of the accessor name.
 - The setter takes ASTNode, rather than that particular type (and downcasts inside). This is to make my life easier.
 
List terminals field (with a
 getTerminals() accessor) that will return the values of all
 terminals in the current reduction, in order. Thus, in or example, in
 case of PROD_2, this field will contain 6 elements:
 ReflectiveVisitorwill be
 generated. It will provide a visit method for every
 ASTNode subclass that was generated. Using our example above,
 one such method will be:
 
 
 public void visit(ext_statement_AST node) {
     // ext_statement ::= SUB tkName <formal_list_opt> tkEol
     // <statement_list> END SUB tkEol
     if (node.getProduction().equals(ext_statement_AST.PROD_1)) {
         String curStr = "";
 
         // TERMINAL: [SUB]
         curStr += (String) node.getTerminals().get(0);
         // TERMINAL: [tkName]
         curStr += (String) node.getTerminals().get(1);
         node.get_formal_list_opt_AST().accept(this);
 
         // TODO
         curStr = this.code;
         this.code = "";
 
         // TERMINAL: [tkEol]
         curStr += (String) node.getTerminals().get(2);
         node.get_statement_list_AST().accept(this);
 
         // TODO
         curStr = this.code;
         this.code = "";
 
         // TERMINAL: [END]
         curStr += (String) node.getTerminals().get(3);
 
         // TERMINAL: [SUB]
         curStr += (String) node.getTerminals().get(4);
 
         // TERMINAL: [tkEol]
         curStr += (String) node.getTerminals().get(5);
         return;
     }
 
     // ext_statement ::= DECLARE FUNCTION tkName LIB tkString
     // <formal_list_opt> <as_opt> tkEol
     if (node.getProduction().equals(ext_statement_AST.PROD_2)) {
         String curStr = "";
 
         // TERMINAL: [DECLARE]
         curStr += (String) node.getTerminals().get(0);
 
         // TERMINAL: [FUNCTION]
         curStr += (String) node.getTerminals().get(1);
 
         // TERMINAL: [tkName]
         curStr += (String) node.getTerminals().get(2);
 
         // TERMINAL: [LIB]
         curStr += (String) node.getTerminals().get(3);
 
         // TERMINAL: [tkString]
         curStr += (String) node.getTerminals().get(4);
 
         node.get_formal_list_opt_AST().accept(this);
 
         // TODO
         curStr = this.code;
         this.code = "";
         node.get_as_opt_AST().accept(this);
 
         // TODO
         curStr = this.code;
         this.code = "";
         // TERMINAL: [tkEol]
         curStr += (String) node.getTerminals().get(5);
         return;
     }
 
     // ext_statement ::=
     if (node.getProduction().equals(ext_statement_AST.PROD_3)) {
         String curStr = "";
         return;
     }
 }
 
 
 
 This visitor can then be modified. TODO
 
root - path where the 
 pkg
  containing generated classes is
            to be createdpkg - package into which to place generated classes; if it exists,
            its contents will be deleted prior to the generation.visitorPkg - package into which a subclass of ReflectiveVisitoris
            generated -- different from 
 pkg
  in that it's
            something to be modified/customized by a developer, rather
            than to be used as generated.visitorName - a name of the subclass of ReflectiveVisitorto be
            generated.
goldengine.java.ParserException - if an error occurs
java.io.IOExceptionpublic static final java.lang.String pkg2Dir(java.lang.String pkg)
public java.util.Collection getAllAsts()
public ASTNode parse(java.lang.ClassLoader loader,
                     java.lang.String pkg,
                     java.lang.String input)
              throws goldengine.java.ParserException
loader - ClassLoader to use to load classes implementing
            ASTNode that were generated by
            #generateClasses(String, String)(useful if not
            running in an IDE, etc.); if null, then
            Thread.getContextClassLoader()of the
            Thread.currentThread()is used.pkg - package where the classes implementing ASTNode that
            were generated by #generateClasses(String, String)
            reside.input - input to parse.
goldengine.java.ParserException - if there were any errors in parsingpublic java.util.Map getAst2Comments()
public static void main(java.lang.String[] argv)
argv - In the following order:
            public java.util.Map getTerminalMap()
private void processReduction(java.lang.ClassLoader myLoader,
                              java.lang.String pkg,
                              goldengine.java.Reduction reduction)
                       throws goldengine.java.ParserException
goldengine.java.ParserExceptionpublic ASTNode getStart()
  | 
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||