Source code: jpicedt/graphic/io/parser/TerminalExpression.java
1 /* jPicEdt version 1.3.2, a picture editor for LaTeX.
2 Copyright (C) 1999-2002 Sylvain Reynal
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 Sylvain Reynal
19 Département de Physique
20 Ecole Nationale Supérieure de l'Electronique et de ses Applications (ENSEA)
21 6, avenue du Ponceau
22 95014 CERGY CEDEX
23 FRANCE
24
25 Tel : 00 +33 130 736 245
26 Fax : 00 +33 130 736 667
27 e-mail : reynal@ensea.fr
28 jPicEdt web page : http://www.jpicedt.org
29 */
30
31 package jpicedt.graphic.io.parser;
32
33 import java.util.*;
34
35 /**
36 * This expression works a bit like a "CR-greedy" expression : it scans each line until
37 * it can successfully parse the reg-exp given in the constructor, POSSIBLY preceded by wild-chars (as
38 * given in the construror). <p>
39 * Say we create a <code>new TerminalExpression(new LiteralExpression("%End Line")>/code> (as in
40 * <code>picedt.PicLineExpression</code>. Then this expression will drop every line (whatever it may contain)
41 * until it finds "^(\s)*%End Line". Hence the type of WildCharExpression specified in the constructor
42 * is solely used when parsing the beginning of each line
43 * [pending] : would "CRGreedyExpression" be a more appropriate name ?
44 */
45 public class TerminalExpression extends AbstractRegularExpression {
46
47 private AbstractRegularExpression expr, wildExpr;
48 private String leadingStr = new String();
49
50 /**
51 * Calls TerminalExpression(expr, WHITESPACES) => "expr" can only be preceded by whitespaces
52 */
53 public TerminalExpression(AbstractRegularExpression expr){
54
55 this(expr, Character.SPACE_SEPARATOR);
56 }
57
58 /**
59 * @param type The character type that can precede the expression to be matched.
60 * (see WildCharExpression for details about the meaning of "type")
61 * Use EOL if you want this expression to start at the beginning of a line
62 * @param expr The expression to be searched for
63 */
64 public TerminalExpression(AbstractRegularExpression expr, int type){
65
66 this.expr = expr;
67 wildExpr = new WildCharExpression(type);
68 }
69
70 /**
71 * Either :
72 * - swallow CR's on empty line,
73 * - or try to match the given expression,
74 * - or try to swallow the given wildchars.
75 *
76 * @return TRUE in any case, else throw an exception (@EOF) ; (this means that exception throwing is
77 * the only way to get out of the infinite loop...)
78 * in case of success, call action() with value=leading String
79 * @throws ParserException.NotFoundInFile if EOF was reached before this expression could be found
80 */
81 public boolean interpret(Context c) throws ParserException {
82
83 while(true){
84 String s = c.getRemainingSubstring();
85 if (s==null) throw new ParserException.NotFoundInFile(c, expr); //EOF=>stop here
86 // EOL ? then swallow CR's :
87 if (s.length()==0){
88 if (!c.lineFeed()) throw new ParserException.NotFoundInFile(c, expr); // do a CR if possible
89 leadingStr += s+ "\n"; // update leading string
90 continue; // grab subsequent line
91 }
92 // OK, then there are still chars on this line :
93 // either try to find the expression to be matched (and exit if success) :
94 if (expr.interpret(c)) {
95 action(new ParserEvent(this, c, true, leadingStr));
96 return true;
97 }
98 // or try to "swallow" a wildchar (type of which is given in the constructor) :
99 if (wildExpr.interpret(c)) continue;
100
101 // otherwise, let's drop the current line (whatever it may contain!), and try to go to the next line :
102 if (!c.lineFeed()) throw new ParserException.NotFoundInFile(c, expr);
103
104 // update leading string with current substring (this gonna be the "value" of the ParserEvent sent on success)
105 leadingStr += s+ "\n";
106 }
107 }
108
109 /**
110 *
111 */
112 public String toString(){
113
114 return "[TerminalExpression:" + expr + "]";
115 }
116 }