001    /*
002     * LAPIS lightweight structured text processing system
003     *
004     * Copyright (C) 1998-2002 Carnegie Mellon University,
005     * Copyright (C) 2003 Massachusetts Institute of Technology.
006     * All rights reserved.
007     *
008     * This library is free software; you can redistribute it
009     * and/or modify it under the terms of the GNU General
010     * Public License as published by the Free Software
011     * Foundation, version 2.
012     *
013     * LAPIS homepage: http://graphics.lcs.mit.edu/lapis/
014     */
015    
016    package lapis.tc;
017    
018    import lapis.*;
019    import java.io.*;
020    import java.util.*;
021    import lapisx.util.Str;
022    import lapisx.util.Debug;
023    
024    public class TC implements Pattern, Parser, Serializable {
025        public static Debug debug = Debug.QUIET;
026    
027        Node root;    // root of Node expression tree; never null
028        TCToken syntax; // root of TCToken syntax tree; may be null
029        String href;    // URL or resource name from which tree was parsed 
030                        // (or null)
031        String expression; // expression from which tree was parsed (or null)
032    
033        Evaluator evaluator;  // evaluation context (or null)
034    
035        public TC (Node root) {
036            this.root = (root != null) ? root : new Nothing ();
037        }
038    
039        public TC (Node root, String expression) {
040            this (root);
041            this.expression = expression;
042        }
043    
044        public TC (Node root, Evaluator evaluator) {
045            this (root);
046            this.evaluator = evaluator;
047        }
048    
049        /**
050         * Create a TC expression tree by parsing a Reader stream.  Doesn't
051         * close the input stream.
052         * @param in Stream to parse
053         * @exception TCParseException if expression is not a valid TC pattern
054         * @exception IOException if an I/O error occurs
055         */
056        public TC (Reader reader) throws TCParseException, IOException {
057            parse (reader, false);
058        }
059    
060        void parse (Reader reader, boolean justOneExpression) 
061            throws TCParseException, IOException {
062            TCParseException errors = new TCParseException ();
063    
064            syntax = TCParser.parseSyntax (reader, errors);
065            reader.close ();
066    
067            if (justOneExpression && syntax != null && syntax.sibling != null) {
068                errors.addError (syntax.sibling, "too many expressions");
069                throw errors;
070            }
071    
072            root = 
073                justOneExpression
074                ? TCParser.translateNoun (syntax, errors)
075                : TCParser.translateSequence (syntax, errors);
076            if (root == null)
077                root = new Nothing ();
078    
079            if (!errors.isEmpty ())
080                throw errors;
081        }
082    
083        /**
084         * Create a TC expression tree by parsing it from a string.
085         * @param expression TC expression
086         * @exception TCParseException if expression is not a valid TC pattern
087         */
088        public TC (String expression) throws TCParseException {
089            this (expression, false);
090        }
091    
092        /**
093         * Create a TC expression tree by parsing it from a string.
094         * @param expression TC expression
095         * @param justOneExpression if true, allows expression to contain only
096         * one TC expression (as opposed to a sequence of assignments)
097         * @exception TCParseException if expression is not a valid TC pattern
098         */
099        public TC (String expression, boolean justOneExpression) throws TCParseException {
100            try {
101                parse (new StringReader (expression), justOneExpression);
102            } catch (IOException e) {
103                throw new TCParseException (e.toString ());
104            }
105            this.expression = expression;
106        }
107    
108        /**
109         * Create a TC expression tree by parsing it from a string.  
110         * By using this method, the caller
111         * is asserting that the TC expression is syntactically correct.
112         * An unchecked RuntimeException will be thrown if a syntax error is 
113         * found.
114         * @param expression TC expression
115         * @return parsed TC object 
116         * @exception RuntimeException if expression is not a valid TC pattern
117         */
118        public static TC make (String expression) {
119            try {
120                return new TC (expression);
121            } catch (TCParseException e) {
122                // caller asserts that this shouldn't happen
123                debug.report (e);
124                throw new RuntimeException (e.toString ());
125            }       
126        }
127    
128    
129        /**
130         * Create a TC expression that matches a literal string.
131         * Deals with newlines and quotes properly.
132         */
133        public static String makeLiteral (String lit) {
134            boolean hasLinebreak = (lit.indexOf ('\n') != -1);
135            boolean hasSingleQuote = (lit.indexOf ('\'') != -1);
136            boolean hasDoubleQuote = (lit.indexOf ('"') != -1);
137    
138            if (hasLinebreak || (hasSingleQuote && hasDoubleQuote))
139                return getTCRegexp (lit);
140            else if (hasDoubleQuote)
141                return "'" + lit + "'";
142            else
143                return "\"" + lit + "\"";
144        }
145    
146        static String getTCRegexp (String lit) {
147            return "/" + Str.escape (lit, "\n\\/().*+?{}", '\\', "n\\/().*+?{}") + "/";
148        }
149    
150    
151        /**
152         * Create a TC expression tree by parsing it from a file.
153         * @param f File to parse
154         * @exception TCParseException if expression is not a valid TC pattern
155         * @exception IOException if an I/O error occurs
156         */
157        public TC (File srcFile) throws TCParseException, IOException {
158            href = srcFile.toString ();
159    
160            // first try to load preparsed object file (.tco file)
161            File objFile = toObjectFile (srcFile);
162            try {
163                if (newerThan (objFile, srcFile)) {
164                    ObjectInputStream in = 
165                        new ObjectInputStream (new FileInputStream (objFile));
166                    root = (TC.Node) in.readObject ();
167                    in.close ();
168                    return;
169                }
170            } catch (Exception e) {
171            }
172    
173            // if we got here, the .tco file wasn't found or was corrupt.
174            // load and parse the source (.tc file) instead.
175            parse (new FileReader (srcFile), false);
176    
177            // store the parse tree out to a .tco file
178            ObjectOutputStream out = 
179                new ObjectOutputStream (new FileOutputStream (objFile));
180            out.writeObject (root);
181            out.close ();
182    
183        }
184    
185        static File toObjectFile (File f) {
186            String pathname = f.getAbsolutePath ();
187            return new File (Str.before (pathname, ".tc") + ".tco");
188        }
189    
190        public static boolean newerThan (File f, File g) {
191            long fTime = f.lastModified ();
192            long gTime = g.lastModified ();
193            return (fTime != 0 && gTime != 0 && fTime >= gTime);
194        }
195    
196        static boolean isTC(Pattern pat) {
197            if(pat instanceof CachedPattern)
198                pat=((CachedPattern) pat).getPattern();
199            return (pat instanceof TC);
200        }
201    
202        /**
203         * Create a TC expression tree by parsing it from a 
204         * class resource (i.e., a file found inside a
205         * JAR archive or in a Java class hierarchy).
206         * Returns the root of a TC tree representing the expression
207         * @param cls Class to use for Class.getResourceAsStream() call
208         * @param name Name to pass to Class.getResourceAsStream()
209         * @exception TCParseException if expression is not a valid TC pattern
210         * @exception IOException if an I/O error occurs
211         */
212        public TC (Class cls, String name) throws TCParseException, IOException {
213            InputStream stream = cls.getResourceAsStream (name);
214            if (stream == null)
215                throw new IOException ("Resource " + name + " not found");
216            Reader reader = new InputStreamReader (stream);
217            parse (reader, false);
218            href = name;
219        }
220        
221        /**
222         * Create a TC expression tree representing a constant region set.
223         * Returns a TC expression that returns sel.regions when it is evaluated
224         * on sel.doc, but empty set when evaluated on any other document.
225         * @param sel a selection (a RegionSet/Document/DocumentVersion triple)
226         */
227        public TC (NamedRegionSet sel) {
228            root = new Constant (sel);
229        }
230    
231        public String getHref () {
232            return href;
233        }
234    
235        public String getExpression () {
236            return expression;
237        }
238    
239        public TCToken getSyntax () {
240            return syntax;
241        }
242    
243        public TC.Node getRoot () {
244            return root;
245        }
246    
247            /*
248        public String getName () {
249                    Set set = getNames();
250                    if (set == null)
251                    return null;
252                    if (set.size() == 1) {
253                    Iterator i = set.iterator();
254                    return (String)i.next();
255                    } 
256                    else 
257                    return null;
258        }
259            */
260        /*
261         * returns the set of Names if the pattern has a name
262         */
263        public Set getNames () {
264                    debug.println(root.accept (LABEL_FINDER).getClass().getName());
265                    return (Set) root.accept (LABEL_FINDER); 
266        }
267    
268            
269            public String parseSyntax() {
270            return parseSyntax(syntax);
271        }
272    
273        private String parseSyntax(TCToken tok) {
274            if(tok == null)
275                    return "";
276            else return tok.text+parseSyntax(tok.child)+parseSyntax(tok.sibling);
277        }
278        
279        public String toString () {
280            return expression != null ? expression : super.toString ();
281        }
282    
283        static final Visitor LABEL_FINDER = new Visitor () {
284            public Object forConstant (TC.Constant n) { return Collections.EMPTY_SET; }
285            public Object forExternalPattern (TC.ExternalPattern n) { return Collections.EMPTY_SET; }
286            public Object forLiteral (TC.Literal n) { return Collections.EMPTY_SET; }
287            public Object forRegexp (TC.Regexp n) { return Collections.EMPTY_SET; }
288            public Object forId (TC.Id n) { 
289                Set set =  new HashSet ();
290                debug.println("forID " + n.getString());
291                set.add(n.getString());
292                return set;
293            }
294            
295            public Object forAny (TC.Any n) { return Collections.EMPTY_SET; }
296            public Object forNothing (TC.Nothing n) { return Collections.EMPTY_SET; }
297            public Object forEquals (TC.Equals n) { return Collections.EMPTY_SET; }
298            public Object forBefore (TC.Before n) { return Collections.EMPTY_SET; }
299            public Object forAfter (TC.After n) { return Collections.EMPTY_SET; }
300            public Object forJustBefore (TC.JustBefore n) { return Collections.EMPTY_SET; }
301            public Object forJustAfter (TC.JustAfter n) { return Collections.EMPTY_SET; }
302            public Object forBeforeDelimited (TC.BeforeDelimited n) { return Collections.EMPTY_SET; }
303            public Object forAfterDelimited (TC.AfterDelimited n) { return Collections.EMPTY_SET; }
304            public Object forJustBeforeDelimited (TC.JustBeforeDelimited n) { return Collections.EMPTY_SET; }
305            public Object forJustAfterDelimited (TC.JustAfterDelimited n) { return Collections.EMPTY_SET; }
306            public Object forIn (TC.In n) { return Collections.EMPTY_SET; }
307            public Object forContains (TC.Contains n) { return Collections.EMPTY_SET; }
308                    
309            
310            public Object forDescendant (TC.Descendant n) { return Collections.EMPTY_SET; }
311            public Object forAncestor (TC.Ancestor n) { return Collections.EMPTY_SET; }
312            
313            public Object forStarting (TC.Starting n) { return Collections.EMPTY_SET; }
314            public Object forEnding (TC.Ending n) { return Collections.EMPTY_SET; }
315            public Object forStartingDelimited (TC.StartingDelimited n) { return Collections.EMPTY_SET; }
316            public Object forEndingDelimited (TC.EndingDelimited n) { return Collections.EMPTY_SET; }
317            public Object forOverlapsStart (TC.OverlapsStart n) { return Collections.EMPTY_SET; }
318            public Object forOverlapsEnd (TC.OverlapsEnd n) { return Collections.EMPTY_SET; }
319            public Object forOverlaps (TC.Overlaps n) { return Collections.EMPTY_SET; }
320            public Object forSeparatedBy (TC.SeparatedBy n) { return Collections.EMPTY_SET; }
321            public Object forStartOf (TC.StartOf n) { return Collections.EMPTY_SET; }
322            public Object forEndOf (TC.EndOf n) { return Collections.EMPTY_SET; }
323            public Object forBalancedUnary (TC.BalancedUnary n) { return Collections.EMPTY_SET; }
324            public Object forFlatten (TC.Flatten n) { return Collections.EMPTY_SET; }
325            public Object forMelt (TC.Melt n) { return Collections.EMPTY_SET; }
326            public Object forCrispen (TC.Crispen n) { return Collections.EMPTY_SET; }
327            public Object forNonempty (TC.Nonempty n) { return Collections.EMPTY_SET; }
328            public Object forAnd (TC.And n) { return Collections.EMPTY_SET; }
329            public Object forOr (TC.Or n) { 
330                Set args = new HashSet();
331                args.addAll((Set)n.getArg1 ().accept (this));
332                args.addAll((Set)n.getArg2 ().accept (this));
333                return args;
334            }
335            public Object forButNot (TC.ButNot n) { return Collections.EMPTY_SET; }
336            public Object forNextTo (TC.NextTo n) { return Collections.EMPTY_SET; }
337            public Object forTrim (TC.Trim n) { return Collections.EMPTY_SET; }
338            public Object forInclude (TC.Include n) { return Collections.EMPTY_SET; }
339            public Object forSeq (TC.Seq n) { return Collections.EMPTY_SET; }
340            public Object forBalancedBinary (TC.BalancedBinary n) { return Collections.EMPTY_SET; }
341            public Object forFromTo (TC.FromTo n) { return Collections.EMPTY_SET; }
342            public Object forIgnoreBinary (TC.IgnoreBinary n) { return Collections.EMPTY_SET; }
343            public Object forAssign (TC.Assign n) {
344                Set set =  new HashSet ();
345                set.add(n.getString());
346                return set;
347            }
348            public Object forOrButNot (TC.OrButNot n) { return Collections.EMPTY_SET; }
349            public Object forNth (TC.Nth n) { return Collections.EMPTY_SET; }
350            public Object forPrefix (TC.Prefix n) { return Collections.EMPTY_SET; }
351            public Object forCaseSensitivity (TC.CaseSensitivity n) { return Collections.EMPTY_SET; }
352            public Object forView (TC.View n) { return Collections.EMPTY_SET; }
353            public Object forUnbind (TC.Unbind n) { return Collections.EMPTY_SET; }
354        };
355        //
356        // Evaluation
357        //
358    
359        public RegionSet match (Document doc) {
360                    long start = System.currentTimeMillis();
361            try {
362                return matchWithWarnings (doc);
363            } catch (TCParseException e) {
364                return RegionSet.EMPTY;
365            }
366            finally {
367                debug.println("TC parser ran in: " + 
368                              (System.currentTimeMillis() - start) + 
369                              " ms");
370            }
371        }
372    
373        public RegionSet matchWithWarnings (Document doc) throws TCParseException {
374            TCParseException warnings = new TCParseException ();
375            Evaluator e;
376            if (evaluator != null) {
377                e = (Evaluator) evaluator.clone();
378                e.doc = doc;
379                e.warnings = warnings;
380                e.lib = PatternLibrary.getDocumentLibrary(doc);
381            } else
382                e = new Evaluator (doc, warnings);
383            
384            RegionSet s = (RegionSet) root.accept (e);
385            if (!warnings.isEmpty ())
386                throw warnings;
387    
388            return s;
389        }
390    
391        //
392        // Binding a set of named patterns into PatternLibrary
393        //
394    
395        public void bind (PatternLibrary lib) {
396            root.accept (new Evaluator (lib));
397        }
398    
399        public void bind (PatternLibrary lib, Document doc) {
400            // no doc-specific patterns for this parser
401        }
402    
403        public TC toBoundExpression (PatternLibrary lib) {
404            return new TC (bindExpression (getRoot (),
405                                           lib,
406                                           "",
407                                           new TCParseException ()),
408                           getExpression ());
409        }
410    
411        public static TC.Node bindExpression (TC.Node node, 
412                                              PatternLibrary lib,
413                                              String prefix,
414                                              TCParseException warnings) {
415            return (TC.Node) node.accept 
416                (new BindingCloner (lib, prefix, warnings));
417        }
418    
419        static class BindingCloner extends Cloner {
420            PatternLibrary lib;
421            String prefix;
422            TCParseException warnings;
423            public BindingCloner (PatternLibrary lib, 
424                                  String prefix,
425                                  TCParseException warnings) {
426                this.lib = lib;
427                this.prefix = prefix;
428                this.warnings = warnings;
429            }
430    
431            public Object forId (TC.Id n) {
432                try {
433                    lapis.Pattern pat = lib.get (lib.lookup (n.getString (), prefix));
434                    if (isTC (pat)) {
435                        debug.println ("binding " + n.getString ());
436                        return new TC.ExternalPattern (pat);
437                    } else {
438                        debug.println ("leaving unbound " + n.getString ());
439                        return n;
440                    }
441                } catch (PatternLibrary.LabelAmbiguousException e) {
442                    String msg = e.getMessage () +":";
443                    String[] choices = e.getChoices ();
444                    for (int i = 0; i < choices.length; ++i)
445                        msg += "\n    " + choices[i];
446                    warnings.addError (msg);
447                    return new TC.Nothing ();
448                } catch (PatternLibrary.LabelNotFoundException e) {
449                    return new TC.Literal (n.getString ());
450                }
451            }
452    
453            public Object forPrefix (TC.Prefix n) {
454                String oldPrefix = prefix;
455                String p = n.getPrefix ();
456                if (!p.startsWith ("."))
457                    p = prefix + "." + p;
458                prefix = p;
459                try {
460                    return super.forPrefix (n);
461                } finally {
462                    prefix = oldPrefix;
463                }
464            }
465        }
466    
467    
468        //
469        // Printing debugging representation
470        //
471    
472        public void print () {
473            PrintWriter out = new PrintWriter (System.err);
474            print (out, 0);
475        }
476    
477        public void print (final PrintWriter out, final int originalIndent) {
478            root.accept (new Traversal () {
479                int indent = originalIndent;
480                void printNode (TC.Node n) {
481                    out.println (Str.repeat (" ", indent) + n);
482                }
483                public Object forConstant (TC.Constant n) {
484                    printNode (n);
485                    indent += 2;
486                    super.forConstant (n);
487                    indent -= 2;
488                    return null;
489                }
490                public Object forExternalPattern (TC.ExternalPattern n) {
491                    printNode (n);
492                    indent += 2;
493                    super.forExternalPattern (n);
494                    indent -= 2;
495                    return null;
496                }
497                public Object forLiteral (TC.Literal n) {
498                    printNode (n);
499                    indent += 2;
500                    super.forLiteral (n);
501                    indent -= 2;
502                    return null;
503                }
504                public Object forRegexp (TC.Regexp n) {
505                    printNode (n);
506                    indent += 2;
507                    super.forRegexp (n);
508                    indent -= 2;
509                    return null;
510                }
511                public Object forId (TC.Id n) {
512                    printNode (n);
513                    indent += 2;
514                    super.forId (n);
515                    indent -= 2;
516                    return null;
517                }
518                public Object forAny (TC.Any n) {
519                    printNode (n);
520                    indent += 2;
521                    super.forAny (n);
522                    indent -= 2;
523                    return null;
524                }
525                public Object forNothing (TC.Nothing n) {
526                    printNode (n);
527                    indent += 2;
528                    super.forNothing (n);
529                    indent -= 2;
530                    return null;
531                }
532                public Object forEquals (TC.Equals n) {
533                    printNode (n);
534                    indent += 2;
535                    super.forEquals (n);
536                    indent -= 2;
537                    return null;
538                }
539                public Object forBefore (TC.Before n) {
540                    printNode (n);
541                    indent += 2;
542                    super.forBefore (n);
543                    indent -= 2;
544                    return null;
545                }
546                public Object forAfter (TC.After n) {
547                    printNode (n);
548                    indent += 2;
549                    super.forAfter (n);
550                    indent -= 2;
551                    return null;
552                }
553                public Object forJustBefore (TC.JustBefore n) {
554                    printNode (n);
555                    indent += 2;
556                    super.forJustBefore (n);
557                    indent -= 2;
558                    return null;
559                }
560                public Object forJustAfter (TC.JustAfter n) {
561                    printNode (n);
562                    indent += 2;
563                    super.forJustAfter (n);
564                    indent -= 2;
565                    return null;
566                }
567                public Object forBeforeDelimited (TC.BeforeDelimited n) {
568                    printNode (n);
569                    indent += 2;
570                    super.forBeforeDelimited (n);
571                    indent -= 2;
572                    return null;
573                }
574                public Object forAfterDelimited (TC.AfterDelimited n) {
575                    printNode (n);
576                    indent += 2;
577                    super.forAfterDelimited (n);
578                    indent -= 2;
579                    return null;
580                }
581                public Object forJustBeforeDelimited (TC.JustBeforeDelimited n) {
582                    printNode (n);
583                    indent += 2;
584                    super.forJustBeforeDelimited (n);
585                    indent -= 2;
586                    return null;
587                }
588                public Object forJustAfterDelimited (TC.JustAfterDelimited n) {
589                    printNode (n);
590                    indent += 2;
591                    super.forJustAfterDelimited (n);
592                    indent -= 2;
593                    return null;
594                }
595                public Object forIn (TC.In n) {
596                    printNode (n);
597                    indent += 2;
598                    super.forIn (n);
599                    indent -= 2;
600                    return null;
601                }
602                public Object forContains (TC.Contains n) {
603                    printNode (n);
604                    indent += 2;
605                    super.forContains (n);
606                    indent -= 2;
607                    return null;
608                }
609    
610                public Object forDescendant (TC.Descendant n) {
611                    printNode (n);
612                    indent += 2;
613                    super.forDescendant (n);
614                    indent -= 2;
615                    return null;
616                }
617                public Object forAncestor (TC.Ancestor n) {
618                    printNode (n);
619                    indent += 2;
620                    super.forAncestor (n);
621                    indent -= 2;
622                    return null;
623                }
624    
625                public Object forStarting (TC.Starting n) {
626                    printNode (n);
627                    indent += 2;
628                    super.forStarting (n);
629                    indent -= 2;
630                    return null;
631                }
632                public Object forEnding (TC.Ending n) {
633                    printNode (n);
634                    indent += 2;
635                    super.forEnding (n);
636                    indent -= 2;
637                    return null;
638                }
639                public Object forStartingDelimited (TC.StartingDelimited n) {
640                    printNode (n);
641                    indent += 2;
642                    super.forStartingDelimited (n);
643                    indent -= 2;
644                    return null;
645                }
646                public Object forEndingDelimited (TC.EndingDelimited n) {
647                    printNode (n);
648                    indent += 2;
649                    super.forEndingDelimited (n);
650                    indent -= 2;
651                    return null;
652                }
653                public Object forOverlapsStart (TC.OverlapsStart n) {
654                    printNode (n);
655                    indent += 2;
656                    super.forOverlapsStart (n);
657                    indent -= 2;
658                    return null;
659                }
660                public Object forOverlapsEnd (TC.OverlapsEnd n) {
661                    printNode (n);
662                    indent += 2;
663                    super.forOverlapsEnd (n);
664                    indent -= 2;
665                    return null;
666                }
667                public Object forOverlaps (TC.Overlaps n) {
668                    printNode (n);
669                    indent += 2;
670                    super.forOverlaps (n);
671                    indent -= 2;
672                    return null;
673                }
674                public Object forSeparatedBy (TC.SeparatedBy n) {
675                    printNode (n);
676                    indent += 2;
677                    super.forSeparatedBy (n);
678                    indent -= 2;
679                    return null;
680                }
681                public Object forStartOf (TC.StartOf n) {
682                    printNode (n);
683                    indent += 2;
684                    super.forStartOf (n);
685                    indent -= 2;
686                    return null;
687                }
688                public Object forEndOf (TC.EndOf n) {
689                    printNode (n);
690                    indent += 2;
691                    super.forEndOf (n);
692                    indent -= 2;
693                    return null;
694                }
695                public Object forBalancedUnary (TC.BalancedUnary n) {
696                    printNode (n);
697                    indent += 2;
698                    super.forBalancedUnary (n);
699                    indent -= 2;
700                    return null;
701                }
702                public Object forFlatten (TC.Flatten n) {
703                    printNode (n);
704                    indent += 2;
705                    super.forFlatten (n);
706                    indent -= 2;
707                    return null;
708                }
709                public Object forMelt (TC.Melt n) {
710                    printNode (n);
711                    indent += 2;
712                    super.forMelt (n);
713                    indent -= 2;
714                    return null;
715                }
716                public Object forCrispen (TC.Crispen n) {
717                    printNode (n);
718                    indent += 2;
719                    super.forCrispen (n);
720                    indent -= 2;
721                    return null;
722                }
723                public Object forNonempty (TC.Nonempty n) {
724                    printNode (n);
725                    indent += 2;
726                    super.forNonempty (n);
727                    indent -= 2;
728                    return null;
729                }
730                public Object forAnd (TC.And n) {
731                    printNode (n);
732                    indent += 2;
733                    super.forAnd (n);
734                    indent -= 2;
735                    return null;
736                }
737                public Object forOr (TC.Or n) {
738                    printNode (n);
739                    indent += 2;
740                    super.forOr (n);
741                    indent -= 2;
742                    return null;
743                }
744                public Object forButNot (TC.ButNot n) {
745                    printNode (n);
746                    indent += 2;
747                    super.forButNot (n);
748                    indent -= 2;
749                    return null;
750                }
751                public Object forNextTo (TC.NextTo n) {
752                    printNode (n);
753                    indent += 2;
754                    super.forNextTo (n);
755                    indent -= 2;
756                    return null;
757                }
758                public Object forTrim (TC.Trim n) {
759                    printNode (n);
760                    indent += 2;
761                    super.forTrim (n);
762                    indent -= 2;
763                    return null;
764                }
765                public Object forInclude (TC.Include n) {
766                    printNode (n);
767                    indent += 2;
768                    super.forInclude (n);
769                    indent -= 2;
770                    return null;
771                }
772                public Object forSeq (TC.Seq n) {
773                    printNode (n);
774                    indent += 2;
775                    super.forSeq (n);
776                    indent -= 2;
777                    return null;
778                }
779                public Object forFromTo (TC.FromTo n) {
780                    printNode (n);
781                    indent += 2;
782                    super.forFromTo (n);
783                    indent -= 2;
784                    return null;
785                }
786                public Object forBalancedBinary (TC.BalancedBinary n) {
787                    printNode (n);
788                    indent += 2;
789                    super.forBalancedBinary (n);
790                    indent -= 2;
791                    return null;
792                }
793                public Object forIgnoreBinary (TC.IgnoreBinary n) {
794                    printNode (n);
795                    indent += 2;
796                    super.forIgnoreBinary (n);
797                    indent -= 2;
798                    return null;
799                }
800                public Object forAssign (TC.Assign n) {
801                    printNode (n);
802                    indent += 2;
803                    super.forAssign (n);
804                    indent -= 2;
805                    return null;
806                }
807                public Object forOrButNot (TC.OrButNot n) {
808                    printNode (n);
809                    indent += 2;
810                    super.forOrButNot (n);
811                    indent -= 2;
812                    return null;
813                }
814                public Object forNth (TC.Nth n) {
815                    printNode (n);
816                    indent += 2;
817                    super.forNth (n);
818                    indent -= 2;
819                    return null;
820                }
821                public Object forPrefix (TC.Prefix n) {
822                    printNode (n);
823                    indent += 2;
824                    super.forPrefix (n);
825                    indent -= 2;
826                    return null;
827                }
828                public Object forCaseSensitivity (TC.CaseSensitivity n) {
829                    printNode (n);
830                    indent += 2;
831                    super.forCaseSensitivity (n);
832                    indent -= 2;
833                    return null;
834                }
835                public Object forView (TC.View n) {
836                    printNode (n);
837                    indent += 2;
838                    super.forView (n);
839                    indent -= 2;
840                    return null;
841                }
842                public Object forUnbind (TC.Unbind n) {
843                    printNode (n);
844                    indent += 2;
845                    super.forUnbind (n);
846                    indent -= 2;
847                    return null;
848                }
849                    
850            });
851            out.flush ();
852        }
853    
854    
855        //
856        // Node types
857        //
858        public abstract static class Node implements Serializable {
859            public abstract Object accept (Visitor visitor);
860            public String toString () {
861                return Str.after (getClass ().getName (), "$");
862            }
863        }
864    
865        // 
866        // Primitive terms
867        //
868        public static class Constant extends Node {
869            NamedRegionSet sel;
870            public Constant (NamedRegionSet sel) {
871                this.sel = sel;
872            }
873            public Constant (Document doc, RegionSet regions) {
874                //this.sel = new NamedRegionSet (doc, regions);
875                            this.sel = new NamedRegionSet (regions);
876            }
877            public NamedRegionSet getSelection () {
878                return sel;
879            }
880            public Object accept (Visitor v) {
881                return v.forConstant (this);
882            }
883        }
884        public static class ExternalPattern extends Node {
885            Pattern pat;
886            public ExternalPattern (Pattern pat) {
887                this.pat = pat;
888            }
889            public Pattern getPattern () {
890                return pat;
891            }
892            public Object accept (Visitor v) {
893                return v.forExternalPattern (this);
894            }
895        }
896        public static class Literal extends Node {
897            String literal;
898            public Literal (String s) {
899                literal = s;
900            }
901            public String getString () {
902                return literal;
903            }
904            public Object accept (Visitor v) {
905                return v.forLiteral (this);
906            }
907            public String toString () {
908                return "\"" + literal + "\"";
909            }
910        }
911        public static class Regexp extends Node {
912            String regexp;
913            public Regexp (String s) {
914                regexp = s;
915            }
916            public String getString () {
917                return regexp;
918            }
919            public Object accept (Visitor v) {
920                return v.forRegexp (this);
921            }
922            public String toString () {
923                return "/" + regexp + "/";
924            }
925        }
926        public static class Id extends Node {
927            String id;
928            transient TCToken tok;
929            public Id (String s) {
930                id = s;
931            }
932            public Id (String s, TCToken tok) {
933                id = s;
934                this.tok = tok;
935            }
936            public String getString () {
937                return id;
938            }
939            public TCToken getToken () {
940                return tok;
941            }
942            public Object accept (Visitor v) {
943                return v.forId (this);
944            }
945            public String toString () {
946                return id;
947            }
948        }
949        public static class Any extends Node {
950            public Any () {
951            }
952            public Object accept (Visitor v) {
953                return v.forAny (this);
954            }
955        }
956        public static class Nothing extends Node {
957            public Nothing () {
958            }
959            public Object accept (Visitor v) {
960                return v.forNothing (this);
961            }
962        }
963    
964        //
965        // Unary operators
966        //
967        abstract static class UnaryOp extends Node {
968            Node arg;
969            public UnaryOp (Node arg) {
970                this.arg = arg;
971            }
972            public Node getArg () {
973                return arg;
974            }
975        }
976        public static class Equals extends UnaryOp {
977            public Equals (Node arg) {
978                super (arg);
979            }
980            public Object accept (Visitor v) {
981                return v.forEquals (this);
982            }
983        }
984        public static class Before extends UnaryOp {
985            public Before (Node arg) {
986                super (arg);
987            }
988            public Object accept (Visitor v) {
989                return v.forBefore (this);
990            }
991        }
992        public static class After extends UnaryOp {
993            public After (Node arg) {
994                super (arg);
995            }
996            public Object accept (Visitor v) {
997                return v.forAfter (this);
998            }
999        }
1000        public static class JustBefore extends UnaryOp {
1001            public JustBefore (Node arg) {
1002                super (arg);
1003            }
1004            public Object accept (Visitor v) {
1005                return v.forJustBefore (this);
1006            }
1007        }
1008        public static class JustAfter extends UnaryOp {
1009            public JustAfter (Node arg) {
1010                super (arg);
1011            }
1012            public Object accept (Visitor v) {
1013                return v.forJustAfter (this);
1014            }
1015        }
1016        public static class BeforeDelimited extends UnaryOp {
1017            public BeforeDelimited (Node arg) {
1018                super (arg);
1019            }
1020            public Object accept (Visitor v) {
1021                return v.forBeforeDelimited (this);
1022            }
1023        }
1024        public static class AfterDelimited extends UnaryOp {
1025            public AfterDelimited (Node arg) {
1026                super (arg);
1027            }
1028            public Object accept (Visitor v) {
1029                return v.forAfterDelimited (this);
1030            }
1031        }
1032        public static class JustBeforeDelimited extends UnaryOp {
1033            public JustBeforeDelimited (Node arg) {
1034                super (arg);
1035            }
1036            public Object accept (Visitor v) {
1037                return v.forJustBeforeDelimited (this);
1038            }
1039        }
1040        public static class JustAfterDelimited extends UnaryOp {
1041            public JustAfterDelimited (Node arg) {
1042                super (arg);
1043            }
1044            public Object accept (Visitor v) {
1045                return v.forJustAfterDelimited (this);
1046            }
1047        }
1048        public static class In extends UnaryOp {
1049            public In (Node arg) {
1050                super (arg);
1051            }
1052            public Object accept (Visitor v) {
1053                return v.forIn (this);
1054            }
1055        }
1056        public static class Contains extends UnaryOp {
1057            public Contains (Node arg) {
1058                super (arg);
1059            }
1060            public Object accept (Visitor v) {
1061                return v.forContains (this);
1062            }
1063        }
1064    
1065        public static class Descendant extends UnaryOp {
1066            public Descendant (Node arg) {
1067                super (arg);
1068            }
1069            public Object accept (Visitor v) {
1070                return v.forDescendant (this);
1071            }
1072        }
1073        public static class Ancestor extends UnaryOp {
1074            public Ancestor (Node arg) {
1075                super (arg);
1076            }
1077            public Object accept (Visitor v) {
1078                return v.forAncestor (this);
1079            }
1080        }
1081    
1082        public static class Starting extends UnaryOp {
1083            public Starting (Node arg) {
1084                super (arg);
1085            }
1086            public Object accept (Visitor v) {
1087                return v.forStarting (this);
1088            }
1089        }
1090        public static class Ending extends UnaryOp {
1091            public Ending (Node arg) {
1092                super (arg);
1093            }
1094            public Object accept (Visitor v) {
1095                return v.forEnding (this);
1096            }
1097        }
1098        public static class StartingDelimited extends UnaryOp {
1099            public StartingDelimited (Node arg) {
1100                super (arg);
1101            }
1102            public Object accept (Visitor v) {
1103                return v.forStartingDelimited (this);
1104            }
1105        }
1106        public static class EndingDelimited extends UnaryOp {
1107            public EndingDelimited (Node arg) {
1108                super (arg);
1109            }
1110            public Object accept (Visitor v) {
1111                return v.forEndingDelimited (this);
1112            }
1113        }
1114        public static class OverlapsStart extends UnaryOp {
1115            public OverlapsStart (Node arg) {
1116                super (arg);
1117            }
1118            public Object accept (Visitor v) {
1119                return v.forOverlapsStart (this);
1120            }
1121        }
1122        public static class OverlapsEnd extends UnaryOp {
1123            public OverlapsEnd (Node arg) {
1124                super (arg);
1125            }
1126            public Object accept (Visitor v) {
1127                return v.forOverlapsEnd (this);
1128            }
1129        }
1130        public static class Overlaps extends UnaryOp {
1131            public Overlaps (Node arg) {
1132                super (arg);
1133            }
1134            public Object accept (Visitor v) {
1135                return v.forOverlaps (this);
1136            }
1137        }
1138        public static class SeparatedBy extends UnaryOp {
1139            public SeparatedBy (Node arg) {
1140                super (arg);
1141            }
1142            public Object accept (Visitor v) {
1143                return v.forSeparatedBy (this);
1144            }
1145        }
1146        public static class StartOf extends UnaryOp {
1147            public StartOf (Node arg) {
1148                super (arg);
1149            }
1150            public Object accept (Visitor v) {
1151                return v.forStartOf (this);
1152            }
1153        }
1154        public static class EndOf extends UnaryOp {
1155            public EndOf (Node arg) {
1156                super (arg);
1157            }
1158            public Object accept (Visitor v) {
1159                return v.forEndOf (this);
1160            }
1161        }
1162        public static class BalancedUnary extends UnaryOp {
1163            public BalancedUnary (Node arg) {
1164                super (arg);
1165            }
1166            public Object accept (Visitor v) {
1167                return v.forBalancedUnary (this);
1168            }
1169        }
1170        public static class Flatten extends UnaryOp {
1171            public Flatten (Node arg) {
1172                super (arg);
1173            }
1174            public Object accept (Visitor v) {
1175                return v.forFlatten (this);
1176            }
1177        }
1178        public static class Unbind extends UnaryOp {
1179            public Unbind (Node arg) {
1180                super (arg);
1181            }
1182            public Object accept (Visitor v) {
1183                return v.forUnbind (this);
1184            }
1185        }
1186        public static class Melt extends UnaryOp {
1187            public Melt (Node arg) {
1188                super (arg);
1189            }
1190            public Object accept (Visitor v) {
1191                return v.forMelt (this);
1192            }
1193        }
1194        public static class Crispen extends UnaryOp {
1195            public Crispen (Node arg) {
1196                super (arg);
1197            }
1198            public Object accept (Visitor v) {
1199                return v.forCrispen (this);
1200            }
1201        }
1202        public static class Nonempty extends UnaryOp {
1203            public Nonempty (Node arg) {
1204                super (arg);
1205            }
1206            public Object accept (Visitor v) {
1207                return v.forNonempty (this);
1208            }
1209        }
1210    
1211        //
1212        // Binary operators
1213        //
1214        abstract static class BinaryOp extends Node {
1215            Node arg1;
1216            Node arg2;
1217            public BinaryOp (Node arg1, Node arg2) {
1218                this.arg1 = arg1;
1219                this.arg2 = arg2;
1220            }
1221            public Node getArg1 () {
1222                return arg1;
1223            }
1224            public Node getArg2 () {
1225                return arg2;
1226            }
1227        }
1228    
1229        public static class And extends BinaryOp {
1230            public And (Node arg1, Node arg2) {
1231                super (arg1, arg2);
1232            }
1233            public Object accept (Visitor v) {
1234                return v.forAnd (this);
1235            }
1236        }
1237        public static class Or extends BinaryOp {
1238            public Or (Node arg1, Node arg2) {
1239                super (arg1, arg2);
1240            }
1241            public Object accept (Visitor v) {
1242                return v.forOr (this);
1243            }
1244    
1245        }
1246        public static class ButNot extends BinaryOp {
1247            public ButNot (Node arg1, Node arg2) {
1248                super (arg1, arg2);
1249            }
1250            public Object accept (Visitor v) {
1251                return v.forButNot (this);
1252            }
1253        }
1254        public static class NextTo extends BinaryOp {
1255            public NextTo (Node arg1, Node arg2) {
1256                super (arg1, arg2);
1257            }
1258            public Object accept (Visitor v) {
1259                return v.forNextTo (this);
1260            }
1261        }
1262        public static class Trim extends BinaryOp {
1263            public Trim (Node arg1, Node arg2) {
1264                super (arg1, arg2);
1265            }
1266            public Object accept (Visitor v) {
1267                return v.forTrim (this);
1268            }
1269        }
1270        public static class Include extends BinaryOp {
1271            public Include (Node arg1, Node arg2) {
1272                super (arg1, arg2);
1273            }
1274            public Object accept (Visitor v) {
1275                return v.forInclude (this);
1276            }
1277        }
1278        public static class Seq extends BinaryOp {
1279            public Seq (Node arg1, Node arg2) {
1280                super (arg1, arg2);
1281            }
1282            public Object accept (Visitor v) {
1283                return v.forSeq (this);
1284            }
1285        }
1286        public static class FromTo extends BinaryOp {
1287            public FromTo (Node arg1, Node arg2) {
1288                super (arg1, arg2);
1289            }
1290            public Object accept (Visitor v) {
1291                return v.forFromTo (this);
1292            }
1293        }
1294        public static class BalancedBinary extends BinaryOp {
1295            public BalancedBinary (Node arg1, Node arg2) {
1296                super (arg1, arg2);
1297            }
1298            public Object accept (Visitor v) {
1299                return v.forBalancedBinary (this);
1300            }
1301        }
1302        public static class IgnoreBinary extends BinaryOp {
1303            public IgnoreBinary (Node arg1, Node arg2) {
1304                super (arg1, arg2);
1305            }
1306            public Object accept (Visitor v) {
1307                return v.forIgnoreBinary (this);
1308            }
1309        }
1310    
1311    
1312        // 
1313        // Other operators
1314        //
1315        public static class Assign extends Node {
1316            String id;
1317            Node arg;
1318            public Assign (String s, Node arg) {
1319                this.arg = arg;
1320                id = s;
1321            }
1322            public Node getArg () {
1323                return arg;
1324            }
1325            public String getString () {
1326                return id;
1327            }
1328            public Object accept (Visitor v) {
1329                return v.forAssign (this);
1330            }
1331    
1332            public String toString () {
1333                return id + " = ";
1334            }
1335    
1336    
1337        }
1338        public static class Nth extends Node {
1339            int n;
1340            Node counter;
1341            Node context;
1342            public Nth (int n, Node counter, Node context) {
1343                this.n = n;
1344                this.counter = counter;
1345                this.context = context;
1346            }
1347            public int getCount () {
1348                return n;
1349            }
1350            public Node getCounter () {
1351                return counter;
1352            }
1353            public Node getContext () {
1354                return context;
1355            }
1356            public Object accept (Visitor v) {
1357                return v.forNth (this);
1358            }
1359    
1360            public String toString () {
1361                return super.toString () + " " + n;
1362            }
1363        }
1364        public static class OrButNot extends Node {
1365            Node arg1;
1366            Node arg2;
1367            Node arg3;
1368            public OrButNot (Node arg1, Node arg2, Node arg3) {
1369                this.arg1 = arg1;
1370                this.arg2 = arg2;
1371                this.arg3 = arg3;
1372            }
1373            public Node getArg1 () {
1374                return arg1;
1375            }
1376            public Node getArg2 () {
1377                return arg2;
1378            }
1379            public Node getArg3 () {
1380                return arg3;
1381            }
1382            public Object accept (Visitor v) {
1383                return v.forOrButNot (this);
1384            }
1385        }
1386        public static class Prefix extends Node {
1387            String prefix;
1388            Node arg;
1389            public Prefix (String prefix, Node arg) {
1390                this.prefix = prefix;
1391                this.arg = arg;
1392            }
1393            public String getPrefix () {
1394                return prefix;
1395            }
1396            public Node getArg () {
1397                return arg;
1398            }
1399            public Object accept (Visitor v) {
1400                return v.forPrefix (this);
1401            }
1402            public String toString () {
1403                return super.toString () + " " + prefix;
1404            }
1405        }
1406        public static class CaseSensitivity extends Node {
1407            boolean enabled;
1408            Node arg;
1409            public CaseSensitivity (boolean enabled, Node arg) {
1410                this.enabled = enabled;
1411                this.arg = arg;
1412            }
1413            public boolean getCaseSensitive () {
1414                return enabled;
1415            }
1416            public Node getArg () {
1417                return arg;
1418            }
1419            public Object accept (Visitor v) {
1420                return v.forCaseSensitivity (this);
1421            }
1422            public String toString () {
1423                return super.toString () + " " + enabled;
1424            }
1425        }
1426        public static class View extends Node {
1427            String view;
1428            Node arg;
1429            public View (String view, Node arg) {
1430                this.view = view;
1431                this.arg = arg;
1432            }
1433            public String getView () {
1434                return view;
1435            }
1436            public Node getArg () {
1437                return arg;
1438            }
1439            public Object accept (Visitor v) {
1440                return v.forView (this);
1441            }
1442            public String toString () {
1443                return super.toString () + " " + view;
1444            }
1445        }
1446    
1447    
1448        //
1449        // Converting to related patterns
1450        //
1451        
1452        public TC getPointPattern () {
1453            return new TC ((Node) root.accept (POINT_CONVERTER));
1454        }
1455        
1456        static final Visitor POINT_CONVERTER = new Cloner () {
1457            public Object forBefore (TC.Before n) {
1458                return new TC.StartOf (n.getArg ());
1459            }
1460            public Object forAfter (TC.After n) {
1461                return new TC.EndOf (n.getArg ());
1462            }
1463            public Object forJustBefore (TC.JustBefore n) {
1464                return new TC.StartOf (n.getArg ());
1465            }
1466            public Object forJustAfter (TC.JustAfter n) {
1467                return new TC.EndOf (n.getArg ());
1468            }
1469            public Object forBeforeDelimited (TC.BeforeDelimited n) {
1470                return new TC.StartOf (n.getArg ());
1471            }
1472            public Object forAfterDelimited (TC.AfterDelimited n) {
1473                return new TC.EndOf (n.getArg ());
1474            }
1475            public Object forJustBeforeDelimited (TC.JustBeforeDelimited n) {
1476                return new TC.StartOf (n.getArg ());
1477            }
1478            public Object forJustAfterDelimited (TC.JustAfterDelimited n) {
1479                return new TC.EndOf (n.getArg ());
1480            }
1481            public Object forStarting (TC.Starting n) {
1482                return new TC.StartOf (n.getArg ());
1483            }
1484            public Object forEnding (TC.Ending n) {
1485                return new TC.EndOf (n.getArg ());
1486            }
1487            public Object forStartingDelimited (TC.StartingDelimited n) {
1488                return new TC.StartOf (n.getArg ());
1489            }
1490            public Object forEndingDelimited (TC.EndingDelimited n) {
1491                return new TC.EndOf (n.getArg ());
1492            }
1493        };
1494    
1495    
1496        public TC getUniversePattern () {
1497            return new TC ((Node) root.accept (UNIVERSE_CONVERTER));
1498        }
1499    
1500        static final Visitor UNIVERSE_CONVERTER = new Cloner () {
1501            public Object forAnd (TC.And n) {
1502                return n.getArg1 ().accept (this);
1503            }
1504            //public Object forOr (TC.Or n);
1505            public Object forButNot (TC.ButNot n) {
1506                return n.getArg1 ().accept (this);
1507            }
1508            public Object forOrButNot (TC.OrButNot n) {
1509                return n.getArg1 ().accept (this);
1510            }
1511            public Object forEquals (TC.Equals n) {
1512                return n.getArg ().accept (this);
1513            }
1514            public Object forBefore (TC.Before n) {
1515                return n;
1516            }
1517            public Object forAfter (TC.After n) {
1518                return n;
1519            }
1520            public Object forJustBefore (TC.JustBefore n) {
1521                return n;
1522            }
1523            public Object forJustAfter (TC.JustAfter n) {
1524                return n;
1525            }
1526            public Object forBeforeDelimited (TC.BeforeDelimited n) {
1527                return n;
1528            }
1529            public Object forAfterDelimited (TC.AfterDelimited n) {
1530                return n;
1531            }
1532            public Object forJustBeforeDelimited (TC.JustBeforeDelimited n) {
1533                return n;
1534            }
1535            public Object forJustAfterDelimited (TC.JustAfterDelimited n) {
1536                return n;
1537            }
1538            public Object forIn (TC.In n) {
1539                return n;
1540            }
1541            public Object forContains (TC.Contains n) {
1542                return n;
1543            }
1544    
1545            public Object forDescendant (TC.Descendant n) {
1546                return n;
1547            }
1548            public Object forAncestor (TC.Ancestor n) {
1549                return n;
1550            }
1551    
1552            public Object forStarting (TC.Starting n) {
1553                return n;
1554            }
1555            public Object forEnding (TC.Ending n) {
1556                return n;
1557            }
1558            public Object forStartingDelimited (TC.StartingDelimited n) {
1559                return n;
1560            }
1561            public Object forEndingDelimited (TC.EndingDelimited n) {
1562                return n;
1563            }
1564            public Object forOverlapsStart (TC.OverlapsStart n) {
1565                return n;
1566            }
1567            public Object forOverlapsEnd (TC.OverlapsEnd n) {
1568                return n;
1569            }
1570            public Object forOverlaps (TC.Overlaps n) {
1571                return n;
1572            }
1573            public Object forSeparatedBy (TC.SeparatedBy n) {
1574                return n;
1575            }
1576            public Object forStartOf (TC.StartOf n) {
1577                return n;
1578            }
1579            public Object forEndOf (TC.EndOf n) {
1580                return n;
1581            }
1582            public Object forBalancedUnary (TC.BalancedUnary n) {
1583                return n;
1584            }
1585            public Object forBalancedBinary (TC.BalancedBinary n){
1586                return n;
1587            }
1588            public Object forFromTo (TC.FromTo n){
1589                return n;
1590            }
1591            //public Object forConstant (TC.Constant n);
1592            //public Object forExternalPattern (TC.ExternalPattern n);
1593            //public Object forLiteral (TC.Literal n);
1594            //public Object forRegexp (TC.Regexp n);
1595            //public Object forId (TC.Id n);
1596            //public Object forAny (TC.Any n);
1597            //public Object forNothing (TC.Nothing n);
1598            public Object forNextTo (TC.NextTo n) {
1599                return n;
1600            }
1601            public Object forTrim (TC.Trim n) {
1602                return n;
1603            }
1604            public Object forInclude (TC.Include n) {
1605                return n;
1606            }
1607            public Object forAssign (TC.Assign n) {
1608                return n;
1609            }
1610            public Object forSeq (TC.Seq n) {
1611                return n.getArg2 ().accept (this);
1612            }
1613            //public Object forIgnoreBinary (TC.IgnoreBinary n);
1614            public Object forNth (TC.Nth n){
1615                return n.getCounter ().accept (this);
1616            }
1617            public Object forFlatten (TC.Flatten n) {
1618                return n;
1619            }
1620            public Object forUnbind (TC.Unbind n) {
1621                return n;
1622            }
1623            public Object forMelt (TC.Melt n) {
1624                return n;
1625            }
1626            public Object forCrispen (TC.Crispen n) {
1627                return n;
1628            }
1629            public Object forNonempty (TC.Nonempty n) {
1630                return n;
1631            }
1632        };
1633    
1634    
1635    
1636        public TC getObjectPattern () {
1637            return new TC ((Node) root.accept (OBJECT_CONVERTER));
1638        }
1639    
1640        static final Visitor OBJECT_CONVERTER = new Cloner () {
1641            public Object forAnd (TC.And n) {
1642                return n.getArg1 ().accept (this);
1643            }
1644            //public Object forOr (TC.Or n);
1645            public Object forButNot (TC.ButNot n) {
1646                return n.getArg1 ().accept (this);
1647            }
1648            public Object forOrButNot (TC.OrButNot n) {
1649                return n.getArg1 ().accept (this);
1650            }
1651            public Object forEquals (TC.Equals n) {
1652                return n.getArg ().accept (this);
1653            }
1654            public Object forBefore (TC.Before n) {
1655                return n.getArg ().accept (this);
1656            }
1657            public Object forAfter (TC.After n) {
1658                return n.getArg ().accept (this);
1659            }
1660            public Object forJustBefore (TC.JustBefore n) {
1661                return n.getArg ().accept (this);
1662            }
1663            public Object forJustAfter (TC.JustAfter n) {
1664                return n.getArg ().accept (this);
1665            }
1666            public Object forBeforeDelimited (TC.BeforeDelimited n) {
1667                return n.getArg ().accept (this);
1668            }
1669            public Object forAfterDelimited (TC.AfterDelimited n) {
1670                return n.getArg ().accept (this);
1671            }
1672            public Object forJustBeforeDelimited (TC.JustBeforeDelimited n) {
1673                return n.getArg ().accept (this);
1674            }
1675            public Object forJustAfterDelimited (TC.JustAfterDelimited n) {
1676                return n.getArg ().accept (this);
1677            }
1678            public Object forIn (TC.In n) {
1679                return n.getArg ().accept (this);
1680            }
1681            public Object forContains (TC.Contains n) {
1682                return n.getArg ().accept (this);
1683            }
1684    
1685            public Object forDescendant (TC.Descendant n) {
1686                return n.getArg ().accept (this);
1687            }
1688            public Object forAncestor (TC.Ancestor n) {
1689                return n.getArg ().accept (this);
1690            }
1691    
1692            public Object forStarting (TC.Starting n) {
1693                return n.getArg ().accept (this);
1694            }
1695            public Object forEnding (TC.Ending n) {
1696                return n.getArg ().accept (this);
1697            }
1698            public Object forStartingDelimited (TC.StartingDelimited n) {
1699                return n.getArg ().accept (this);
1700            }
1701            public Object forEndingDelimited (TC.EndingDelimited n) {
1702                return n.getArg ().accept (this);
1703            }
1704            public Object forOverlapsStart (TC.OverlapsStart n) {
1705                return n.getArg ().accept (this);
1706            }
1707            public Object forOverlapsEnd (TC.OverlapsEnd n) {
1708                return n.getArg ().accept (this);
1709            }
1710            public Object forOverlaps (TC.Overlaps n) {
1711                return n.getArg ().accept (this);
1712            }
1713            public Object forSeparatedBy (TC.SeparatedBy n) {
1714                return n.getArg ().accept (this);
1715            }
1716            public Object forStartOf (TC.StartOf n) {
1717                return n.getArg ().accept (this);
1718            }
1719            public Object forEndOf (TC.EndOf n) {
1720                return n.getArg ().accept (this);
1721            }
1722            public Object forBalancedUnary (TC.BalancedUnary n) {
1723                return n;
1724            }
1725            public Object forBalancedBinary (TC.BalancedBinary n){
1726                return n;
1727            }
1728            public Object forFromTo (TC.FromTo n){
1729                return n;
1730            }
1731            //public Object forConstant (TC.Constant n);
1732            //public Object forExternalPattern (TC.ExternalPattern n);
1733            //public Object forLiteral (TC.Literal n);
1734            //public Object forRegexp (TC.Regexp n);
1735            //public Object forId (TC.Id n);
1736            //public Object forAny (TC.Any n);
1737            //public Object forNothing (TC.Nothing n);
1738            public Object forNextTo (TC.NextTo n) {
1739                return n;
1740            }
1741            public Object forTrim (TC.Trim n) {
1742                return n;
1743            }
1744            public Object forInclude (TC.Include n) {
1745                return n;
1746            }
1747            public Object forAssign (TC.Assign n) {
1748                return n;
1749            }
1750            public Object forSeq (TC.Seq n) {
1751                return n.getArg2 ().accept (this);
1752            }
1753            //public Object forIgnoreBinary (TC.IgnoreBinary n);
1754            public Object forNth (TC.Nth n){
1755                return n.getCounter ().accept (this);
1756            }
1757            public Object forFlatten (TC.Flatten n) {
1758                return n;
1759            }
1760            public Object forUnbind (TC.Unbind n) {
1761                return n;
1762            }
1763            public Object forMelt (TC.Melt n) {
1764                return n;
1765            }
1766            public Object forCrispen (TC.Crispen n) {
1767                return n;
1768            }
1769            public Object forNonempty (TC.Nonempty n) {
1770                return n;
1771            }
1772        };
1773    
1774    
1775    }