Changeset 2622


Ignore:
Timestamp:
Nov 7, 2012, 7:21:11 PM (6 years ago)
Author:
ksherdy
Message:

Continued implementation of CPP unparser.

Location:
proto/pablo
Files:
7 edited
2 moved

Legend:

Unmodified
Added
Removed
  • proto/pablo/input/grammar/scatter/pablo.scatter

    r2621 r2622  
    7070
    7171grammar {
    72         program         -> ( declarations | functionDef ) *;
     72        program         -> (declarations | functionDef) *;
    7373
    7474        //
     
    8181        declarations                    -> (typeDecl | typeDef) TERMINATOR ;
    8282
    83         typeDecl                                ->  type declaratorList ?;
     83        typeDecl                                ->  type declaratorList?;
    8484               
    8585        typeDef                                 ->  TYPEDEF type identifier ;
    8686       
    87         declaratorList                  ->  identifier (COMMA identifier)? ;
     87        declaratorList                  ->  identifier (COMMA identifier)* ; // TODO - support or support via 'source' function definitions
    8888       
    8989   
     
    9191        // f u n c t i o n   d e f i n i t i o n s                                                             
    9292        //
    93         functionDef             -> FUNCTION type functionName LROUND parameterList RROUND blockStatement TERMINATOR?;                           
     93        functionDef             -> FUNCTION type functionName LROUND parameterList? RROUND blockStatement TERMINATOR?;                         
    9494                                                                               
    9595        returnType              #-> type ;      // Note: Strictly not required.
    9696       
    97         parameterList   -> (parameter (COMMA parameter)*)?;
     97        parameterList   -> parameter (COMMA parameter)*;
    9898                                                                                                               
    9999        functionName    #-> identifier ;
     
    122122        assignmentOperator                                      -> ASSIGN | AND_ASSIGN | OR_ASSIGN | XOR_ASSIGN ;                               
    123123                                       
    124         assignmentRest                          -> assignmentOperator^! expression ;                           
     124        assignmentRest                                          -> assignmentOperator^! expression ;                           
    125125                                       
    126126        ifStatement                                                     -> IF LROUND expression RROUND blockStatement ; // (ELSE blockStatement)?                       
     
    129129                       
    130130        returnStatement                                         -> RETURN (expression)? TERMINATOR;
    131        
    132         // localVarDeclList                                     -> localVarDecl (COMMA localVarDecl)* TERMINATOR;
    133                
     131                       
    134132        localVarDecl                                            -> VAR type variableName (assignmentOperator^! expression) ?;
    135133               
    136134        variableName                                            #-> identifier;
    137135
    138         blockStatement  -> LCURLY statement* RCURLY ;
     136        blockStatement                                          -> LCURLY statement* RCURLY ;
    139137       
    140138        //
     
    179177        //
    180178
    181         // p r i m i t i v e
     179        // p r i m i t i v e s
    182180        //
    183181        // s t r e a m
  • proto/pablo/src/compiler/PabloCompiler.java

    r2608 r2622  
    7777                System.out.print(syntaxTree);
    7878               
    79                 CodeGenerator cPPCodeGenerator = new CPPCodeGenerator(syntaxTree);
     79                Unparser cPPCodeGenerator = new CPPUnparser(syntaxTree);
    8080                String code = cPPCodeGenerator.getCode();
    8181                System.out.print(code);
  • proto/pablo/src/compiler/ast/Accessors.java

    r2621 r2622  
    2020                return 0 == node.nChildren();
    2121        }
     22
     23        ////////////////////////////////////////////////////////////////////////////
     24        // Type declarations
     25        ////////////////////////////////////////////////////////////////////////////                           
     26        public static boolean hasDeclaratorList(TypeDeclNode node) {
     27
     28                if (node.nChildren() > 1) {
     29                        ASTNode child = node.child(1);
     30                        assert child instanceof DeclaratorListNode;
     31                        return true;
     32                }
     33                return false;
     34        }
    2235       
    2336        ////////////////////////////////////////////////////////////////////////////
     
    133146       
    134147        public static boolean hasParameters(FunctionDefNode node) {
    135                 if (node.nChildren() > 2) {
    136                         ASTNode child = node.child(2);
    137                         assert child instanceof ParameterListNode;
    138                         if(child.nChildren() > 0) {
    139                                         return true;
    140                         }
     148                ASTNode child2 = node.child(2);
     149               
     150                if ((node.nChildren()) > 2 && (child2 instanceof ParameterListNode)) {
     151                        return true;
    141152                }
    142153                return false;
     
    215226        }       
    216227       
     228               
    217229        public static boolean hasStructBody(StructTypeNode node) {
    218230                if (node.nChildren() > 1) {
  • proto/pablo/src/compiler/codeGeneration/CodeStore.java

    r2621 r2622  
    22
    33import java.util.ArrayList;
     4import java.util.Iterator;
    45import java.util.List;
    56
     
    112113                addLine(betailed, last.relativeIndent);
    113114        }
     115       
     116        public static String makeDelimitedList(Iterator<CodeStore> iter, String delimeter) {
     117                StringBuilder resultVariable = new StringBuilder();
     118                while (iter.hasNext()) {
     119                        resultVariable.append(iter.next().getResultVariableName());
     120                        if (iter.hasNext()) {
     121                                resultVariable.append(delimeter);
     122                        }
     123                }
     124                return resultVariable.toString();
     125        }       
     126
    114127}
  • proto/pablo/src/compiler/codeGeneration/TemplateContentsGenerator.java

    r2608 r2622  
    1717        private ASTNode astTree;
    1818    private Template template;
    19     private CodeGenerator codeGenerator;
     19    private Unparser codeGenerator;
    2020//      private String outputDirectory;
    2121       
  • proto/pablo/src/compiler/visitors/CPPUnparser.java

    r2621 r2622  
    1313 */
    1414
    15 public class CPPCodeGenerator extends CodeGenerator {
     15public class CPPUnparser extends Unparser {
    1616
    1717//      private Labeller labeller = new Labeller();
    1818
    19         private boolean inTypeDecl = false;
    20                        
    21         public CPPCodeGenerator(ASTNode astTree) {
     19        public CPPUnparser(ASTNode astTree) {
    2220                this.astTree = astTree;
    2321        }
     
    3836
    3937        public void visitEnter(DeclarationsNode node) {
    40                 inTypeDecl = true;
    41         }
    42        
    43         public CodeStore visitLeave(DeclarationsNode node, List<CodeStore> childResults) {
    44                 inTypeDecl = false;
    45                
    46                 return concatenatedChildrenCode(new CodeStore(), childResults, false);         
     38
     39        }
     40       
     41        public CodeStore visitLeave(DeclarationsNode node, List<CodeStore> childResults) {     
     42                return concatenatedChildrenCode(new CodeStore(), childResults, true);           
    4743        }       
    4844
    4945        public CodeStore visitLeave(TypeDeclNode node, List<CodeStore> childResults) {
    5046                CodeStore code = new CodeStore();
    51                 code.addFormattedLine("%s;", childResults.get(0).getResultVariableName());
     47                String type = childResults.get(0).getResultVariableName();
     48                String declaratorList;
     49                if (Accessors.hasDeclaratorList(node)) {
     50                        declaratorList = childResults.get(1).getResultVariableName();
     51                        code.addFormattedLine("%s %s;", type, declaratorList);
     52                       
     53                } else {
     54                        code.addFormattedLine("%s;", type);
     55                }
    5256                return code;           
    5357        }               
     58
     59        public CodeStore visitLeave(DeclaratorListNode node, List<CodeStore> childResults) {
     60                CodeStore code = new CodeStore();
     61                Iterator<CodeStore> iter = childResults.iterator();
     62                code.setResultVariableName(CodeStore.makeDelimitedList(iter, ","));
     63                return code;           
     64        }               
    5465       
    5566        ////////////////////////////////////////////////////////////////////////////
     
    6172                CodeStore returnType = childResults.get(0);
    6273                CodeStore functionName = childResults.get(1);
     74                CodeStore blockStatement; 
    6375               
    6476                String parameters = new String();
    6577                if(Accessors.hasParameters(node)) {
    6678                        parameters = childResults.get(2).getResultVariableName();
     79                        blockStatement = childResults.get(3);
     80                } else {
     81                        blockStatement = childResults.get(2);
    6782                }
    6883                               
     
    7287                                parameters);   
    7388               
    74                 CodeStore blockStatement = childResults.get(3);
    7589                code.addLine("{");
    7690                code.addAll(blockStatement, 1);
     
    7993        }
    8094
    81         public CodeStore visitLeave(ParameterListNode node, List<CodeStore> childResults) { // a variable, not a line of code
    82                 CodeStore code = new CodeStore();
    83                
    84                 StringBuilder parameterList = new StringBuilder();
    85                
     95        public CodeStore visitLeave(ParameterListNode node, List<CodeStore> childResults) {
     96                CodeStore code = new CodeStore();               
    8697                Iterator<CodeStore> iter = childResults.iterator();
    87                
    88                 while (iter.hasNext()) {
    89                         parameterList.append(iter.next().getResultVariableName());
    90                         if (iter.hasNext()) {
    91                                 parameterList.append(", ");
    92                         }
    93                 }
    94                
    95                 code.setResultVariableName(parameterList.toString());
    96                
     98                code.setResultVariableName(CodeStore.makeDelimitedList(iter, ","));             
    9799                return code;
    98100        }
    99101       
    100102        // Parameter
    101         public CodeStore visitLeave(ParameterNode node, List<CodeStore> childResults) { // a variable, not a line of code
     103        public CodeStore visitLeave(ParameterNode node, List<CodeStore> childResults) {
    102104                CodeStore code = new CodeStore();
    103105               
     
    141143        }       
    142144       
    143         public CodeStore visitLeave(FunctionInvocationArgumentListNode node, List<CodeStore> childResults) { // a variable, not a line of code
    144                 CodeStore code = new CodeStore();
    145                
    146                 StringBuilder resultVariable = new StringBuilder();
    147                
     145        public CodeStore visitLeave(FunctionInvocationArgumentListNode node, List<CodeStore> childResults) {
     146                CodeStore code = new CodeStore();
    148147                Iterator<CodeStore> iter = childResults.iterator();
    149                
    150                 while (iter.hasNext()) {
    151                         resultVariable.append(iter.next().getResultVariableName());
    152                         if (iter.hasNext()) {
    153                                 resultVariable.append(", ");
    154                         }
    155                 }
    156                
    157                 code.setResultVariableName(resultVariable.toString());
    158                
    159                 return code;
    160         }       
     148                code.setResultVariableName(CodeStore.makeDelimitedList(iter, ","));
     149                return code;
     150        }
    161151               
    162152        // if statement
     
    191181                return code;
    192182        }
    193                        
    194         // variable declarations list
    195         //public CodeStore visitLeave(LocalVarDeclListNode node, List<CodeStore> childResults) {
    196                 // TODO - implement
    197         //      return concatenatedChildrenCode(new CodeStore(), childResults, true);
    198         //}     
    199 
     183                               
    200184        // variable declaration
    201185        public CodeStore visitLeave(LocalVarDeclNode node, List<CodeStore> childResults) {
     
    250234                StringBuffer resultVariable = new StringBuffer();
    251235
     236       
     237               
     238               
     239               
     240               
     241               
     242               
    252243                if(!Accessors.isTerminal(Accessors.leftOperand(node))) {
    253244                        lhsCode = bracketExpressionCode(lhsCode);
     
    298289       
    299290        ////////////////////////////////////////////////////////////////////////////
    300         // Operator
    301         ////////////////////////////////////////////////////////////////////////////
    302        
    303        
    304         ////////////////////////////////////////////////////////////////////////////
    305291        // StringConstant
    306292        ////////////////////////////////////////////////////////////////////////////
     
    359345        public CodeStore visitLeave(StructTypeBodyNode node, List<CodeStore> childResults) {
    360346                CodeStore code = new CodeStore();
    361                 StringBuffer resultVariable = new StringBuffer();
    362                
    363347                for (CodeStore child: childResults.subList(0, 1)) {
    364348                        code.addAll(child,1);
    365349                }
    366                
    367350                for (CodeStore child: childResults.subList(1, childResults.size())) {
    368351                        code.addAll(child, 0);         
    369                 }
    370                
    371                
     352                }       
    372353                return code;
    373354        }
     
    388369       
    389370        // Stream
    390         public CodeStore visitLeave(StreamTypeNode node, List<CodeStore> childResults) { // a variable, not a line of code
     371        public CodeStore visitLeave(StreamTypeNode node, List<CodeStore> childResults) {
    391372                CodeStore code = new CodeStore();
    392373                code.setResultVariableName(Accessors.streamTypeName(node));
     
    402383       
    403384        // Field Width
    404         public CodeStore visitLeave(FieldWidthNode node, List<CodeStore> childResults) { // a variable, not a line of code
     385        public CodeStore visitLeave(FieldWidthNode node, List<CodeStore> childResults) {
    405386                CodeStore code = new CodeStore();
    406387                code.setResultVariableName(Accessors.fieldWidthValue(node));           
     
    409390
    410391        // Void
    411         public CodeStore visitLeave(VoidNode node, List<CodeStore> childResults) { // a variable, not a line of code
     392        public CodeStore visitLeave(VoidNode node, List<CodeStore> childResults) {
    412393                CodeStore code = new CodeStore();
    413394                code.setResultVariableName(Accessors.voidValue(node));
     
    415396        }               
    416397       
     398        // Compound Identifiers
     399        public CodeStore visitLeave(CompoundVariableNode node, List<CodeStore> childResults) {
     400                CodeStore code = new CodeStore();
     401                Iterator<CodeStore> iter = childResults.iterator();
     402                code.setResultVariableName(CodeStore.makeDelimitedList(iter, "."));
     403                return code;
     404        }
     405       
    417406        // Identifiers
    418         public CodeStore visitLeave(IdentifierNode node, List<CodeStore> childResults) { // a variable, not a line of code
     407        public CodeStore visitLeave(IdentifierNode node, List<CodeStore> childResults) {
    419408                CodeStore code = new CodeStore();
    420409                code.setResultVariableName(Accessors.identifierLexeme(node));
     
    423412       
    424413}
    425 
    426 /*
    427 public CodeStore visitLeave(GrammarSectionNode node, List<CodeStore> childResults) {
    428         CodeStore code = new CodeStore();                       
    429 
    430         Nonterminal startSymbol = node.getStartSymbol();
    431         code.addLine("public ASTNode parse() {");
    432         code.indentedLine("readToken();");
    433         code.addLine("return " + startSymbol.getParseMethodName() + "();");
    434         code.dedentedLine("}");
    435        
    436         return concatenatedChildrenCode(code, childResults, true);
    437 }
    438 
    439 public void visitEnter(TokenRecognizerSectionNode node) {
    440         inRecognizers = true;
    441 }
    442 
    443 public CodeStore visitLeave(TokenRecognizerSectionNode node, List<CodeStore> childResults) {
    444         inRecognizers = false;
    445         return concatenatedChildrenCode(childResults);
    446 }
    447 
    448 public void visitEnter(ActionNode node) {
    449         inAction = true;
    450 }
    451 
    452 public CodeStore visitLeave(ActionNode node, List<CodeStore> childResults) {
    453         inAction = false;
    454         return concatenatedChildrenCode(childResults);
    455 }
    456 
    457 
    458 public CodeStore visitLeave(NumberNode node, List<CodeStore> childResults) {
    459         CodeStore code =  new CodeStore();
    460         String variableName = labeller.newLabel();
    461 
    462         int value = ((NumberNode)node).getValue();
    463         code.addFormattedLine("int %s = %d;", variableName, value);
    464        
    465         code.setResultVariableName(variableName);
    466         return code;
    467 }
    468 
    469 public CodeStore visitLeave(BooleanConstantNode node, List<CodeStore> childResults) {
    470         CodeStore code =  new CodeStore();
    471         String variableName = labeller.newLabel();
    472 
    473         Boolean value = ((BooleanConstantNode)node).getValue();
    474         code.addFormattedLine("boolean %s = %s;", variableName, value.toString());
    475        
    476         code.setResultVariableName(variableName);
    477         return code;
    478 }
    479 public CodeStore visitLeave(BinaryOperatorNode node, List<CodeStore> childResults) {
    480         CodeStore code =  new CodeStore();
    481         String variableName = labeller.newLabel();
    482        
    483         CodeStore leftCode   = (CodeStore)childResults.get(0);
    484         CodeStore rightCode  = (CodeStore)childResults.get(1);
    485         String leftVariable  = leftCode.getResultVariableName();
    486         String rightVariable = rightCode.getResultVariableName();
    487 
    488         String resultType = "int";      //TODO: fix for other operations, etc.
    489         String operator = node.getToken().getLexeme();
    490        
    491         code.addAll(leftCode, 0);
    492         code.addAll(rightCode, 0);
    493         code.addFormattedLine("%s %s = %s %s %s;", resultType, variableName, leftVariable, operator, rightVariable);
    494        
    495         code.setResultVariableName(variableName);
    496         return code;
    497 }
    498 public CodeStore visitLeave(AssignmentNode node, List<CodeStore> childResults) {
    499         CodeStore code =  new CodeStore();
    500        
    501         CodeStore leftCode   = (CodeStore)childResults.get(0);  // this code is just the receiver
    502         CodeStore rightCode  = (CodeStore)childResults.get(1);
    503         String receiver      = leftCode.getResultVariableName();
    504         String value         = rightCode.getResultVariableName();
    505 
    506         code.addLine("{");
    507         code.addAll(leftCode, 1);
    508         code.addAll(rightCode, 0);
    509        
    510         AttributeNode lhs = (AttributeNode)node.child(0);
    511         String attributeName = lhs.attributeName();
    512         String setter = callSetter(receiver, attributeName, value);
    513         code.addFormattedLine("%s;", setter);
    514 
    515         code.dedentedLine("}");
    516        
    517         // no variable for value
    518         return code;
    519 }
    520 // produces code just for the attributeReference receiver; parent must handle getter/setter.
    521 public CodeStore visitLeave(AttributeNode node, List<CodeStore> childResults) {
    522         assert node.nChildren() == 2;
    523 
    524         CodeStore code =  new CodeStore();
    525         String variableName = labeller.newLabel();
    526        
    527         CodeStore receiverCode = (CodeStore) childResults.get(0);
    528         String receiver = receiverCode.getResultVariableName();
    529        
    530         code.addAll(receiverCode, 0);
    531        
    532         String attributeName = node.attributeName();
    533         String attributeType = attributeTypeFor(node);
    534        
    535         if(node.isTokenReference()) {
    536                 String castReceiver = labeller.newLabel();
    537                 String castType = "IntConstantToken";
    538                 code.addFormattedLine("%s %s = (%s)%s;", castType, castReceiver, castType, receiver);
    539                 receiver = castReceiver;
    540         }
    541         else {
    542                 String castReceiver = labeller.newLabel();
    543                 String castType = declaringNodeTypeFor(attributeName);
    544                 code.addFormattedLine("%s %s = (%s)%s;", castType, castReceiver, castType, receiver);
    545                 receiver = castReceiver;
    546         }
    547        
    548         if(node.isAssignmentLHS()) {
    549                 // let parent AssignmentNode call setter.
    550                 code.setResultVariableName(receiver);
    551         }
    552         else {
    553                 // call getter
    554                 String getter = callGetter(receiver, attributeName);
    555                 code.addFormattedLine("%s %s = %s;", attributeType, variableName, getter);
    556                 code.setResultVariableName(variableName);
    557         }
    558        
    559         return code;
    560 }
    561 private String attributeTypeFor(AttributeNode node) {
    562         if(node.isTokenReference()) {
    563                 return "int";           // hardwired for proof-of-concept
    564         }
    565         else {
    566                 AttributeRegistry attributeRegistry = symbolTable.attributeRegistry();
    567                 return attributeRegistry.getType(node.attributeName());
    568         }
    569 }
    570 @SuppressWarnings("unused")
    571 private boolean hasDeclaringNodeType(String attributeName) {
    572         AttributeRegistry attributeRegistry = symbolTable.attributeRegistry();
    573         return attributeRegistry.containsKey(attributeName);
    574 }
    575 private String declaringNodeTypeFor(String attributeName) {
    576         AttributeRegistry attributeRegistry = symbolTable.attributeRegistry();
    577         NodeClass definingNodeClass = attributeRegistry.get(attributeName);
    578         return definingNodeClass.getName();
    579 }
    580 
    581 public CodeStore visitLeave(SymbolReferenceNode node, List<CodeStore> childResults) {
    582         CodeStore code =  new CodeStore();
    583         String variableName = labeller.newLabel();
    584 
    585         if(node.isTokenReference()) {
    586                 variableName = "previouslyRead";
    587         }
    588         else {
    589                 String object = node.objectFor("result", "allChildren");
    590                 code.addFormattedLine("ASTNode %s = %s;", variableName, object);
    591         }
    592        
    593         code.setResultVariableName(variableName);
    594         return code;
    595 }
    596 
    597 
    598 private String callGetter(String object, String attributeName) {
    599         String methodName = "get" + NodeClassRegistry.capitalizeFirst(attributeName);
    600         return object + "." + methodName + "()";
    601 }
    602 private String callSetter(String object, String attributeName, String value) {
    603         String methodName = "set" + NodeClassRegistry.capitalizeFirst(attributeName);
    604         return object + "." + methodName + "( " + value + " )";
    605 }
    606 
    607 public CodeStore visitLeave(AlternationNode node, List<CodeStore> childResults) {
    608         CodeStore code = new CodeStore();
    609 
    610         for(int i=0; i<node.nChildren(); i++) {
    611                 ASTNode child = node.child(i);
    612                 CodeStore childCode = (CodeStore) childResults.get(i);
    613                 String condition = startCondition(child);
    614                
    615                 String statement = (i==0) ? "if" : "else if";
    616                 code.addLine(statement + "( " + condition + " ) {");
    617                 code.addAll(childCode, 1);
    618                 code.addLine("}", -1);
    619         }
    620         return code;
    621 }
    622 
    623 public CodeStore visitLeave(ConcatenationNode node, List<CodeStore> childResults) {
    624         return concatenatedChildrenCode(childResults);
    625 }
    626 
    627 public CodeStore visitLeave(LextantNode node, List<CodeStore> childResults) {
    628         CodeStore code = new CodeStore();
    629        
    630         if(node.getToken().isLextant(Lextant.LEFTASSOC)) {
    631                 code.addLine("result = rotateLeftIfPossible(result);");
    632         }
    633         else if (node.getToken().isLextant(Lextant.PROMOTE)) {
    634                 code.addLine("result = promoteLastChild(result);");
    635                 code.addLine("allowCompression = false;");
    636         }
    637        
    638         return code;
    639 }
    640 public CodeStore visitLeave(EpsilonNode node, List<CodeStore> childResults) {
    641         CodeStore code = new CodeStore();
    642         code.addLine("// epsilon");
    643         return code;
    644 }
    645 
    646 public CodeStore visitLeave(RepetitionNode node, List<CodeStore> childResults) {
    647         CodeStore code = new CodeStore();
    648        
    649         assert node.nChildren() == 1;
    650         ASTNode child = node.child(0);
    651         CodeStore childCode = (CodeStore) childResults.get(0);
    652        
    653         switch(node.getCardinality()) {
    654         case ONE:
    655                 code.addAll(childCode, 0);
    656                 break;
    657         case ONE_OR_MORE:
    658                 code.addLine("do {");
    659                 code.addAll(childCode, 1);
    660                 code.dedentedLine("} while( " + startCondition(child) +" );");
    661                 break;
    662         case ZERO_OR_MORE:
    663                 code.addLine( "while( " + startCondition(child) +" ) {");
    664                 code.addAll(childCode, 1);
    665                 code.dedentedLine("}");
    666                 break;
    667         case ZERO_OR_ONE:
    668                 code.addLine("if( " + startCondition(child) +" ) {");
    669                 code.addAll(childCode, 1);
    670                 code.dedentedLine("}");
    671                 break;
    672         }
    673         return code;
    674 }
    675 
    676 public CodeStore visitLeave(ProductionNode node, List<CodeStore> childResults) {
    677         CodeStore code = new CodeStore();
    678         CodeStore bodyCode = (CodeStore) childResults.get(1);
    679        
    680         Nonterminal head = node.head();
    681        
    682         code.addLine("public ASTNode " + head.getParseMethodName() + "() {");
    683         addGuard(code, head);
    684         code.indentedLine("boolean allowCompression = true;");
    685         code.addLine("ASTNode result = new " + head.getNodeClass().getName() + "(nowReading);");
    686         code.addLine("result.setProductionTag(" + head.ordinal() + ");");
    687         code.addLine("RevList<ASTNode> allChildren = new ReverseAccessibleArrayList<ASTNode>();");
    688         code.addAll(bodyCode, 0);
    689         addReturnLine(code, head);
    690         code.dedentedLine("}");
    691         return code;
    692 }
    693 
    694 private void addReturnLine(CodeStore code, Nonterminal head) {
    695         code.addLine("if(allowCompression) {");
    696         if(head.compressible()) {
    697                 code.indentedLine("return compressIfPossible(result);");
    698         }
    699         else{
    700                 code.indentedLine("return result;");
    701         }
    702         code.dedentedLine("}");
    703         code.addLine("return result;");
    704 }
    705 // needed because scala seems to erase the parameter type on Terminal's
    706 // implementation of Comparable<Terminal>
    707 class TerminalComparator implements Comparator<Terminal> {
    708         @Override
    709         public int compare(Terminal o1, Terminal o2) {
    710                 return o1.compareTo(o2);
    711         }
    712 }
    713 
    714 private void addGuard(CodeStore code, Nonterminal head) {
    715         if(head.isNullable()) {
    716                 return;
    717         }
    718         Set<Terminal> starters = head.getTerminalStarters();
    719         List<Terminal> sortedStarters = new ArrayList<Terminal>(starters);
    720         Collections.sort(sortedStarters, new TerminalComparator());
    721         String condition = Terminal.tokenSetCondition(starters, "nowReading");
    722        
    723         code.indentedLine("if( !(" + condition + ") ) {");
    724         code.indentedLine("return syntaxErrorNode(\"" + head + " " + sortedStarters + "\");");
    725         code.dedentedLine("}");
    726         code.dedentedLine("");
    727 }
    728 
    729 private String startCondition(ASTNode branch) {
    730         Set<Symbol> starters = XStarters.startingSymbols(branch);
    731         Set<Terminal> terminals = terminalsOf(starters);
    732        
    733         if(terminals.isEmpty()) {
    734                 return "true";
    735         }
    736        
    737         return terminalTest(terminals);
    738 }
    739 
    740 //////////////////////////////////////////////////////////////////////////////////////
    741 // ContextableSymbol
    742 public void visitEnter(ContextableSymbolNode node) {
    743         node.skipChildren();
    744 }
    745 public CodeStore visitLeave(ContextableSymbolNode node, List<CodeStore> childResults) {
    746         CodeStore code = new CodeStore();
    747         addContextPushOrPop(code, node);       
    748         code.addAll(node.child(0).accept(this), 0);
    749        
    750         return code;
    751 }
    752 
    753 private void addContextPushOrPop(CodeStore code, ContextableSymbolNode node) {
    754         if(node.nChildren()==2) {
    755                 IdentifierNode contextName = (IdentifierNode)node.child(1);
    756                 String newContextName = contextName.getIdentifier();
    757                 code.addLine("lexController.pushTo(\"" + newContextName + "\");");
    758         }
    759         else {
    760                 assert node.nChildren() == 1;
    761                 code.addLine("lexController.pop();");
    762         }
    763 }
    764 //////////////////////////////////////////////////////////////////////////////////////
    765 // identifier visit is last because it is decomposed into several submethods.
    766 //
    767 public CodeStore visitLeave(IdentifierNode node, List<CodeStore> childResults) {
    768         if(inAction || inRecognizers) {
    769                 return null;
    770         }
    771         CodeStore code = new CodeStore();
    772         Symbol symbol = node.getSymbol();
    773        
    774         if(symbol.isTerminal()) {
    775                 visitTerminalIdentifier(code, node, (Terminal)symbol);
    776         }
    777         else {
    778                 visitNonterminalIdentifier(node, code, (Nonterminal)symbol);
    779         }
    780         return code;
    781 }
    782 
    783 private void visitTerminalIdentifier(CodeStore code, IdentifierNode node, Terminal terminal) {
    784         if(terminal.isClassType()) {
    785                 addClassTerminalGuard(code, terminal);  // compensates for no "expect" taking classes.
    786                 possiblyRaiseTerminalToken(node, code);
    787                 possiblySwitchContexts(node, code);
    788                 code.addLine("readToken();");
    789         }
    790         else {
    791                 possiblyRaiseTerminalToken(node, code);
    792                 possiblySwitchContexts(node, code);
    793                 code.addLine("expect(" + terminal.lextantName() + ");");
    794         }
    795 }
    796 
    797 private void addClassTerminalGuard(CodeStore code, Terminal terminal) {
    798         String test = terminalTest(terminal);
    799         code.addLine(     "if( !" + test + " ) {");
    800         code.indentedLine("return syntaxErrorNode(" + quoted(terminal.getLexeme()) + ");");
    801         code.dedentedLine("}");
    802 }
    803 private void possiblyRaiseTerminalToken(IdentifierNode node, CodeStore code) {
    804         if(node.raiseToken()) {
    805                 code.addLine("result.setToken(nowReading);");
    806         }
    807         if(!node.allowParentCompression()) {
    808                 code.addLine("allowCompression = false;");
    809         }
    810 }
    811 private void possiblySwitchContexts(IdentifierNode node, CodeStore code) {
    812         if(node.isContextChange()) {
    813                 if(node.newContext() == "") {
    814                         code.addLine("lexController.pop();");
    815                 }
    816                 else {
    817                         code.addLine("lexController.pushTo(\"" + node.newContext() +"\");");
    818                 }
    819         }
    820 }
    821 
    822 private void visitNonterminalIdentifier(IdentifierNode node,
    823                 CodeStore code, Nonterminal nonterminal) {
    824         code.addLine("{");
    825         code.indentedLine("ASTNode child = " + nonterminal.getParseMethodName() + "();");
    826         if(node.getOmit()) {
    827                 code.addLine("// node omitted - no result.appendChild(child);");
    828         }
    829         else {
    830                 code.addLine("result.appendChild(child);");
    831         }
    832         code.addLine("allChildren.add(child);");
    833         if(node.raiseToken()) {
    834                 code.addLine("result.setToken( child.getToken() );");
    835         }
    836         if(!node.allowParentCompression()) {
    837                 code.addLine("allowCompression = false;");
    838         }
    839         code.dedentedLine("}");
    840 }
    841 /////////////////////////////////////////////////////////////////////////////
    842 // utilities
    843 
    844 private Set<Terminal> terminalsOf(Set<Symbol> starters) {
    845         Set<Terminal> result = new HashSet<Terminal>();
    846         for(Symbol symbol: starters) {
    847                 if(symbol.isTerminal()) {
    848                         result.add((Terminal)symbol);
    849                 }
    850         }
    851         return result;
    852 }
    853 private String quoted(String string) {
    854         return "\"" + string + "\"";
    855 }
    856 
    857 private String terminalTest(Symbol symbol) {
    858         Terminal terminal = (Terminal) symbol;
    859         return terminal.tokenCondition("nowReading");
    860 }
    861 private String terminalTest(Set<Terminal> terminals) {
    862         return Terminal.tokenSetCondition(terminals, "nowReading");
    863 }
    864 
    865 */             
  • proto/pablo/src/compiler/visitors/ReadMe.txt

    r2621 r2622  
    1 CPP code not generated.
     1TODO
     2
     3CPPUnparser
    24
    351. Negative numbers.
    4 2. Variable initialization lists.
  • proto/pablo/src/compiler/visitors/Unparser.java

    r2607 r2622  
    66import java.util.List;
    77
    8 public abstract class CodeGenerator extends ASTVisitor.Default<CodeStore> {
     8public abstract class Unparser extends ASTVisitor.Default<CodeStore> {
    99               
    1010        protected ASTNode astTree;
  • proto/pablo/src/parser/Parser.java

    r2621 r2622  
    167167                        allChildren.add(child);
    168168                }
    169                 if( nowReading.isLextant(Lextant.COMMA) ) {
     169                while( nowReading.isLextant(Lextant.COMMA) ) {
    170170                        expect(Lextant.COMMA);
    171171                        {
     
    202202                }
    203203                expect(Lextant.LROUND);
    204                 {
    205                         ASTNode child = parseParameterList();
    206                         result.appendChild(child);
    207                         allChildren.add(child);
     204                if( nowReading.isLextant(Lextant.STREAM, Lextant.STRUCT, Lextant.VOID) || (nowReading.isLexicalType(LexicalType.IDENTIFIER)) ) {
     205                        {
     206                                ASTNode child = parseParameterList();
     207                                result.appendChild(child);
     208                                allChildren.add(child);
     209                        }
    208210                }
    209211                expect(Lextant.RROUND);
     
    243245         
    244246        public ASTNode parseParameterList() {
     247                if( !(nowReading.isLextant(Lextant.STREAM, Lextant.STRUCT, Lextant.VOID) || (nowReading.isLexicalType(LexicalType.IDENTIFIER))) ) {
     248                        return syntaxErrorNode("parameterList² [IDENTIFIER¹, STREAM¹, STRUCT¹, VOID¹]");
     249                }
     250       
    245251                boolean allowCompression = true;
    246252                ASTNode result = new ParameterListNode(nowReading);
    247253                result.setProductionTag(8);
    248254                RevList<ASTNode> allChildren = new ReverseAccessibleArrayList<ASTNode>();
    249                 if( nowReading.isLextant(Lextant.STREAM, Lextant.STRUCT, Lextant.VOID) || (nowReading.isLexicalType(LexicalType.IDENTIFIER)) ) {
     255                {
     256                        ASTNode child = parseParameter();
     257                        result.appendChild(child);
     258                        allChildren.add(child);
     259                }
     260                while( nowReading.isLextant(Lextant.COMMA) ) {
     261                        expect(Lextant.COMMA);
    250262                        {
    251263                                ASTNode child = parseParameter();
    252264                                result.appendChild(child);
    253265                                allChildren.add(child);
    254                         }
    255                         while( nowReading.isLextant(Lextant.COMMA) ) {
    256                                 expect(Lextant.COMMA);
    257                                 {
    258                                         ASTNode child = parseParameter();
    259                                         result.appendChild(child);
    260                                         allChildren.add(child);
    261                                 }
    262266                        }
    263267                }
Note: See TracChangeset for help on using the changeset viewer.