// Parses a single outfil configuration. private LegacyOutputFile ParseOutfil(Lexer lexer) { LegacyOutputFile outputFile = null; if (lexer.MoveNext()) { outputFile = new LegacyOutputFile(); string outrec = null; string include = null; string omit = null; while (lexer.Current != null) { // Look for the supported commands if (string.Equals(Outrec, lexer.Current, StringComparison.InvariantCultureIgnoreCase)) { lexer.MoveNext(); outrec = ParseCommandParameters(lexer); } else if (string.Equals(Include, lexer.Current, StringComparison.InvariantCultureIgnoreCase)) { lexer.MoveNext(); include = ParseCommandParameters(lexer); } else if (string.Equals(Omit, lexer.Current, StringComparison.InvariantCultureIgnoreCase)) { lexer.MoveNext(); omit = ParseCommandParameters(lexer); } else if (lexer.Current != SemiColon) { throw new ParsingException(string.Format("Unexpected token at index {0}: {1}", lexer.Index, lexer.Current)); } else { break; } } // Set the required properties of the output file if (!string.IsNullOrEmpty(outrec)) { var formatterParser = new FormatterParser { Encoding = Encoding }; outputFile.Formatter = formatterParser.GetFormatter(outrec); } if (!string.IsNullOrWhiteSpace(include) || !string.IsNullOrWhiteSpace(omit)) { var filterParser = new FilterParser { Encoding = Encoding, SortEncoding = SortEncoding }; outputFile.Filter = filterParser.GetFilter(include, omit); } } return outputFile; }
public void TestLexer4() { string[] expected = { "(", "C", "'srchfor ''", "1", "7", "C", "'''", "80:X", ")" }; var lexer = new Lexer("(C'srchfor ''',1,7,C'''',80:X)"); var results = new List<string>(); while (lexer.MoveNext()) { results.Add(lexer.Current); } Assert.IsTrue(results.SequenceEqual(expected)); }
public void TestLexer3() { string[] expected = { "1", "25", "A", "26", "10", "ZD", "D" }; var lexer = new Lexer("1,25,A,26,10,ZD,D"); var results = new List<string>(); while (lexer.MoveNext()) { results.Add(lexer.Current); } Assert.IsTrue(results.SequenceEqual(expected)); }
/// <summary> /// Gets a formatter from its configuration card. /// </summary> /// <param name="configuration">a formatter configuration card</param> /// <returns>the corresponding <see cref="LegacyFormatter"/></returns> public LegacyFormatter GetFormatter(string configuration) { var lexer = new Lexer(configuration); IList <ISubFormatter> formatters = null; if (lexer.MoveNext()) { var parentheses = lexer.Current == OpeningPar; if (parentheses) { lexer.MoveNext(); } formatters = ParseSubFormatters(lexer); if (parentheses) { lexer.Parse(ClosingPar); } } return(new LegacyFormatter { Formatters = formatters, Encoding = Encoding }); }
/// <summary> /// Parses an <see cref="IFilter{T}"/>. /// </summary> /// <param name="lexer">the lexer to read the tokens from</param> /// <param name="defaultFormat">the default format</param> /// <returns>an <see cref="IFilter{T}"/></returns> private IFilter <byte[]> ParseFilter(Lexer lexer, string defaultFormat) { IFilter <byte[]> filter = null; if (lexer.MoveNext()) { if (lexer.Current == OpeningPar) { filter = ParseFilter(lexer, defaultFormat); lexer.Parse(ClosingPar); } else { string format1; string format2; var leftAccessor = ParseAccessor(lexer, defaultFormat, out format1); var op = lexer.Parse(); var rightAccessor = ParseAccessor(lexer, defaultFormat, out format2); var format = format1 ?? format2; filter = GetFilter(leftAccessor, rightAccessor, format, op); } if (lexer.Current == Or) { var disjunction = new DisjunctionFilter <byte[]> { Filters = new List <IFilter <byte[]> > { filter, ParseFilter(lexer, defaultFormat) } }; filter = disjunction; } else if (lexer.Current == And) { var conjunction = new ConjunctionFilter <byte[]> { Filters = new List <IFilter <byte[]> > { filter, ParseFilter(lexer, defaultFormat) } }; filter = conjunction; } } return(filter); }
// Retrieves the parameter of a command so that it can be parsed by a specific parser. private static string ParseCommandParameters(Lexer lexer) { var start = lexer.Index; lexer.Parse(OpeningPar); while (lexer.MoveNext() && lexer.Current != ClosingPar) { } var length = lexer.Index - start - 1; lexer.Parse(ClosingPar); return(lexer.SubString(start, length)); }
/// <summary> /// Parse all the individual comparers and combine them in a <see cref="ComparerChain{T}"/>. /// </summary> /// <param name="lexer">the lexer to read the tokens from</param> /// <param name="defaultFormat">the default format</param> /// <returns> /// a single <see cref="IComparer{T}"/> if there is only one comparer, or a <see cref="ComparerChain{T}"/> /// if there are more than one comparer. /// </returns> private IComparer <byte[]> ParseComparers(Lexer lexer, string defaultFormat) { IList <IComparer <byte[]> > comparers = new List <IComparer <byte[]> >(); do { comparers.Add(ParseComparer(lexer, defaultFormat)); } while (lexer.MoveNext() && lexer.Current != ClosingPar); if (comparers.Count == 0) { return(null); } return(comparers.Count > 1 ? new ComparerChain <byte[]> { Comparers = comparers } : comparers[0]); }
// Retrieves the parameter of a command so that it can be parsed by a specific parser. private static string ParseCommandParameters(Lexer lexer) { var start = lexer.Index; lexer.Parse(OpeningPar); while (lexer.MoveNext() && lexer.Current != ClosingPar) { } var length = lexer.Index - start - 1; lexer.Parse(ClosingPar); return lexer.SubString(start, length); }
/// <summary> /// Parses an accessor. /// </summary> /// <param name="lexer">the lexer to read the tokens from</param> /// <param name="defaultFormat">the default format</param> /// <param name="format">the format of the parsed accessor</param> /// <returns>an <see cref="IAccessor{T}"/></returns> private object ParseAccessor(Lexer lexer, string defaultFormat, out string format) { var elements = new List<string>(); format = null; do { elements.Add(lexer.Current); } while (lexer.MoveNext() && lexer.Current != ClosingPar && !LogicalOperators.Contains(lexer.Current) && !ComparisonOperators.Contains(lexer.Current)); if (elements.Count == 1) { // decimal constant return new ConstantAccessor<decimal> { Constant = decimal.Parse(elements[0]) }; } if (elements.Count == 2 && elements[0] == "C") { // string constant var constant = elements[1].Substring(1, elements[1].Length - 2); return new ConstantAccessor<string> { Constant = constant }; } if (elements.Count == 2 && elements[0] == "X") { // HexaDecimal constant var constant = elements[1].Substring(1, elements[1].Length - 2); BinaryAccessor accessor = new BinaryAccessor (); int value = Convert.ToInt32(constant, 16); byte[] bytes = Enumerable.Range(0, constant.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(constant.Substring(x, 2), 16)).ToArray(); accessor.SetBytes(bytes, bytes, 0); decimal constant1 = Convert.ToInt32(constant, 16); return new ConstantAccessor<decimal> { Constant = constant1 }; } // field accesor var start = int.Parse(elements[0]) - 1; var length = int.Parse(elements[1]); format = elements.Count == 3 ? elements[2] : defaultFormat; return GetAccessor(start, length, format, Encoding); }
/// <summary> /// Parses an <see cref="IFilter{T}"/>. /// </summary> /// <param name="lexer">the lexer to read the tokens from</param> /// <param name="defaultFormat">the default format</param> /// <returns>an <see cref="IFilter{T}"/></returns> private IFilter<byte[]> ParseFilter(Lexer lexer, string defaultFormat) { IFilter<byte[]> filter = null; if (lexer.MoveNext()) { if (lexer.Current == OpeningPar) { filter = ParseFilter(lexer, defaultFormat); lexer.Parse(ClosingPar); } else { string format1; string format2; var leftAccessor = ParseAccessor(lexer, defaultFormat, out format1); var op = lexer.Parse(); var rightAccessor = ParseAccessor(lexer, defaultFormat, out format2); var format = format1 ?? format2; filter = GetFilter(leftAccessor, rightAccessor, format, op); } if (lexer.Current == Or) { var disjunction = new DisjunctionFilter<byte[]> { Filters = new List<IFilter<byte[]>> { filter, ParseFilter(lexer, defaultFormat) } }; filter = disjunction; } else if (lexer.Current == And) { var conjunction = new ConjunctionFilter<byte[]> { Filters = new List<IFilter<byte[]>> { filter, ParseFilter(lexer, defaultFormat) } }; filter = conjunction; } } return filter; }
/// <summary> /// Parses an accessor. /// </summary> /// <param name="lexer">the lexer to read the tokens from</param> /// <param name="defaultFormat">the default format</param> /// <param name="format">the format of the parsed accessor</param> /// <returns>an <see cref="IAccessor{T}"/></returns> private object ParseAccessor(Lexer lexer, string defaultFormat, out string format) { var elements = new List<string>(); format = null; do { elements.Add(lexer.Current); } while (lexer.MoveNext() && lexer.Current != ClosingPar && !LogicalOperators.Contains(lexer.Current) && !ComparisonOperators.Contains(lexer.Current)); if (elements.Count == 1) { // decimal constant return new ConstantAccessor<decimal> { Constant = decimal.Parse(elements[0]) }; } if (elements.Count == 2 && elements[0] == "C") { // string constant var constant = elements[1].Substring(1, elements[1].Length - 2); return new ConstantAccessor<string> { Constant = constant }; } // field accesor var start = int.Parse(elements[0]) - 1; var length = int.Parse(elements[1]); format = elements.Count == 3 ? elements[2] : defaultFormat; return GetAccessor(start, length, format, Encoding); }
/// <summary> /// Parse all the individual comparers and combine them in a <see cref="ComparerChain{T}"/>. /// </summary> /// <param name="lexer">the lexer to read the tokens from</param> /// <param name="defaultFormat">the default format</param> /// <returns> /// a single <see cref="IComparer{T}"/> if there is only one comparer, or a <see cref="ComparerChain{T}"/> /// if there are more than one comparer. /// </returns> private IComparer<byte[]> ParseComparers(Lexer lexer, string defaultFormat) { IList<IComparer<byte[]>> comparers = new List<IComparer<byte[]>>(); do { comparers.Add(ParseComparer(lexer, defaultFormat)); } while (lexer.MoveNext() && lexer.Current != ClosingPar); if (comparers.Count == 0) { return null; } return comparers.Count > 1 ? new ComparerChain<byte[]> { Comparers = comparers } : comparers[0]; }
/// <summary> /// Parses a numeric edit formatter. /// </summary> /// <param name="start">the index of the first byte to read in the input record</param> /// <param name="length">the length of the column to read in the input record</param> /// <param name="outputIndex">the index in the output record for the sub-formatter</param> /// <param name="lexer">the lexer to read the tokens from</param> /// <returns>the parsed <see cref="NumericEditFormatter"/></returns> private NumericEditFormatter ParseEditFormatter(int start, int length, int outputIndex, Lexer lexer) { var format = lexer.Parse(); var pattern = lexer.Parse(); string edit; string positiveSign = DefaultPositiveSign; string negativeSign = DefaultNegativeSign; if (pattern == "EDIT=") { var sb = new StringBuilder(); lexer.Parse(OpeningPar); do { sb.Append(",").Append(lexer.Current); } while (lexer.MoveNext() && lexer.Current != ClosingPar); edit = sb.ToString().Substring(1); lexer.Parse(ClosingPar); } else { var mask = Masks[pattern]; edit = mask.Pattern; positiveSign = mask.PositiveSign; negativeSign = mask.NegativeSign; } var editLength = edit.Length; while (IsPartOfEdit(lexer.Current)) { var element = lexer.Parse(); if (element.StartsWith(Length)) { editLength = int.Parse(element.Substring(Length.Length)); } else { lexer.Parse(OpeningPar); positiveSign = lexer.Parse(); if (lexer.Current == ClosingPar) { // We actually only have the negative sign negativeSign = positiveSign; positiveSign = DefaultPositiveSign; } else { negativeSign = lexer.Parse(); } lexer.Parse(ClosingPar); } } return(new NumericEditFormatter { Accessor = (IAccessor <decimal>)GetAccessor(start, length, format, Encoding), Edit = edit, Encoding = Encoding, Length = editLength, PositiveSign = positiveSign, NegativeSign = negativeSign, OutputIndex = outputIndex }); }