001 package com.saelist.stx.parser;
002
003 import java.util.*;
004 import org.apache.log4j.*;
005 import com.saelist.stx.*;
006
007 /**
008
009 Parses free form structured text.<p>
010 <pre>
011 PAIR = TEXT [ LBR PAIR * RBR ].
012 </pre>
013
014 */
015 public class StxParser {
016
017 static int subpos;
018 public static Logger logger = Logger.getLogger(StxParser.class);
019
020 /** @param text the text to parse. */
021 public static Pair parse(String text) throws ParserException {
022 List tokens = Tokenizer.tokenize(text);
023 tokens = Tokenizer.assemble(tokens);
024 if(tokens.isEmpty())
025 throw new ParserException(ParserException.EXPECTED_TEXT);
026 Pair pair = parsePair(null, tokens, 0);
027 if(subpos < tokens.size() - 1)
028 throw new ParserException(ParserException.EXTRA_CHARS_AT_END, (Token) tokens.get(subpos));
029 return pair;
030 }
031
032
033 /** A pair that remembers its location in the source file.
034 */
035 public static Pair parsePair(Pair parent, List tokens, int pos) throws ParserException {
036
037 logger.debug("parsePair(): pos=" + pos + " " + tokens.get(pos));
038
039 Token token = (Token) tokens.get(pos);
040 int type = token.getType();
041
042 if(type != Token.SQ && type != Token.DQ && type != Token.TEXT) {
043 throw new ParserException(ParserException.EXPECTED_TEXT, token);
044 }
045
046 Pair pair = new Pair(parent, token.getValue());
047 // pair.setToken(token);
048 pos++;
049 subpos = pos;
050
051 if(pos < tokens.size() && ((Token) tokens.get(pos)).getType() == Token.LBR) {
052 List pairs = parsePairList(pair, tokens, pos);
053 for(Iterator it = pairs.iterator(); it.hasNext(); )
054 pair.add((Pair) it.next());
055 pos = subpos;
056 }
057
058 return pair;
059 }
060
061 private static List parsePairList(Pair parent, List tokens, int pos) throws ParserException {
062
063 // logger.debug("parsePairList(): pos=" + pos + " " + tokens.get(pos));
064
065 List pairs = new ArrayList();
066
067 pos ++; // skip the LBR.
068
069 while(pos < tokens.size()) {
070 Token token = (Token) tokens.get(pos);
071 int type = token.getType();
072
073 if(type == Token.RBR) {
074 subpos = ++pos;
075 return pairs;
076 } else {
077 Pair pair = parsePair(parent, tokens, pos);
078 pairs.add(pair);
079 pos = subpos;
080 }
081 }
082 throw new ParserException(ParserException.EOF_EXPECTING_LBR);
083 }
084
085
086
087 }