/* * xtc - The eXTensible Compiler * Copyright (C) 2004, 2006 Robert Grimm * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ package xtc.parser; import java.util.ArrayList; import java.util.List; import xtc.util.State; /** * Parser state for parsing <i>Rats!</i> grammars. Note that * this class supports only a single state-modifying transaction. In * other words, calls to {@link #start()}, {@link #commit()}, and * {@link #abort()} cannot be nested within each other. * * @author Robert Grimm * @version $Revision: 1.5 $ */ public class PParserState implements State { /** The current indentation level. */ private int level; /** The list of indentation levels. */ private List<Integer> indent; /** * The flag for whether we have seen anything besides spaces on the * current line. */ private boolean content; /** Create a new packrat parser state object. */ public PParserState() { reset(null); } public void reset(String file) { level = -1; indent = null; } public void start() { level = 0; indent = new ArrayList<Integer>(); indent.add(level); content = false; } public void commit() { level = -1; } public void abort() { level = -1; } /** Record an opening brace. */ public void open() { if (-1 < level) level++; } /** Record any character besides spaces. */ public void content() { if (-1 < level) content = true; } /** Record a newline. */ public void newline() { if (-1 < level) { indent.add(level); content = false; } } /** Record a closing brace. */ public void close() { if (0 < level) { // If the closing brace appears at the beginning of the current // line (disregarding spaces), we need to also decrement the // last captured indentation level. if (! content) { final int idx = indent.size() - 1; final int value = indent.get(idx) - 1; indent.set(idx, value); } level--; } } /** * Retrieve the list of indentation levels. The list contains one * entry per invocation of {@link #newline()} since the last * invocation of {@link #start()}. * * @return The list of indentation levels. */ public List<Integer> indentations() { return indent; } }