Package uk.co.badgersinfoil.metaas.impl.parser

Source Code of uk.co.badgersinfoil.metaas.impl.parser.E4XHelper

/*
* E4XHelper.java
*
* Copyright (c) 2006-2007 David Holroyd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package uk.co.badgersinfoil.metaas.impl.parser;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import org.antlr.runtime.ANTLRReaderStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.RecognitionException;
import org.asdt.core.internal.antlr.AS3Lexer;
import uk.co.badgersinfoil.metaas.impl.AS3FragmentParser;
import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListToken;
import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTokenSource;
import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTokenStream;
import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTreeAdaptor;
import uk.co.badgersinfoil.metaas.impl.parser.e4x.E4XParser;
import uk.co.badgersinfoil.metaas.impl.parser.e4x.E4XLexer;


public class E4XHelper {
  private static final LinkedListTreeAdaptor TREE_ADAPTOR = new LinkedListTreeAdaptor();

  /**
   * Creates a properly-configured parser object for the E4X grammar.
   */
  public static E4XParser parserOn(Reader in) throws IOException {
    ANTLRReaderStream cs = new ANTLRReaderStream(in);
    E4XLexer lexer = new E4XLexer(cs);
    LinkedListTokenSource source = new LinkedListTokenSource(lexer);
    LinkedListTokenStream stream = new LinkedListTokenStream(source);
    E4XParser parser = new E4XParser(stream);
    parser.setTreeAdaptor(TREE_ADAPTOR);
    parser.setInput(lexer, cs);
    return parser;
  }

  public static LinkedListTree parseXMLLiteral(AS3Lexer lexer, CharStream cs, LinkedListTokenStream stream) throws RecognitionException {
    String tail = cs.substring(cs.index(), cs.size()-1);
    int initialTailLength = tail.length();
    E4XParser parser;
    try {
      parser = e4xParserOn(new StringReader(tail), stream);
    } catch (IOException e) {
      // TODO: better exception type?
      throw new RuntimeException(e);
    }
    LinkedListTree ast = AS3FragmentParser.tree(parser.xmlPrimary());
    tail = parser.getInputTail();
    // skip over the XML in the original, underlying CharStream
    cs.seek(cs.index() + (initialTailLength - tail.length()));
    LinkedListTokenSource source = (LinkedListTokenSource)stream.getTokenSource();
    stream.setTokenSource(source)// cause any remembered E4X state to be dropped
    stream.scrub(1); // erase the subsequent token that the E4X parser got from this stream
    source.setDelegate(lexer);
    return ast;
  }

  private static E4XParser e4xParserOn(Reader in, LinkedListTokenStream stream) throws IOException {
    ANTLRReaderStream cs = new ANTLRReaderStream(in);
    E4XLexer lexer = new E4XLexer(cs);
    LinkedListTokenSource source = (LinkedListTokenSource)stream.getTokenSource();
    source.setDelegate(lexer);
   
    // The AS3 grammar will see the initial '<' as an LT (less-than)
    // token, and lookahead in the AS3Parser will have already
    // grabbed references to that token in order to make it the
    // startToken for various AST subtrees, so we can't just delete
    // it.  We therefore find the LT token and change its type to
    // match the E4X vocabulary, and then rewind the token stream
    // so that this will be the first token that the E4XParser will
    // see.
    LinkedListToken startMarker = (LinkedListToken)stream.LT(-1);
    startMarker.setType(E4XParser.XML_LCHEVRON);
    stream.seek(stream.index()-1);

    E4XParser parser = new E4XParser(stream);
    parser.setTreeAdaptor(new LinkedListTreeAdaptor());
    parser.setInput(lexer, cs);
    return parser;
  }

}
TOP

Related Classes of uk.co.badgersinfoil.metaas.impl.parser.E4XHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.