/*
 *  This file is part of ALTER.
 *
 *  ALTER is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  ALTER 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with ALTER.  If not, see <http://www.gnu.org/licenses/>.
 */

options
{
  STATIC = false;
}

PARSER_BEGIN(GdeParser)

package es.uvigo.ei.sing.alter.parser;

import es.uvigo.ei.sing.alter.types.Gde;
import es.uvigo.ei.sing.alter.types.GdeSequence;
import java.io.StringReader;
import java.util.Vector;

/**
* GDE format parser.
* @author Daniel Gomez Blanco
* @version 1.2
*/
public class GdeParser
{
  /**
  * Static method that parses an input string and returns a MSA in GDE format.
  * @param in Input string.
  * @return MSA in GDE format.
  */
  public static Gde parseMSA (String in) throws ParseException
    {
        //Parse string and return MSA
        GdeParser parser = new GdeParser(new StringReader(in));
        return parser.Gde();
    }
}

PARSER_END(GdeParser)

TOKEN :
{
    <EOL: "\n" | "\r" | "\r\n" > |
    <BLANK: " " | "\t" > |
    <UPPER_CASE: ["A"-"Z"] > |
    <LOWER_CASE: ["a"-"z"] > |
    <NUMBER: ["0"-"9"] > |
    <ANY: ~["\r","\n"," ","\t","A"-"Z","a"-"z","0"-"9","#","%","-",".","?"] >

}

/**
* Grammar's root production. Structure:<br>
* &nbsp;&nbsp;1. Any combinations of spaces, tabs and new lines until "#" or "%".<br>
* &nbsp;&nbsp;2. Sequences with the following format:<br>
* &nbsp;&nbsp;&nbsp;&nbsp;2a. "#" ó "%".<br>
* &nbsp;&nbsp;&nbsp;&nbsp;2b. Sequence identifier.<br>
* &nbsp;&nbsp;&nbsp;&nbsp;2c. New line.<br>
* &nbsp;&nbsp;&nbsp;&nbsp;2d. Sequence data.<br>
* @return MSA in GDE format.
*/
Gde Gde():
{
    Vector<GdeSequence> seqs = new Vector<GdeSequence>();
    String id, data;
}
{
    (<EOL> | <BLANK>)*
    (
        ("#" | "%") id = Line() <EOL> data = Data()
        {
            seqs.add(new GdeSequence(id,data));
        }
    )+
    <EOF>
    {
        return new Gde(seqs);
    }
}

/**
* Parses a line made up of any character sequence.
* @return Parsed line.
*/
String Line():
{
    StringBuffer s = new StringBuffer();
    Token t;
}
{
    (
        (t = <BLANK> | t = <UPPER_CASE> | t = <LOWER_CASE> | t = <NUMBER> |
        t = <ANY> | t = "-" | t = "#" | t = "%" | t = "." | t = "?" )
        {
            s.append(t.image);
        }
    )+
    {
        return s.toString().trim();
    }
}

/**
* Parses sequence data. These data can be made up of any characters
* from "A" to "Z" (lowercase and uppercase), "-", "." or "?".
* Spaces, tabs and new lines are omitted.
* @return String with the sequence data (uppercase always).
*/
String Data():
{
    StringBuffer s = new StringBuffer();
    Token t;
}
{
    (
        (t = <BLANK> | t = <EOL>)
        |
        (
            (t = <UPPER_CASE> | t = <LOWER_CASE> | t = "-" | t = "." | t = "?" )
            {
                s.append(t.image);
            }
        )
    )+
    {
        return s.toString().toUpperCase();
    }
}