所以我为专有文件类型编写了一个解析器。我在那里 95%,但我的解析器在文件的最后一行失败,即#
. 这是其他几个解析器的部分匹配。看起来它试图将行解析为 PropertyList 并失败,从而导致整个解析器失败。
我能做些什么来解决这个问题?
mcve 如下,Fiddle 在这里https://dotnetfiddle.net/f30sN9
using System;
using Superpower;
using Superpower.Model;
using Superpower.Parsers;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var result1 = TagTXTParser.firstLine.TryParse(sampleFirstLine);
Console.WriteLine(result1);
var result2 = TagTXTParser.propertyList.TryParse(samplePropertyList);
Console.WriteLine(result2);
var result8 = TagTXTParser.record.TryParse(sampleRecord);
Console.WriteLine(result8);
var result9 = TagTXTParser.TagRecordsFileParser.TryParse(sampleFile);
Console.WriteLine(result9);
}
public static string sampleFirstLine = "// 895.34 - Tags\n";
public static string sampleSectionHeading = "#Parameters\n";
public static string sampleItemList = "<[0]>|1|0|0|0|0|0.000000|0.000000|0.000000| | | |\n";
public static string samplePropertyList = "#4|NavDisabled|0|1| | |0|0| |\n";
public static string sampleSection1 = "#Parameters\n<[0] >| 1 | 0 | 0 | 0 | 0 | 0.000000 | 0.000000 | 0.000000 | | | | \n";
public static string sampleSection2 = "#Parameters\n<[0] >| 1 | 0 | 0 | 0 | 0 | 0.000000 | 0.000000 | 0.000000 | | | | \n<[1] >| 1 | 0 | 0 | 0 | 0 | 0.000000 | 0.000000 | 0.000000 | | | | \n";
public static string sampleSection3 = "#Parameters\n";
public static string sampleRecord = "#3|ScreenNumber|0|1| | |1|0| |\n#Parameters\n<[0] >| 1 | 0 | 0 | 0 | 0 | 0.000000 | 0.000000 | 0.000000 | | | |\n#Alarm\n#History\n#ItemParameters\n<[0] >| 1 | 1 | \n";
public static string sampleFile =
@"// 8.10 - Application Tags
#1|SelectedWindowOnNavBar|0|1| | |1|0| |
#Parameters
<[0]>|1|0|0|0|0|0.000000|0.000000|0.000000| | | |
#Alarm
#History
#ItemParameters
<[0]>|1|1|
#2|ScreenName|0|3| | |1|0| |
#Parameters
<[0]>|1|0|0|0|0|0.000000|0.000000|0.000000| | | |
#Alarm
#History
#ItemParameters
<[0]>|1|1|
#3|ScreenNumber|0|1| | |1|0| |
#Parameters
<[0]>|1|0|0|0|0|0.000000|0.000000|0.000000| | | |
#Alarm
#History
#ItemParameters
<[0]>|1|1|
#4|NavDisabled|0|1| | |0|0| |
#Parameters
<[0]>|1|0|0|0|0|0.000000|0.000000|0.000000| | | |
#Alarm
#History
#ItemParameters
<[0]>|1|1|
#5|PLC_1_IPAddress|0|3| | |1|0| |
#Parameters
<[0]>|1|1|0|0|0|0.000000|0.000000|0.000000| | | |
#Alarm
#History
#ItemParameters
<[0]>|1|1|
#6|NumOfMeters|0|3| | |1|0| |
#Parameters
<[0]>|1|1|0|0|0|0.000000|0.000000|0.000000| | | |
#Alarm
#History
#ItemParameters
<[0]>|1|1|
#7|ComputerName|0|3| | |1|0| |
#Parameters
<[0]>|1|0|0|0|0|0.000000|0.000000|0.000000| | | |
#Alarm
#History
#ItemParameters
<[0]>|1|1|
#8|TZPosition|0|1| | |0|0| |
#Parameters
<[0]>|1|0|0|0|0|0.000000|0.000000|0.000000| | | |
#Alarm
#History
#ItemParameters
<[0]>|1|1|
#9|NewTime|0|3| | |1|0| |
#Parameters
<[0]>|1|0|0|0|0|0.000000|0.000000|0.000000| | | |
#Alarm
#History
#ItemParameters
<[0]>|1|1|
#";
}
public class TagTXTParser
{
public record TagProperies(int Id, string Name, List<string> others);
public record TagRecordSection(List<string>[] items);
public class TagRecord
{
public int Id { get; set; } //** first element of First line
public string Name { get; set; }
public List<string> Properties { get; set; }
public TagRecordSection Parameters { get; set; }
public TagRecordSection Alarm { get; set; }
public TagRecordSection History { get; set; }
public TagRecordSection ItemParameters { get; set; }
}
public static TextParser<char> hash = Character.EqualTo('#');
public static TextParser<TextSpan> eol = Span.EqualTo('\n').Or(Span.EqualTo("\r\n"));
public static TextParser<char> pipe = Character.EqualTo('|');
public static TextParser<string> text = Character.ExceptIn('#', '|', '\n', '\r').Many().Select(x => new string(x));
public static TextParser<string> firstLine = from _ in Span.EqualTo("//")
from rest in text
from end in eol
select new string(rest.ToCharArray());
public static TextParser<char[]> heading =
from h in hash
from name in Character.Letter.AtLeastOnce()
from end in eol
select name;
public static TextParser<List<string>> itemList = //from _ in eol
from items in text.ManyDelimitedBy<string, char>(pipe)
from end in eol
select new List<string>(items);
public static TextParser<TagProperies> propertyList =
from _ in hash
from id in Character.Digit.AtLeastOnce()
from endOfId in pipe
from name in text
from endOfName in pipe
from otherItems in itemList
select new TagProperies(Convert.ToInt32(new string(id)), name, otherItems);
public static TextParser<TagRecordSection> section =
from _ in heading
from items in itemList.Many()
select new TagRecordSection(items);
public static TextParser<TagRecord> record =
from props in propertyList
from sections in section.Repeat(4)
select new TagRecord()
{
Id = props.Id,
Name = props.Name,
Properties = props.others,
Parameters = sections[0],
Alarm = sections[1],
History = sections[2],
ItemParameters = sections[3]
};
public static TextParser<TagRecord[]> TagRecordsFileParser =
from _ in firstLine
from records in record.Many()
from end in hash
select records;
}