Changeset 30

Show
Ignore:
Timestamp:
12/31/06 11:53:18 (2 years ago)
Author:
chris
Message:

- Change to chart parser, initial implementation works with standard rules, but not permutable or searching rules

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lex/trunk

    • Property svn:ignore set to

      work
  • lex/trunk/src/com/qwirx/lex/parser/Edge.java

    r26 r30  
    2929    Edge getBoundCopy(); 
    3030    Edge getUnboundCopy(); 
     31     
     32    boolean isAt(int pos); 
    3133} 
  • lex/trunk/src/com/qwirx/lex/parser/EdgeBase.java

    r26 r30  
    7171     * @param b The second Instance (actual) 
    7272     */ 
     73    /* 
    7374    public boolean equals(Object object) 
    7475    { 
     
    142143        return true; 
    143144    } 
     145    */ 
    144146} 
  • lex/trunk/src/com/qwirx/lex/parser/Parser.java

    r26 r30  
    99import java.sql.ResultSet; 
    1010import java.sql.SQLException; 
     11import java.util.ArrayList; 
    1112import java.util.Iterator; 
    1213import java.util.List; 
    13 import java.util.Stack; 
    1414import java.util.Vector; 
    1515 
    1616import com.qwirx.lex.DatabaseException; 
    17 import com.qwirx.lex.parser.Rule.Match; 
    1817import com.qwirx.lex.sql.SqlDatabase; 
    1918 
     
    2423 * Window - Preferences - Java - Code Style - Code Templates 
    2524 */ 
    26 public class Parser { 
     25public class Parser  
     26
    2727        private Rule [] rules; 
    2828         
    29         public Parser(SqlDatabase db) throws DatabaseException, SQLException { 
     29        public Parser(SqlDatabase db) throws DatabaseException, SQLException  
     30    { 
    3031                Vector ruleV = new Vector(); 
    3132                 
     
    5758        } 
    5859         
    59         public Edge[][] parse(String input)  
     60        public Chart parse(String input)  
    6061    { 
    6162                String[] words = input.split(" "); 
    62                  
    63                 Vector stacks = new Vector(); 
    64                 stacks.add(new Stack()); 
     63        Chart chart = new Chart(words.length); 
    6564                 
    6665                for (int i = 0; i < words.length; i++)  
    6766        { 
    68             for (int s = 0; s < stacks.size(); s++)  
     67            chart.add(new WordEdge(words[i], i)); 
     68             
     69                        for (int r = 0; r < rules.length; r++)  
    6970            { 
    70                 Stack stack = (Stack)( stacks.get(s) ); 
    71                 stack.push(new WordEdge(words[i])); 
    72             } 
     71                                /* 
     72                if (r == 4 && s == 5) 
     73                { 
     74                    System.out.println("boo"); 
     75                } 
     76                                */ 
    7377 
    74                         for (int s = 0; s < stacks.size(); s++)  
    75             { 
    76                                 Stack oldStack = (Stack)( stacks.get(s) ); 
    77                          
    78                                 for (int r = 0; r < rules.length; r++)  
    79                 { 
    80                                         /* 
    81                     if (r == 4 && s == 5) 
    82                     { 
    83                         System.out.println("boo"); 
    84                     } 
    85                                         */ 
    86  
    87                     Rule rule = rules[r]; 
    88                     List matches = rule.applyTo(oldStack); 
    89                      
    90                     for (Iterator m = matches.iterator(); m.hasNext(); ) 
    91                     { 
    92                         Match match = (Match)( m.next() ); 
    93                         // System.out.println(stacks.size() + ": " + match.stack); 
    94                         stacks.add(match.stack); 
    95                     } 
    96                                 } 
     78                Rule rule = rules[r]; 
     79                List newEdges = rule.applyTo(chart, i); 
     80                chart.add(newEdges); 
    9781                        } 
    9882                } 
    9983 
    10084                System.out.println("Parse finished."); 
    101                 Edge[][] results = new Edge[stacks.size()][]; 
    102  
    103                 for (int i = 0; i < stacks.size(); i++)  
    104         { 
    105                         Stack stack = (Stack)( stacks.get(i) ); 
    106                         // System.out.println("Stack "+(i+1)+" contains:"); 
    107  
    108                         Edge[] thisResult = new Edge[stack.size()]; 
    109  
    110                         for (int j = 0; j < stack.size(); j++)  
    111             { 
    112                                 // System.out.println(j+": "+ 
    113                                 //      stack.get(j).toString()); 
    114                                 thisResult[j] = (Edge)( stack.get(j) ); 
    115                         } 
    116                          
    117                         results[i] = thisResult; 
    118                 } 
    119                  
    120                 return results; 
     85         
     86        return chart; 
    12187        } 
    12288 
    123     public Edge[][] parseFor(String input, String goal) 
     89    public List parseFor(String input, String goal) 
    12490    { 
    12591        return parseFor(input, goal, false); 
    12692    } 
    12793     
     94    /* 
    12895    private String getStringFromArray(Object [] array) 
    12996    { 
     
    141108        return sb.toString(); 
    142109    } 
     110    */ 
    143111 
    144         public Edge[][] parseFor(String input, String goal, boolean verbose)  
     112        public List parseFor(String input, String goal, boolean verbose)  
    145113    { 
    146                 Edge[][] parseResults = parse(input); 
     114                Chart chart = parse(input); 
    147115                 
    148                 Vector results = new Vector(); 
    149                 for (int i = 0; i < parseResults.length; i++)  
     116        List edges = chart.getEdges(); 
     117                List goals = new ArrayList(); 
     118         
     119                for (Iterator i = edges.iterator(); i.hasNext(); )  
    150120        { 
    151                        Edge[] result = parseResults[i]
    152                         if (result.length > 1)  
    153                        
     121            Edge edge = (Edge)( i.next() )
     122            if (! edge.symbol().equals(goal)) 
     123           
    154124                if (verbose) 
    155125                { 
    156                     System.out.println("Rejected stack " + (i+1) + 
    157                         ": too long: " + getStringFromArray(result)); 
     126                    System.out.println("Rejected non-goal edge: " + edge); 
    158127                }    
    159                 continue; 
    160                         } 
    161                          
    162             String symbol = result[0].symbol(); 
    163                         if (! symbol.equals(goal))  
    164             { 
    165                             if (verbose) 
    166                 { 
    167                     System.out.println("Rejected stack " + (i+1) + 
    168                         ": not " + goal + ": " + getStringFromArray(result)); 
    169                 } 
     128                 
    170129                continue; 
    171130            } 
    172131             
    173                        results.add(result)
     132            boolean hasHoles = false
    174133             
    175             if (!verbose
     134            for (int j = 0; j < chart.getWidth(); j++
    176135            { 
     136                if (! edge.isAt(j)) 
     137                { 
     138                    hasHoles = true; 
     139                    break; 
     140                } 
     141            } 
     142             
     143            if (hasHoles) 
     144            { 
     145                if (verbose) 
     146                { 
     147                    System.out.println("Rejected edge with holes: " + edge); 
     148                }    
    177149                continue; 
    178150            } 
    179151             
    180                System.out.println("Accepted stack "+(i+1)+":"); 
    181              
    182             for (int j = 0; j < result.length; j++)  
     152                       goals.add(edge); 
     153 
     154            if (verbose) 
    183155            { 
    184                                 if (result[j] instanceof RuleEdge)  
    185                 { 
    186                                         RuleEdge instance = (RuleEdge)( result[j] ); 
    187                                         StringBuffer buf = new StringBuffer(); 
    188                                         instance.appendStringPrettyPrint(buf); 
    189                                         System.out.println(buf.toString()); 
    190                                 }  
    191                 else  
    192                 { 
    193                                         System.out.print(result[j]); 
    194                                         System.out.print(" "); 
    195                                 } 
    196                         } 
    197              
    198                         System.out.println(""); 
     156                System.out.println("Accepted edge: " + edge); 
     157            }    
    199158                } 
    200159                 
    201                 Edge[][] resultArray = new Edge[results.size()][]; 
    202                 resultArray = (Edge[][])( results.toArray(resultArray) ); 
    203                 return resultArray; 
     160                return goals; 
    204161        } 
    205162} 
  • lex/trunk/src/com/qwirx/lex/parser/Rule.java

    r26 r30  
    77package com.qwirx.lex.parser; 
    88 
     9import java.util.ArrayList; 
    910import java.util.Hashtable; 
    1011import java.util.Iterator; 
     
    2425        private final boolean     m_isPermutable; 
    2526    private final boolean     m_isSearching; 
     27    private final List []     m_PartBindingLists;  
     28    private final boolean []  m_PartsFinished; 
     29    private       boolean []  m_PositionsUsed; 
    2630     
    2731        public Rule 
     
    3741                this.fixedAttrs = fixedAttrs; 
    3842                this.copyAttrs  = copyAttrs; 
    39         this.m_isPermutable = isPermutable; 
    40         this.m_isSearching  = isSearching; 
     43         
     44        m_isPermutable = isPermutable; 
     45        m_isSearching  = isSearching; 
     46        m_PartBindingLists = new List [right.length]; 
     47        m_PartsFinished = new boolean [right.length]; 
     48         
     49        for (int i = 0; i < right.length; i++) 
     50        { 
     51            m_PartBindingLists[i] = new ArrayList(); 
     52            m_PartsFinished[i] = false; 
     53        } 
    4154        } 
    4255 
     
    207220     
    208221    private int m_NumPartsRemaining; 
    209     private boolean [] m_PartsAlreadyUsed; 
    210222     
    211223    private void hidePart(int index) 
    212224    { 
    213         if (m_PartsAlreadyUsed[index]) 
     225        if (m_PartsFinished[index]) 
    214226        { 
    215227            throw new AssertionError("the current rule part should " + 
    216228                "not be marked to be skipped"); 
    217229        } 
    218         m_PartsAlreadyUsed[index] = true; 
     230        m_PartsFinished[index] = true; 
    219231         
    220232        if (m_NumPartsRemaining <= 0) 
     
    228240    private void unhidePart(int index) 
    229241    { 
    230         if (!m_PartsAlreadyUsed[index]) 
     242        if (!m_PartsFinished[index]) 
    231243        { 
    232244            throw new AssertionError("the current rule part should " + 
    233245                "be marked to be skipped"); 
    234246        } 
    235         m_PartsAlreadyUsed[index] = false; 
     247        m_PartsFinished[index] = false; 
    236248         
    237249        if (m_NumPartsRemaining >= right.length) 
     
    243255    } 
    244256     
     257    private Chart m_CurrentChart; 
     258     
     259    /**  
     260     * Public entry point for parsing. 
     261     * @param chart A chart containing existing edges to apply to 
     262     * @param endPos The right-hand side of the chart, where this rule is 
     263     * required to match this time (it may match elsewhere as well)  
     264     * @return A list of new Edges to be added to the Chart 
     265     */ 
     266    public List applyTo(Chart chart, int endPos) 
     267    { 
     268        m_CurrentChart = chart; 
     269         
     270        // debugging code 
     271        for (int i = 0; i < right.length; i++) 
     272        { 
     273            if (m_PartBindingLists[i].size() > 0) 
     274            { 
     275                throw new AssertionError 
     276                ( 
     277                    "the part binding list should be empty at the start of " + 
     278                    "the parse" 
     279                ); 
     280            } 
     281             
     282            if (m_PartsFinished[i]) 
     283            { 
     284                throw new AssertionError 
     285                ( 
     286                    "no parts should be already used at the start of the parse" 
     287                ); 
     288                 
     289            } 
     290        } 
     291         
     292        m_PositionsUsed = new boolean[endPos + 1]; 
     293 
     294        // we must always match an edge at the specified end position, 
     295        // which will be different every time we are called, 
     296        // otherwise we will generate duplicate edges. 
     297         
     298        List oldEdges = chart.getEdgesAt(endPos); 
     299        List newEdges = new ArrayList(); 
     300         
     301        if (m_isSearching || m_isPermutable) 
     302        { 
     303            // any part can match one or more edges 
     304             
     305        } 
     306        else 
     307        { 
     308            // the last part must match one or more edges, 
     309            // unless it's optional, in which case it might be skipped 
     310            // and the last-but-one might match, etc. 
     311             
     312            int firstPartSkipped = right.length; 
     313             
     314            for (int partIndex = right.length - 1; partIndex >= 0; partIndex--) 
     315            { 
     316                RulePart part = right[partIndex]; 
     317                 
     318                for (Iterator i = oldEdges.iterator(); i.hasNext(); ) 
     319                { 
     320                    Edge edge = (Edge)( i.next() ); 
     321                    if (part.matches(edge)) 
     322                    { 
     323                        bindAndContinueParse(partIndex, edge, newEdges); 
     324                    } 
     325                } 
     326                 
     327                if (!part.canSkip()) 
     328                { 
     329                    break; 
     330                } 
     331                 
     332                m_PartsFinished[partIndex] = true; 
     333                firstPartSkipped = partIndex; 
     334            } 
     335             
     336            for (int i = firstPartSkipped; i < right.length; i++) 
     337            { 
     338                if (!m_PartsFinished[i]) throw new AssertionError(); 
     339                m_PartsFinished[i] = false; 
     340            } 
     341        } 
     342         
     343        return newEdges; 
     344    } 
     345     
     346    private void bindAndContinueParse(int partIndex, Edge edge, List newEdges) 
     347    { 
     348        for (int i = 0; i < right.length; i++) 
     349        { 
     350            if (m_PartBindingLists[i].contains(edge)) 
     351            { 
     352                throw new AssertionError 
     353                ( 
     354                    "No part binding list should already contain this edge" 
     355                ); 
     356            } 
     357        } 
     358 
     359        m_PartBindingLists[partIndex].add(0, edge); 
     360 
     361        if (m_PartsFinished[partIndex]) 
     362        { 
     363            throw new AssertionError 
     364            ( 
     365                "Not allowed to bind a rule part that is already finished" 
     366            ); 
     367        } 
     368         
     369        for (int i = 0; i < m_PositionsUsed.length; i++) 
     370        { 
     371            if (!edge.isAt(i)) 
     372            { 
     373                continue; 
     374            } 
     375             
     376            if (m_PositionsUsed[i]) 
     377            { 
     378                throw new AssertionError 
     379                ( 
     380                    "Not allowed to bind an edge that overlaps an existing " + 
     381                    "bound edge" 
     382                ); 
     383            } 
     384             
     385            m_PositionsUsed[i] = true; 
     386        } 
     387         
     388        if (right[partIndex].canRepeat()) 
     389        { 
     390            continueParseWithThisPart(partIndex, true, newEdges); 
     391        } 
     392        else 
     393        { 
     394            m_PartsFinished[partIndex] = true; 
     395            continueParseWithNextPart(newEdges);         
     396            m_PartsFinished[partIndex] = false; 
     397        } 
     398         
     399        for (int i = 0; i < m_PositionsUsed.length; i++) 
     400        { 
     401            if (!edge.isAt(i)) 
     402            { 
     403                continue; 
     404            } 
     405             
     406            if (!m_PositionsUsed[i]) 
     407            { 
     408                throw new AssertionError 
     409                ( 
     410                    "Positions used by this edge should be marked as used" 
     411                ); 
     412            } 
     413             
     414            m_PositionsUsed[i] = false; 
     415        } 
     416 
     417        for (int i = 0; i < right.length; i++) 
     418        { 
     419            if (i == partIndex) 
     420            { 
     421                if (!m_PartBindingLists[i].contains(edge)) 
     422                { 
     423                    throw new AssertionError 
     424                    ( 
     425                        "The part binding list for this part should " + 
     426                        "contain this edge" 
     427                    ); 
     428                } 
     429            } 
     430            else 
     431            { 
     432                if (m_PartBindingLists[i].contains(edge)) 
     433                { 
     434                    throw new AssertionError 
     435                    ( 
     436                        "No other part binding list should contain this edge" 
     437                    ); 
     438                } 
     439            } 
     440        } 
     441 
     442        m_PartBindingLists[partIndex].remove(edge); 
     443    } 
     444 
     445    private void continueParseWithNextPart(List newEdges) 
     446    { 
     447        boolean foundUnfinishedPart = false; 
     448         
     449        for (int i = right.length - 1; i >= 0; i--) 
     450        { 
     451            if (m_PartsFinished[i]) 
     452            { 
     453                continue; 
     454            } 
     455             
     456            foundUnfinishedPart = true; 
     457             
     458            continueParseWithThisPart(i, false, newEdges); 
     459             
     460            // reordering of elements in permutable rules happens here, 
     461            // by allowing the loop to proceed with the next unfinished part. 
     462            if (!m_isPermutable) 
     463            { 
     464                return; 
     465            } 
     466        } 
     467         
     468        if (foundUnfinishedPart) 
     469        { 
     470            return; 
     471        } 
     472         
     473        // base case: we end up here when all parts have been used, 
     474        // and we should be ready to create a new edge. 
     475         
     476        // don't create new edges which don't contain any other edges: 
     477        // we could keep doing that forever. 
     478         
     479        int numEdges = 0; 
     480         
     481        for (int i = 0; i < right.length; i++) 
     482        { 
     483            numEdges += m_PartBindingLists[i].size(); 
     484        } 
     485         
     486        if (numEdges == 0) 
     487        { 
     488            return; 
     489        } 
     490 
     491        int position = 0; 
     492        Edge[] contained = new Edge[numEdges]; 
     493         
     494        for (int i = 0; i < right.length; i++) 
     495        { 
     496            for (Iterator j = m_PartBindingLists[i].iterator(); j.hasNext(); ) 
     497            { 
     498                Edge edge = (Edge)( j.next() ); 
     499                Edge unbound = edge.getUnboundCopy(); 
     500                try 
     501                { 
     502                    unbound.bindTo(null, right[i]); 
     503                } 
     504                catch (AlreadyBoundException e) 
     505                { 
     506                    throw new AssertionError(e); 
     507                } 
     508                contained[position++] = unbound; 
     509            } 
     510        } 
     511         
     512        if (position != numEdges) 
     513        { 
     514            throw new AssertionError(); 
     515        } 
     516         
     517        Edge newEdge = new RuleEdge(this, contained); 
     518        newEdges.add(newEdge);        
     519    } 
     520 
     521    private void continueParseWithThisPart(int partIndex, boolean hasMatched, 
     522        List newEdges) 
     523    { 
     524        if (m_PartsFinished[partIndex]) 
     525        { 
     526            throw new AssertionError 
     527            ( 
     528                "Not allowed to bind a rule part that is already finished" 
     529            ); 
     530        } 
     531 
     532        // find any other edges that we can use 
     533         
     534        int rightmostEmptyPos = -1; 
     535        for (int i = m_PositionsUsed.length - 1; i >= 0; i--) 
     536        { 
     537            if (!m_PositionsUsed[i]) 
     538            { 
     539                rightmostEmptyPos = i; 
     540                break; 
     541            } 
     542        } 
     543         
     544        List edges = m_CurrentChart.getEdgesAt(rightmostEmptyPos); 
     545        RulePart part = right[partIndex]; 
     546                 
     547        for (Iterator i = edges.iterator(); i.hasNext(); ) 
     548        { 
     549            Edge edge = (Edge)( i.next() ); 
     550            if (!part.matches(edge)) 
     551            { 
     552                continue; 
     553            } 
     554             
     555            // check that the edge doesn't overlap any previously chosen ones 
     556            boolean overlaps = false; 
     557            for (int j = rightmostEmptyPos + 1;  
     558                j < m_CurrentChart.getWidth(); j++) 
     559            { 
     560                if (edge.isAt(j)) 
     561                { 
     562                    overlaps = true; 
     563                    break; 
     564                } 
     565            } 
     566             
     567            if (overlaps == true) 
     568            { 
     569                continue; 
     570            } 
     571             
     572            bindAndContinueParse(partIndex, edge, newEdges); 
     573        } 
     574         
     575        // Optional elements may only be skipped (match 0 times) 
     576        // in permutable rules if no matches have yet been made. 
     577        // This enforces the condition that they may not match  
     578        // nothing at different places in the same input, which  
     579        // would produce duplicate trees in the output. 
     580         
     581        boolean canSkip = part.canSkip(); 
     582         
     583        if (canSkip && m_isPermutable) 
     584        { 
     585            for (int i = 0; i < m_PositionsUsed.length; i++) 
     586            { 
     587                if (m_PositionsUsed[i]) 
     588                { 
     589                    canSkip = false; 
     590                    break; 
     591                } 
     592            } 
     593        } 
     594 
     595        // stop now if this part is not optional and has not matched yet 
     596        if (!canSkip && !hasMatched) 
     597        { 
     598            return; 
     599        } 
     600         
     601        // mark it as finished, so we can move onto the next part 
     602        // (in the case where it is optional and being skipped) 
     603         
     604        m_PartsFinished[partIndex] = true; 
     605         
     606        continueParseWithNextPart(newEdges); 
     607         
     608        if (!m_PartsFinished[partIndex]) 
     609        { 
     610            throw new AssertionError("this part should still be marked" + 
     611                "as fininshed"); 
     612        } 
     613         
     614        m_PartsFinished[partIndex] = false; 
     615    } 
     616 
    245617    private void apply(List stack, Match match, List out) 
    246618    { 
     
    251623            for (int i = 0; i < right.length; i++) 
    252624            { 
    253                 if (m_PartsAlreadyUsed[i]) 
     625                if (m_PartsFinished[i]) 
    254626                { 
    255627                    realNumPartsRemaining--; 
     
    321693            for (int i = right.length - 1; i >= 0; i--) 
    322694            { 
    323                 if (!m_PartsAlreadyUsed[i]) 
     695                if (!m_PartsFinished[i]) 
    324696                { 
    325697                    firstRulePartIndex = i; 
     
    339711        for (int i = firstRulePartIndex; i < right.length; i++) 
    340712        { 
    341             if (m_PartsAlreadyUsed[i]) 
     713            if (m_PartsFinished[i]) 
    342714            { 
    343715                // the caller has processed this part, and asked us to skip it 
     
    528900            for (int i = right.length - 1; i >= 0; i--) 
    529901            { 
    530                 if (!m_PartsAlreadyUsed[i]) 
     902                if (!m_PartsFinished[i]) 
    531903                { 
    532904                    nextPartIndex = i; 
     
    566938        Match match = new Match(right.length); 
    567939        List out = new Vector(); 
    568         m_PartsAlreadyUsed = new boolean [right.length]; 
     940        for (int i = 0; i < right.length; i++) 
     941        { 
     942            m_PartsFinished[i] = false; 
     943        } 
    569944        m_NumPartsRemaining = right.length; 
    570945        apply(stack, match, out); 
  • lex/trunk/src/com/qwirx/lex/parser/RuleEdge.java

    r26 r30  
    1616{ 
    1717        private final Edge [] parts; 
    18         private final Rule        rule; 
     18        private final Rule    rule; 
    1919        private Map attribs = new Hashtable(); 
    2020         
     
    5454                super(); 
    5555        this.rule  = rule; 
    56                 this.parts = new Edge [parts.length]; 
     56 
     57        this.parts = new Edge [parts.length]; 
    5758         
    5859        for (int i = 0; i < this.parts.length; i++) 
     
    104105        } 
    105106     
    106         public String toString() { 
     107        public String toString()  
     108    { 
    107109                StringBuffer buf = new StringBuffer(); 
    108110                appendString(buf); 
    109111                return buf.toString(); 
    110112        } 
    111         public void appendString(StringBuffer buf) { 
     113     
     114        public void appendString(StringBuffer buf)  
     115    { 
    112116                buf.append("{"); 
    113117                buf.append(rule().symbol()); 
     
    115119                 
    116120                Map attribs = attributes(); 
    117                 for (Iterator i = attribs.entrySet().iterator(); i.hasNext(); ) { 
     121                for (Iterator i = attribs.entrySet().iterator(); i.hasNext(); )  
     122        { 
    118123                        Entry e = (Entry)( i.next() ); 
    119124                        buf.append(e.getKey()); 
     
    142147                buf.append("}"); 
    143148        } 
    144         public void appendStringPrettyPrint(StringBuffer buf) { 
     149     
     150        public void appendStringPrettyPrint(StringBuffer buf)  
     151    { 
    145152                appendStringPrettyPrint(buf, ""); 
    146153        } 
    147         private void appendStringPrettyPrint(StringBuffer buf, String indent) { 
     154     
     155        private void appendStringPrettyPrint(StringBuffer buf, String indent)  
     156    { 
    148157                buf.append(indent); 
    149158                buf.append("{"); 
     
    152161                 
    153162                Map attribs = attributes(); 
    154                 for (Iterator i = attribs.entrySet().iterator(); i.hasNext(); ) { 
     163                for (Iterator i = attribs.entrySet().iterator(); i.hasNext(); )  
     164        { 
    155165                        Entry e = (Entry)( i.next() ); 
    156166                        buf.append(e.getKey()); 
     
    190200                buf.append("}"); 
    191201        } 
    192         public String[] words() { 
     202     
     203        public String[] words()  
     204    { 
    193205                Vector v = new Vector(); 
    194206                appendWords(v); 
    195207                return (String[])( v.toArray(new String[v.size()]) ); 
    196208        } 
    197         public void appendWords(Vector words) { 
    198                 for (int i = 0; i < parts.length; i++) { 
     209     
     210        public void appendWords(Vector words)  
     211    { 
     212                for (int i = 0; i < parts.length; i++)  
     213        { 
    199214                        parts[i].appendWords(words); 
    200215                } 
    201216        } 
    202         public Edge[] parts() { 
     217     
     218        public Edge[] parts()  
     219    { 
    203220                Edge [] result = new Edge[parts.length]; 
    204221                System.arraycopy(parts, 0, result, 0, parts.length); 
     
    219236         
    220237    public Map attributes() { return attribs; } 
    221         private void findAttributes() { 
     238        private void findAttributes()  
     239    { 
    222240                attribs = new Hashtable(); 
    223241                 
     
    240258                                 
    241259                                Edge partInstance = parts[p]; 
     260                 
    242261                                Object value = partInstance.attributes().get(name); 
    243                                 if (value == null) { 
     262                 
     263                                if (value == null)  
     264                { 
    244265                                        throw new IllegalStateException( 
    245266                                                        partInstance.toString()+ 
     
    247268                                                        name+" to copy into "+this); 
    248269                                } 
     270                 
    249271                                Object oldValue = attribs.get(name); 
    250                                 if (oldValue != null && ! oldValue.equals(value)) { 
     272                 
     273                                if (oldValue != null && ! oldValue.equals(value))  
     274                { 
    251275                                        throw new IllegalStateException( 
    252276                                                        "Unable to unify "+oldValue+" and "+value+ 
    253277                                                        " for attribute "+name+" of "+this); 
    254278                                } 
    255                                 if (oldValue == null) { 
     279                 
     280                                if (oldValue == null)  
     281                { 
    256282                                        attribs.put(name, value); 
    257283                                } 
     
    281307                } 
    282308        } 
    283         public int getDepthScore() { 
     309     
     310        public int getDepthScore()  
     311    { 
    284312                return getDepthScore(1); 
    285313        } 
    286         private int getDepthScore(int initialDepth) { 
     314     
     315        private int getDepthScore(int initialDepth)  
     316    { 
    287317                int d = initialDepth; 
    288                 for (int i = 0; i < parts.length; i++) { 
    289                         if (parts[i] instanceof RuleEdge) { 
     318                for (int i = 0; i < parts.length; i++)  
     319        { 
     320                        if (parts[i] instanceof RuleEdge)  
     321            { 
    290322                                d += ((RuleEdge)(parts[i])).getDepthScore(initialDepth+1); 
    291323                        } 
     
    293325                return d; 
    294326        } 
     327     
    295328    public Edge getUnboundCopy() 
    296329    { 
    297330        return new RuleEdge(rule, parts); 
    298331    } 
     332     
     333    public boolean isAt(int position) 
     334    { 
     335        for (int i = 0; i < parts.length; i++) 
     336        { 
     337            if (parts[i].isAt(position)) 
     338            { 
     339                return true; 
     340            } 
     341        } 
     342         
     343        return false; 
     344    } 
    299345} 
  • lex/trunk/src/com/qwirx/lex/parser/WordEdge.java

    r26 r30  
    1919    private static final Edge[]   parts   = new Edge[0]; 
    2020    private static final ImmutableMap attribs = new