001/*
002 * Copyright (C) 2009-2011 Mathias Doenitz
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.parboiled.parserunners;
018
019import org.parboiled.MatchHandler;
020import org.parboiled.MatcherContext;
021import org.parboiled.Rule;
022import org.parboiled.buffers.DefaultInputBuffer;
023import org.parboiled.buffers.InputBuffer;
024import org.parboiled.errors.ParseError;
025import org.parboiled.matchers.Matcher;
026import org.parboiled.support.DefaultValueStack;
027import org.parboiled.support.ParsingResult;
028import org.parboiled.support.ValueStack;
029import org.parboiled.matchers.Matcher;
030import org.parboiled.support.DefaultValueStack;
031import org.parboiled.support.ParsingResult;
032import org.parboiled.support.ValueStack;
033
034import java.util.ArrayList;
035import java.util.List;
036
037import static org.parboiled.common.Preconditions.checkArgNotNull;
038
039public abstract class AbstractParseRunner<V> implements ParseRunner<V> {
040    private final Matcher rootMatcher;
041    private List<ParseError> parseErrors;
042    private ValueStack<V> valueStack;
043    private Object initialValueStackSnapshot;
044
045    public AbstractParseRunner(Rule rule) {
046        this.rootMatcher = checkArgNotNull((Matcher) rule, "rule");
047    }
048
049    public Matcher getRootMatcher() {
050        return rootMatcher;
051    }
052
053    public ParseRunner<V> withParseErrors(List<ParseError> parseErrors) {
054        this.parseErrors = parseErrors;
055        return this;
056    }
057
058    public List<ParseError> getParseErrors() {
059        if (parseErrors == null) {
060            withParseErrors(new ArrayList<ParseError>());
061        }
062        return parseErrors;
063    }
064
065    public ParseRunner<V>withValueStack(ValueStack<V> valueStack) {
066        this.valueStack = checkArgNotNull(valueStack, "valueStack");
067        this.initialValueStackSnapshot = valueStack.takeSnapshot();
068        return this;
069    }
070
071    public ValueStack<V> getValueStack() {
072        if (valueStack == null) {
073            withValueStack(new DefaultValueStack<V>());
074        }
075        return valueStack;
076    }    
077
078    public ParsingResult<V> run(String input) {
079        checkArgNotNull(input, "input");
080        return run(input.toCharArray());
081    }
082
083    public ParsingResult<V> run(char[] input) {
084        checkArgNotNull(input, "input");
085        return run(new DefaultInputBuffer(input));
086    }
087
088    protected void resetValueStack() {
089        getValueStack().restoreSnapshot(initialValueStackSnapshot);
090    }
091
092    protected MatcherContext<V> createRootContext(InputBuffer inputBuffer, MatchHandler matchHandler,
093                                                     boolean fastStringMatching) {
094        return new MatcherContext<V>(inputBuffer, getValueStack(), getParseErrors(), matchHandler, rootMatcher,
095                fastStringMatching);
096    }
097    
098    protected ParsingResult<V> createParsingResult(boolean matched, MatcherContext<V> rootContext) {
099        return new ParsingResult<V>(matched, rootContext.getNode(), getValueStack(), getParseErrors(),
100                rootContext.getInputBuffer());
101    }
102}