Changeset 1303 for proto


Ignore:
Timestamp:
Aug 8, 2011, 8:37:08 PM (8 years ago)
Author:
shermer
Message:

Refactoring: broke parseStatement.Step into subclasses for each type of step, part 1.

Location:
proto/pebble/trunk
Files:
5 added
5 edited

Legend:

Unmodified
Added
Removed
  • proto/pebble/trunk/inputs/xmlwf2.pbl

    r1287 r1303  
    387387                                                                       
    388388                # Comment processing
    389                 parse `(,hh>>~d*>,,r)?` {
     389                parse `(,hh>>~d*>,,r@)?` {
    390390                        h: [-]
    391391                        d: "--"
  • proto/pebble/trunk/src/parseStatement/ParseFormatDecoder.java

    r1287 r1303  
    44import java.util.List;
    55
     6import parseStatement.steps.*;
     7
    68import util.error.ErrLog;
    79
    810
    911public class ParseFormatDecoder {
    10         int markerNumber = 0;
    11         List<Step> parsed = new ArrayList<Step>();
     12        String format;
     13        int markerNumber;
    1214
    1315        public ParseFormatDecoder(String qformat) {
    14                 String format = qformat.substring(1, qformat.length()-1);
     16                format = qformat.substring(1, qformat.length()-1);
    1517                markerNumber = 0;
    16                 parsed = parseFormat(format);
    17 //              for(Step step: parsed) {
    18 //                      System.err.println(step.toString());
    19 //              }
    2018        }
    2119        public List<Step> getSteps() {
    22                 return parsed;
    23         }
    24        
    25        
    26         private Step newStep(List<Step> steps) {
    27                 Step currentStep = new Step();
    28                 steps.add(currentStep);
    29                 return currentStep;
    30         }
    31         // return this step if its content is empty, otherwise a new step.
    32         private Step contentEmptyStep(Step currentStep, List<Step> steps) {
    33                 if(currentStep.hasContent()) {
    34                         currentStep.validate();
    35                         return newStep(steps);
    36                 }
    37                 else {
    38                         return currentStep;
    39                 }
     20                return parseFormat(format);
    4021        }
    4122
    42         // in creation, a Step has two states: either it has content or it doesn't.
    43         // if it has content, then all it can get is plurality.
    44         //              If we don't see plurality,
    45         //              then finish this Step and create a new one.
    46         // if it doesn't have content, then it is empty or just has the prefix (~).
    47         //
     23       
     24        // normally, a char creates a step.
     25        // exceptions are the modifiers ~ +*?
    4826        private List<Step> parseFormat(String format) {
    4927                List<Step> result = new ArrayList<Step>();
    50                 Step currentStep = newStep(result);
    51 
     28                boolean seenComplement = false;
     29                Step current = null;
     30               
    5231                int index=0;   
    5332                while(index<format.length()) {
    5433                        char c = format.charAt(index);
    5534                        switch(c) {
    56                         case '(':
    57                                 currentStep = contentEmptyStep(currentStep, result);
    58                                 int closeIndex = findClosingParenthesisIndex(format, index);
    59                                 currentStep.setChildren(parseFormat(format.substring(index+1, closeIndex)));
    60                                 index = closeIndex+1;
    61                                 break;
    62 
    6335                        case '~':
    64                                 currentStep = contentEmptyStep(currentStep, result);
    65                                 if(currentStep.isComplemented()) {
    66                                         ErrLog.reportError("malformed parse format string: double-complementation not allowed.");
    67                                 }
    68                                 else {
    69                                         currentStep.setComplemented();
    70                                 }
     36                                issueComplementationErrors(seenComplement);
     37                                seenComplement = true;
    7138                                index++;
    72                                 break;
    73 
    74                         case ',':
    75                                 currentStep = contentEmptyStep(currentStep, result);
    76                                 currentStep.setMarker(markerNumber++);
    77                                 index++;
    78                                 break;
     39                                continue;       // don't do after-switch code.
    7940
    8041                        case '+':       
    8142                        case '*':
    8243                        case '?':
    83                                 if(!currentStep.hasContent()) {
    84                                         ErrLog.reportError("malformed parse format string: found [+*?] without referent.");
    85                                 }
    86                                 else if(currentStep.getPlurality() != Plurality.ONE) {
    87                                         ErrLog.reportError("malformed parse format string: found multiple [+*?] on same step.");
    88                                 }
    89                                 else {
    90                                         currentStep.setPlurality(c);
    91                                 }
     44                                current = issuePluralityErrors(seenComplement, current);
     45                                current.setPluralityForChar(c);
     46                                current.validate();
    9247                                index++;
     48                                continue;       // don't do after-switch code.
     49                               
     50                        case '(':
     51                                int closingIndex = findClosingParenthesisIndex(format, index);
     52                                List<Step> children = parseFormat(format.substring(index+1, closingIndex));
     53                                current = SubgroupStep.make(seenComplement, children);
     54                               
     55                                index = closingIndex;   // gets incremented after switch at bottom of loop.
     56                                break;
     57                               
     58                        case ',':
     59                                current = MarkerStep.make(seenComplement, markerNumber++);
    9360                                break;
    9461
    9562                        case '>':       
    96                                 currentStep = contentEmptyStep(currentStep, result);
    97                                 currentStep.setAnyChar(true);
    98                                 index++;
     63                                current = WildcardStep.make(seenComplement);
    9964                                break;
    100                                
     65       
    10166                        default:
    102                                 currentStep = contentEmptyStep(currentStep, result);
    103                                 currentStep.setVariable("" + c);
    104                                 index++;
     67                                current = VariableStep.make(seenComplement, "" + c);
    10568                                break;
    10669                        }
    10770
     71                        current.validate();
     72                        result.add(current);
     73                        seenComplement = false;
     74
     75                        index++;
    10876                }
    109                 if(!currentStep.hasContent()) {
    110                         if(currentStep.isComplemented()) {
    111                                 ErrLog.reportError("malformed parse format string: complement (~) after step content.");
    112                         }
    113                         // allow marker at end, but nothing else without content.
    114                         if(!currentStep.hasMarker()) {
    115                                 result.remove(currentStep);
    116                         }
    117                 }
    118 
    11977                return result;
    12078        }
    121 
     79        private void issueComplementationErrors(boolean seenComplement) {
     80                if(seenComplement) {
     81                        ErrLog.reportError("malformed parse format string: double-complementation not allowed.");
     82                }
     83        }
     84        /**
     85         * Issues any errors that arise from trying to add a plurality to
     86         * the current (abstract) Step.  Any errors due to a clash with the
     87         * particular type of Step are not issued.  Returns a valid step that
     88         * can have its plurality set.
     89         *   
     90         * @param seenComplement
     91         * @param lastStep
     92         * @return
     93         */
     94        private Step issuePluralityErrors(boolean seenComplement, Step lastStep) {
     95                if(lastStep == null ) {
     96                        ErrLog.reportError("malformed parse format string: found [+*?] without referent.");
     97                        return WildcardStep.make(false);        // as a placeholder.  Replace with NullStep if ever there is one.
     98                }
     99                else if (seenComplement) {
     100                        ErrLog.reportError("malformed parse format string: found complement before plurality.");
     101                }
     102                else if(lastStep.getPlurality() != lastStep.defaultPlurality()) {
     103                        ErrLog.reportError("malformed parse format string: found multiple [+*?] on same step.");
     104                }
     105                return lastStep;
     106        }
    122107        private int findClosingParenthesisIndex(String format, int index) {
    123108                int balance = 0;
     
    132117                }
    133118                ErrLog.reportError("malformed parse format string: unbalanced parentheses.");
    134                 return 0;
     119                return format.length();
    135120        }
    136 
    137121}
  • proto/pebble/trunk/src/parseStatement/Plurality.java

    r1287 r1303  
    44package parseStatement;
    55
    6 enum Plurality {
     6public enum Plurality {
    77        PLUS,
    88        STAR,
  • proto/pebble/trunk/src/parseStatement/SingleExpander.java

    r1287 r1303  
    9797        private void addParsingCode(List<Step> steps) {
    9898                for(Step step: steps) {
    99                         if(!step.hasContent()) {
    100                                 assert false;
    101                                 break;                                  // last step: probably an error now.
    102                         }
    10399                       
    104100                        // step may need subclasses...this is clearly a type switch.
     
    109105                                generateIsAnyCharCode(step);
    110106                        }
    111                         else if(step.hasChildren()) {
     107                        else if(step.isSubgroup()) {
    112108                                generateHasChildrenCode(step);
    113109                        }
     
    219215
    220216        private void generateErrorCheckCode(Step step) {
     217                if(step.isAnyChar()) {
     218                        return;
     219                }
    221220                AST errorChars = NotASTB.make(makeHasVariableBaseAST(step));
    222221                AST isError = AndASTB.make(var(cursor), errorChars);
     
    230229                        return placeholder();
    231230                }
    232                 if(!step.hasChildren()) {
     231                if(!step.isSubgroup()) {
    233232                        ErrLog.reportCompilerError("child content sought on non-parent step.");
    234233                        return placeholder();
     
    237236                List<Step> children = step.getChildren();
    238237                for(Step child: children) {
    239                         if(!child.hasContent()) {
    240                                 ErrLog.reportCompilerError("Found child step without content.");
    241                                 return placeholder();
    242                         }
    243                         else if(child.hasMarker()) {
     238                        if(child.hasMarker()) {
    244239                                continue;
    245240                        }
     
    248243                                return placeholder();
    249244                        }
    250                         else if(child.hasChildren()) {
     245                        else if(child.isSubgroup()) {
    251246                                ErrLog.reportError("Clauses may not nest.");
    252247                                return placeholder();
     
    265260               
    266261        private AST makeHasVariableBaseAST(Step step) {
    267                 String vname = namer.parseClassName(step.variable);
    268                 variablesUsed.add(step.variable);
     262                String vname = namer.parseClassName(step.getVariable());
     263                variablesUsed.add(step.getVariable());
    269264
    270265                AST result = VariableASTB.make(vname);
  • proto/pebble/trunk/src/parseStatement/Step.java

    r1287 r1303  
    1 /**
    2  *
    3  */
    41package parseStatement;
    52
    6 import java.util.ArrayList;
    73import java.util.List;
    84
     
    117import util.error.ErrLog;
    128
    13 class Step {
     9// base class for steps in the parsing algorithm
     10public abstract class Step {
    1411        static final int NO_MARKER = -1;
     12
    1513       
    1614        //      four types of main content:
     
    2624        //
    2725       
    28         String variable;
    29         private List<Step> children;
    30         private boolean isAnyChar;
    31         private int markerNumber;
    32        
    33         boolean isComplemented = false;
    34         Plurality plurality = Plurality.ONE;
     26        boolean isComplemented;
     27        Plurality plurality;
    3528       
    3629        public Step() {
    37                 variable = null;
    38                 children = new ArrayList<Step>();
    39                 isAnyChar = false;
    40                 markerNumber = Step.NO_MARKER;
     30                isComplemented = false;
     31                plurality = Plurality.ONE;
    4132        }
    4233        public boolean hasContent() {
    43                 return hasChildren() || hasVariable() || isAnyChar() || hasMarker();
     34                return isSubgroup();
    4435        }
    4536
    4637        // issue an error if there is a problem with the object
    47         public void validate() {
    48                 if(isComplemented() && !hasVariable()) {
    49                         ErrLog.reportError("malformed parse step: negation can only be applied to variables.");
    50                 }
    51                 if( (hasMarker() || isAnyChar()) && (plurality != Plurality.ONE)) {
    52                         ErrLog.reportError("malformed parse step: marker or wildcard may not have plurality.");
    53                 }
    54                 if( hasChildren() && (plurality != Plurality.OPTIONAL)) {
    55                         ErrLog.reportError("malformed parse step: subparse may only have optional plurality.");
    56                 }
    57                 if(hasVariable() && (plurality == Plurality.OPTIONAL)) {
    58                         ErrLog.reportError("malformed parse step: variable may not have optional plurality.");
    59                 }
    60         }
     38        abstract public void validate();
    6139       
    6240        /////////////////////////////////////////////////////////////
     
    6442        /////////////////////////////////////////////////////////////
    6543        public boolean hasMarker() {
    66                 return markerNumber != Step.NO_MARKER;
     44                return false;
    6745        }
    6846        public int getMarker() {
    69                 return markerNumber;
    70         }
    71         public void setMarker(int markerNumber) {
    72                 this.markerNumber = markerNumber;
     47                return NO_MARKER;
    7348        }
    7449
     
    7752        /////////////////////////////////////////////////////////////
    7853        public boolean isAnyChar() {
    79                 return isAnyChar;
     54                return false;
    8055        }
    81         public void setAnyChar(boolean anychar) {
    82                 isAnyChar = anychar;
    83         }
    84        
    8556
    8657        /////////////////////////////////////////////////////////////
    8758        // children
    8859        /////////////////////////////////////////////////////////////
    89         public boolean hasChildren() {
    90                 return !children.isEmpty();
    91         }
    92         public void addChild(Step step) {
    93                 children.add(step);
     60        public boolean isSubgroup() {
     61                return false;
    9462        }
    9563        public List<Step> getChildren() {
    96                 return children;
     64                return null;
    9765        }
    9866        public void setChildren(List<Step> steps) {
    99                 children = steps;
    100         }
    101         public Step getChild(int i) {
    102                 return children.get(i);
    10367        }
    10468       
     
    10872        /////////////////////////////////////////////////////////////
    10973        public boolean hasVariable() {
    110                 return variable != null;
    111         }
    112         public void setVariable(String symbol) {
    113                 variable = symbol;
     74                return false;
    11475        }
    11576        public String getVariable() {
    116                 return variable;
     77                System.err.println(this);
     78                return "getVariable called on non-variable step";
    11779        }
    11880       
     
    12587                return isComplemented;
    12688        }
    127         public void setComplemented() {
    128                 isComplemented = true;
     89        public void setComplemented(boolean value) {
     90                isComplemented = value;
    12991        }
    13092       
    131         public void setPlurality(char c) {
     93       
     94        public void setPluralityForChar(char c) {
    13295                if(c=='?')
    13396                        plurality = Plurality.OPTIONAL;
     
    145108                return plurality;
    146109        }
    147 
     110        public Plurality defaultPlurality() {
     111                return Plurality.ONE;
     112        }
    148113       
    149114        /////////////////////////////////////////////////////////////
    150115        // string representation
    151116        /////////////////////////////////////////////////////////////
     117        @Override
    152118        public String toString() {
    153119                PStringBuilder builder = new PStringBuilder();
    154120                toBuilder(builder);
    155121                return builder.toString();
     122        }       
     123        // toBuilder is overridden for subgroups
     124        public void toBuilder(PStringBuilder builder) {
     125                builder.appendLine(thisToString());
    156126        }
    157         public String simpleToString() {
    158                 String markerString = (markerNumber == Step.NO_MARKER) ? "" : "marker " + markerNumber;
    159                 String isAnyCharString = isAnyChar ? "wildcard" : "";
    160                 String hasChildrenString = hasChildren() ? "children" : "";
    161                 String hasVariableString = hasVariable() ? "variable " + variable : "";
    162                 String contentString = markerString + isAnyCharString + hasChildrenString + hasVariableString;
     127        final public String thisToString() {
     128                String contentString = contentString();
    163129                String complementString = isComplemented ? "~ " : "";
    164130                return "step(" + complementString + contentString + " : " + plurality + ")";
    165131        }
    166         public void toBuilder(PStringBuilder builder) {
    167                 builder.appendLine(simpleToString());
    168                 if(children!=null) {
    169                         builder.indent();
    170                         for(Step child: children) {
    171                                 child.toBuilder(builder);
    172                         }
    173                         builder.dedent();
    174                 }
    175         }
     132        protected abstract String contentString();
     133
     134       
     135
    176136
    177137
Note: See TracChangeset for help on using the changeset viewer.