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    }