我正在构建一个简单的解析器,而我无法理解整体设计。什么是最佳做法?
解析器采用一个简单的文本文件并将其构建为HTML文件,这将大量使用嵌套列表,并为每个列表项添加索引和ID。
输入(为清晰起见,添加了缩进)。
A. First section with random name Article 1 Spam and eggs and some more Article 2 1. The first member 2. The second member 3. The final member B. Second section called whatever Article 3 This one has no members but it does contain subs a. item 1 b. item 2 Article 4 1. A member 2. A member with subs a. sub 1 here b. sub 2 here c. final sub C. Another section etc
我有正则表达式找到各种列表项,带行号(现在我正在使用词法分析器,但这可能是矫枉过正,对吧?)
正如我所说,我需要制作嵌套的HTML列表,每个列表项都有一个ID。根据您的经验,您将如何代表文档的结构?
作为一系列元组或词典,每个项目(id,行号):
list_section = ( ('A',1), ('B',8), ('C',18), ... )
list_article = ( ('1',2), ('2',4), ('3',9), ('4',13), ... )
list_member = ( ('2-1',5), ('2-2',6), ('2-3',7), ('4-1',14), ...)
etc
或者作为嵌套元组,其中每个标记都有(TYPE,id,line-number):
(('SECTION','A',1 ,
('ARTICLE','1',2),
('ARTICLE','2',4 ,
('MEMBER','2-1',5),
('MEMBER','2-2',6),
('MEMBER','2-3',7)
)
)
现在我倾向于第二种选择。第一个将更容易构建和迭代,但层次结构只能通过查看周围的行号来推断。
你会这样做,还是以完全不同的方式?我不是要求你写我的解析器或正则表达式,我只是在寻找关于最佳实践的声音建议。
我在HTML中添加了所需的输出。指数:
<div id="index">
<ol class="indexlist sections">
<li><a href="#listref_A">First section with random name</a><br>
Article 1 - 2</li>
<li><a href="#listref_B">Second section called whatever</a><br>
Artikel 3 - 4</li>
<li><a href="#listref_C">Another section</a><br>
Article 5</li>
</ol>
内容:
<div id="content">
<ol class="sections">
<li id="listref_D"><h2></h2>
<ol class="articles">
<li id="listref_8">Article 8
<ol class="members">
<li id="listref_8-1">Member 1.</li>
<li id="listref_8-2">Member 2</li>
<li id="listref_8-3">Member 3</li>
<li id="listref_8-4">Member 4.</li>
</ol>
</li>
</ol>
</li>
<li id="listref_E">Section E
<ol class="articles">
<li id="listref_9">Article 9
<ol class="members">
<li id="listref_9-1">Member 1 has subs:
<ol class="subs">
<li id="listref_9-1-a">sub a;</li>
<li id="listref_9-1-b">sub b;</li>
<li id="listref_9-1-c">sub c.</li>
</ol>
</li>
<li id="lijstref_9-2">Member 2, refers to <a href="#listref_8-2">article 8 sub 2</a>.</li>
</ol>
答案 0 :(得分:2)
尝试使用ANTLR Lexer / Parser组合。您只需要正则表达式来生成词法分析器/基本解析器组合。它使用类似于BNF语法的策略,您可以非常轻松地定义要打印到控制台或文件的操作。它默认输出Java,但ANTLR 4也输出到C#。 ANTLR 3可以输出多种语言,如Ruby。
要生成词法分析器的一部分,您可能会执行类似
的操作 // Define Tokens
WS : [ \t\r\n] ~> skip;
DOT : '.';
ARTICLE : 'Article';
fragment DIGIT : [0-9];
fragment ALPHA : [a-zA-Z];
AlphaString : ALPHA+;
Number : DIGIT+;
AlphaNumericString : (AlphaString | Number)+;
// Define Lexer and Parser Grammars
SectionTitle : AlphaString;
SectionHeader : SectionTitle DOT AlphaNumericString;
ArticleHeader : ARTICLE Number;
MemberTitle : Number;
MemberHeader : MemberTitle DOT AlphaNumericString;
submember : /*Code to define submember*/;
member : MemberHeader submember+;
article : ArticleHeader (member | AlphaNumericString)+;
section : SectionHeader
(article | AlphaNumericString)+;
显然这不是一个全面的语法,但它显示了基础知识。一个很好的参考是ANTLR 4 Documentation Wiki和ANTLR 4: The Defenitive Guide。这些将向您展示如何执行这些语法以及如何在其中嵌入操作。他们都是小型或大型项目的良好指南。后者的第2章和第3章以简单的方式展示了您需要的基础知识,并提供了很好的例子。