using System;
using System.Collections.Generic;
using System.Text;
using DNAModule.Sunweaver.Commands.Abstracts;
using DNAModule.Sunweaver.DataPrototypes;
using DNAModule.Sunweaver.MetaTags;
using DNAModule.Sunweaver;
using Sunweaver;
using System.IO;
namespace DNAModule.Sunweaver
{
public static class Parser
{
///
/// Trys to convert word into a label using a DNA's custom
/// label list, as well as sysvars
///
///
///
///
public static bool ParseLabel(string word, DNA dna, ref int ParsedInteger)
{
word = word.ToLower();
//TODO: check against sysvars when that is implemented
if (DNASystem.Sysvar.Contains(word))
{
ParsedInteger = DNASystem.Sysvar[word];
return true;
}
if (dna == null || dna.PersonalConstants == null)
return false;
if (!dna.PersonalConstants.ContainsKey(word))
return false;
ParsedInteger = dna.PersonalConstants[word];
return true;
}
public static bool TryParseLabel(string word, DNA dna, ref int val)
{
return DNAModule.Sunweaver.Parser.ParseLabel(word, dna, ref val);
}
public static BasePair ParseBasePair(string word, DNA dna)
{
word = word.ToLower();
if (char.IsPunctuation(word[0]))
return DNASystem.PunctuationsList[word, dna];
if (char.IsNumber(word[0]))
return new Commands.Constant(word);
int value = 0;
if(TryParseLabel(word, dna, ref value))
{
return new Commands.Label(word, value);
}
return DNASystem.CommandList[word];
}
public static List ParseCodule(string[] commands, DNA dna)
{
List Final = new List();
foreach (string word in commands)
{
if(word != "")
Final.Add(ParseBasePair(word.Trim(), dna));
}
return Final;
}
///
/// Parses the line if it's a proper metatag line
///
/// Line should be predelineated into words
/// Returns if the parse was successful
///
public static bool ParseMetaTag(string[] line, DNA Returnme)
{
try
{
MetaTag tag = DNASystem.MetaTagList[line];
tag.Implement(Returnme);
}
catch
{
return false;
}
return true;
}
///
/// Parses a line as either a metatag definition,
/// or sends it to the codule parser if it's unrecognized.
///
///
///
/// True if this line is a metatag, false if it's
/// something else (like regular base pairs)
public static bool ParseLine(string line, DNA Returnme)
{
//Crop comments
if(line.Contains("'"))
line = line.Substring(0, line.IndexOf('\''));
string[] SplitLine = line.Split(" \t".ToCharArray());
//Early out when line is empty
if (SplitLine[0].Length == 0)
return true;
//Try to parse SplitLine as a MetaTag
try
{
MetaTag tag = DNASystem.MetaTagList[SplitLine];
tag.Implement(Returnme);
return true;
}
catch //Failing that, pass on to ParseCodule
{
Chromosome Current = Returnme.Chromosomes[Returnme.Chromosomes.Count - 1];
Current.Codules[Current.Codules.Count - 1].BasePairs.AddRange(ParseCodule(SplitLine, Returnme));
return false;
}
}
public static DNA ParseDNA(string DNAFile)
{
DNA Returnme = new DNA();
Returnme.Chromosomes.Add(new Chromosome(Returnme));
foreach (string line in DNAFile.Split("\n\r".ToCharArray()))
{
ParseLine(line, Returnme);
}
return Returnme;
}
public static DNA ParseDNAFile(string fileName)
{
return ParseDNA(File.ReadAllText(fileName));
}
}
}