.net 使用Superpower解析列表列表
我想解析以如下格式表示的图书馆书籍:.net 使用Superpower解析列表列表,.net,parsing,superpower,.net,Parsing,Superpower,我想解析以如下格式表示的图书馆书籍: #Book title 1 Chapter 1 Chapter 2 #Book title 2 Chapter 1 Chapter 2 Chapter 3 正如您所看到的,《靴子》的标题前面有一行,每本书的章节如下。为此创建解析器应该相当容易 到目前为止,我有以下代码解析器+标记器: void Main() { var tokenizer = new TokenizerBuilder<PrjToken>()
#Book title 1
Chapter 1
Chapter 2
#Book title 2
Chapter 1
Chapter 2
Chapter 3
正如您所看到的,《靴子》的标题前面有一行,每本书的章节如下。为此创建解析器应该相当容易
到目前为止,我有以下代码解析器+标记器:
void Main()
{
var tokenizer = new TokenizerBuilder<PrjToken>()
.Match(Superpower.Parsers.Character.EqualTo('#'), PrjToken.Hash)
.Match(Span.Regex("[^\r\n#:=-]*"), PrjToken.Text)
.Match(Span.WhiteSpace, PrjToken.WhiteSpace)
.Build();
var input = @"#Book 1
Chapter 1
Chapter 2
#Book 2
Chapter 1
Chapter 2
Chapter 3";
var library = MyParsers.Library.Parse(tokenizer.Tokenize(input));
}
public enum PrjToken
{
WhiteSpace,
Hash,
Text
}
public class Book
{
public string Title { get; }
public string[] Chapters { get; }
public Book(string title, string[] chapters)
{
Title = title;
Chapters = chapters;
}
}
public class Library
{
public Book[] Books { get; }
public Library(Book[] books)
{
Books = books;
}
}
public class MyParsers
{
public static readonly TokenListParser<PrjToken, string> Text = from text in Token.EqualTo(PrjToken.Text)
select text.ToStringValue();
public static readonly TokenListParser<PrjToken, Superpower.Model.Token<PrjToken>> Whitespace = from text in Token.EqualTo(PrjToken.WhiteSpace)
select text;
public static readonly TokenListParser<PrjToken, string> Title =
from hash in Token.EqualTo(PrjToken.Hash)
from text in Text
from wh in Whitespace
select text;
public static readonly TokenListParser<PrjToken, Book> Book =
from title in Title
from chapters in Text.ManyDelimitedBy(Whitespace)
select new Book(title, chapters);
public static readonly TokenListParser<PrjToken, Library> Library =
from books in Book.ManyDelimitedBy(Whitespace)
select new Library(books);
}
上面的代码已准备好在.NET FIDLE中运行此链接
一切看起来都很好。但是,解析器有问题,因为我遇到了以下错误:
语法错误第4行第1列:意外哈希,预期文本
我的解析器出了什么问题?您可以通过将章节解析为一个单独的列表来解决这个问题,其中每个章节都以空格字符结尾:
public static readonly TokenListParser<PrjToken, string> Chapter =
from chapterName in Text
from wh in Whitespace
select chapterName;
public static readonly TokenListParser<PrjToken, Book> Book =
from title in Title
from chapters in Chapter.Many()
select new Book(title, chapters);
除此之外,如果希望解析文件时不在文件末尾添加换行符,还必须将章节末尾的空白设置为可选:
public static readonly TokenListParser<PrjToken, string> Chapter =
from chapterName in Text
from wh in Whitespace.Optional()
select chapterName;
最后,我们得到了完整的解析器:
public class MyParsers
{
public static readonly TokenListParser<PrjToken, string> Text = from text in Token.EqualTo(PrjToken.Text)
select text.ToStringValue();
public static readonly TokenListParser<PrjToken, Superpower.Model.Token<PrjToken>> Whitespace = from text in Token.EqualTo(PrjToken.WhiteSpace)
select text;
public static readonly TokenListParser<PrjToken, string> Title =
from hash in Token.EqualTo(PrjToken.Hash)
from text in Text
from wh in Whitespace
select text;
public static readonly TokenListParser<PrjToken, string> Chapter =
from chapterName in Text
from wh in Whitespace.Optional()
select chapterName;
public static readonly TokenListParser<PrjToken, Book> Book =
from title in Title
from chapters in Chapter.Many()
select new Book(title, chapters);
public static readonly TokenListParser<PrjToken, Library> Library =
from books in Book.Many()
select new Library(books);
}
我已经根据你的建议修改了代码,但它只解析了第一本书。请你复习一下好吗?提前谢谢!这是修改后的版本:请检查输出。它只解析第一本书:
public class MyParsers
{
public static readonly TokenListParser<PrjToken, string> Text = from text in Token.EqualTo(PrjToken.Text)
select text.ToStringValue();
public static readonly TokenListParser<PrjToken, Superpower.Model.Token<PrjToken>> Whitespace = from text in Token.EqualTo(PrjToken.WhiteSpace)
select text;
public static readonly TokenListParser<PrjToken, string> Title =
from hash in Token.EqualTo(PrjToken.Hash)
from text in Text
from wh in Whitespace
select text;
public static readonly TokenListParser<PrjToken, string> Chapter =
from chapterName in Text
from wh in Whitespace.Optional()
select chapterName;
public static readonly TokenListParser<PrjToken, Book> Book =
from title in Title
from chapters in Chapter.Many()
select new Book(title, chapters);
public static readonly TokenListParser<PrjToken, Library> Library =
from books in Book.Many()
select new Library(books);
}