这个项目的诞生可以看作是一个小主意,它在2007年底访问了我,注定要在12年后找到其最终形式(当然,尽管笔者认为当前的实施情况非常令人满意) 。
一切始于在图书馆履行公务的过程中,我提请注意以下事实:可以明显简化将书籍(和音乐)出版物内容的扫描文本中的数据输入到现有数据库中的过程并使用输入所需的所有数据的有序性和可重复性的属性进行自动化,例如文章作者的姓名(如果我们正在谈论的是文章集),文章的名称(或目录中反映的字幕)以及 当前目录的页面。 最初,我几乎确信,可以在Internet上轻松找到适合此任务的系统。 当我因找不到这样的项目而感到意外时,我决定尝试自己实施。
在相当短的时间后,第一个原型开始工作,我立即在日常活动中开始使用该原型,同时使用所有示例将其调试。 幸运的是,在我平时从来都不是程序员的工作场所中,我仍然能够摆脱工作中可见的“停机时间”,在此期间,我努力工作以调试自己的才智,这在当今现实中几乎是不可想象的,这意味着每天的报告白天完成的工作。 完善程序的过程总共花费了不少于一年的时间,但是即使在那之后,结果也很难被认为是完全成功的-从一开始就有太多不同的概念难以理解:可以跳过可选元素; 元素的主导视图(目的是替换先前元素的搜索结果); 甚至您自己尝试实现诸如正则表达式之类的东西(具有独特的语法)。 我必须说,在此之前,我设法花了一点时间(大约8年,如果不是更长的话),所以有一个新的机会将我的技能运用到一项有趣且必要的任务上,这完全吸引了我的注意力。 毫不奇怪,所得到的源代码-在没有为我设计的任何明智方法的情况下-迅速变成了C语言中不同部分与某些C ++元素和可视化编程方面的不可思议的混合(最初决定使用例如Borland C ++ Builder的设计系统-“几乎是Delphi,但在C中”)。 但是,所有这些最终都在我们图书馆日常活动的自动化中获得了回报。
同时,为了以防万一,我决定为专业软件开发人员参加培训课程。 我不知道是否可以从头开始真正地向“程序员”学习,但是考虑到我当时已经具备的技能,我能够掌握一些更高级的技术,例如C#,Visual Studio以进行开发。 NET以及与Java,HTML和SQL相关的一些技术。 所有培训总共花费了两年时间,并且成为了我的另一个项目的起点,该项目最终持续了数年-但这已经是另一份出版物的主题。 在这里仅需要注意的是,我试图适应已经描述的项目中的经验,以在C#和WinForms中创建一个完整的窗口应用程序来实现必要的功能,并将其作为即将到来的毕业设计的基础。
随着时间的流逝,这种想法似乎值得在这样的年度会议上表达出来,在诸如LIBCOM和CRIMEA的各种图书馆的代表的参与下。 这个想法是肯定的,但绝不是我那个时候的实现。 然后,我还希望,除其他外,有人会使用更胜任的方法来重写它。 无论如何,我决定在2013年之前草拟一份关于我的初步工作的报告,并将其发送给会议组织委员会,并申请资助参加会议。 令我惊讶的是,我的应用程序感到满意,并且我开始对该项目进行一些改进,以准备在会议上演示。
到那时,该项目已经获得了一个新的名称BIRMA,并获得了各种额外的机会(未完全按预期实现)-
所有详细信息都可以在我的报告中找到 。
坦白说,2013年的BIRMA很难说完整。 坦白说,这是一条鞭子,制作工艺很怪异。 至于代码部分,除了为解析器创建某种统一语法的尝试外,几乎没有任何特殊的创新,这种外观在外观上类似于IRBIS 64格式语言(实际上甚至是ISIS,在循环结构中也带有括号;为什么?然后在我看来,它看起来非常酷)。 解析器从相应类型的括号中无意间偶然发现了这些漩涡(因为括号在此处起着相同的作用,即它们标记了可在解析过程中跳过的可选结构)。 每个想要更详细地了解当时难以想象的,不合理的BIRMA语法的人,我都会再次参考当时的报告。
总的来说,除了与我们自己的解析器的争执之外,就此版本的代码而言,我无话可说-除了C ++中可用源的反向转换以及保留.NET代码的某些典型功能(老实说,很难理解)。正是这促使我将所有内容都转移回去-可能是对将我的源代码保密的一种古怪的恐惧,好像这相当于可口可乐的秘密秘方一样。
也许这个愚蠢的决定也包含了将生成的DLL与现有的自制工作站接口配对以将数据输入电子目录时遇到困难的原因(是的,我没有提到另一个重要事实:从现在开始,所有BIRMA引擎代码都是如预期的那样,与接口分离并打包在适当的DLL中)。 您为什么需要为此目的编写一个单独的工作站,无论如何,无论其外观还是与用户进行交互的方式,都无耻地复制了IRBIS 64系统的同一“编录器”工作站-这是一个单独的问题。 简而言之:他对我当时的毕业设计成就给予了应有的尊重(否则仅靠难消化的解析器引擎是不够的)。 另外,在将“ Catalogizer”工作站与以C ++和C#实现的我自己的模块配对并直接寻址到我的引擎时,我遇到了一些困难。
总的来说,这很奇怪,但是未来BIRMA.NET的这个相当笨拙的原型注定会在未来四年成为我的“主力军”。 不能说,在这段时间里,我什至没有尝试寻找新方法,以更完整地实施一个长期存在的想法。 在其他创新中,应该已经有嵌套的循环序列,其中还可以包括可选元素-这就是我要实现的通用书架概念,用于出版物和其他有趣事物的书目描述。 但是,在我当时的实践中,对这一切的要求不高,并且我当时的实现足以介绍目录。 此外,我们图书馆发展方向的方向开始越来越偏离,将博物馆档案数字化,生成报告和其他我不感兴趣的活动,最终使我完全放弃了它,让那些本来会更满意的人让位于。
矛盾的是,但恰好在这些戏剧性事件发生之后,当时已经具有典型长期建设的所有特征的BIRMA项目似乎开始获得它期待已久的新生命! 我有更多的空闲时间来闲逛,我再次开始搜寻万维网,以寻找类似的东西(很好,现在我已经可以猜想从任何地方(即在GitHub上)以及在今年年初,我终于以不重要的名字
Gorp碰到了著名的Salesforce办公室的相应技术。 就其本身而言,它可以完成解析器引擎所需的几乎所有工作,即智能地将任意片段与任意片段分离,但具有清晰的文本结构,同时为最终用户提供一个易于消化的界面,包括实体作为一种模式,模式和出现方式,同时涉及到正则表达式的常规语法,由于分解为有意义的语义组进行分析,其可读性变得无与伦比。
通常,我决定使用相同的
Gorp (我想知道这个名称的含义吗?也许是某种“面向常规的常规解析器”?)正是我长期以来一直在寻找的东西。 没错,为满足我自己的需要而立即执行该问题,使得该引擎需要过于严格地遵守源文本的结构顺序。 对于某些报告,例如日志文件(即,它们由开发人员放置为项目使用的直观示例),此方法可以正常工作,但对于相同的文本,扫描的目录是不可能的。 毕竟,与目录相同的页面可以以“目录”,“目录”和其他一些初步描述开头,我们根本不需要这些提议来放入建议的分析结果(并且每次手动将它们剪掉也是不方便的)。 此外,在各个重复元素之间(例如作者的姓名,标题和页码),该页面可能包含一定数量的垃圾(例如图片和随机字符),也很容易被剪掉。 但是,最后一个方面仍然没有那么重要,但是借助第一个方面,现有的实现无法从某个特定位置开始在文本中查找必要的结构,而是仅仅从一开始就对其进行了处理,未在此处找到指定的模式并...完成你的工作。 显然,需要进行适当的修订,这将至少允许在重复的结构之间留出一些空隙,这使我再次坐下来工作。
另一个问题是该项目本身是用Java实现的,如果我计划进一步实现一些将该技术与将数据输入到现有数据库中的常用应用程序相连接的方法(例如Irbis编目器),那么至少至少在C#和.NET中可以做到。 并不是说Java本身就是一门糟糕的语言-我什至在Java上实现了一个无趣的窗口应用程序,该应用程序实现了家用可编程计算器的功能(作为课程项目的一部分)。 是的,并且在语法上与同一C-sharpe非常相似。 好吧,这只是一个优点:对我来说,完成一个现有项目越容易。 但是,我不想涉足窗口(或桌面)Java技术这个不寻常的世界-最后,该语言本身并没有为此应用“削尖”,而且我也没有重复任何先前的经验。 也许是因为C#与WinForms的结合更接近于Delphi,而我们很多人都曾经开始使用它。 幸运的是,通过
IKVM.NET项目,很快找到了正确的解决方案,这很容易将现有的Java程序转换为托管的.NET代码。 是的,该项目本身当时已经被作者放弃了,但是它的最新实现使我能够相当成功地对
Gorp源代码文本采取必要的措施。
因此,我进行了所有必要的更改,并将其全部放入适当类型的DLL中,在Visual Studio中为.NET Framework创建的任何项目都可以轻松地“拾取”。
同时 ,我创建了另一层用于方便地表示
Gorp返回的结果的层,形式为相应的数据结构,可以方便地以表表示形式进行处理(并以行和列为基础;字典键和数字索引为基础) 。 好吧,用于处理和显示结果的必要实用程序本身很快就写好了。
同样,为新引擎改编模板的过程也没有引起任何特殊的复杂性,以便教会他如何拆卸目录文本扫描的现有样本。 实际上,我什至不必转向以前的空白:我只是从头开始创建了所有必要的模板。 此外,如果旨在与该系统的先前版本一起使用的模板设置了一个相当狭窄的框架,可以在文本的帮助下正确地对其进行解析,则新引擎已经允许同时开发适用于多种类型标记的相当通用的模板。 我什至尝试为任何目录文本编写一个全面的模板,尽管当然,即使有所有对我开放的新可能性,包括特别是实现所有相同的嵌套重复序列(例如姓和名的首字母缩写)的能力有限连续几位作者),结果证明是乌托邦。
将来可能会实现某种元模板概念,该概念可以一次检查源文本是否符合多个可用模板,然后根据获得的结果,使用某种智能算法选择最合适的模板。 但是现在我更担心另一个问题。 尽管
Gorp这样的解析器具有多种功能和我所做的修改,但从本质上来说,它仍然无法执行我自己的手写解析器从第一个版本就可以完成的看似简单的事情。 即:他有能力在适当的位置从源文本中查找和提取与所用模板框架中指定的掩码匹配的所有片段,而对这些片段之间的空格中的文本完全不感兴趣。 到目前为止,我仅对新引擎进行了少许改进,使其能够从当前位置搜索此类给定序列的给定序列的所有可能的新重复,从而在解析检测到的重复结构之间包含的任意字符集时完全无法考虑文本的可能性。 但是,这使得无论下一个掩码的对应掩码如何,无论下一个掩码的搜索结果如何,都无法设置下一个掩码:所描述的文本结构的严格性仍然没有为任意包含不规则字符留出空间。
而且,如果对于我遇到的目录示例来说,这个问题似乎还没有那么严重,那么当试图将新的解析机制应用于本质上类似的任务来解析网站内容(即相同的解析)时,其局限性就在这里他们带着所有证据出现了。 毕竟,为Web标记片段设置必要的掩码非常简单,在这之间应该是我们正在寻找的数据(您需要提取),但是尽管所有可能的HTML标记和属性都适合,但如何使解析器立即转到下一个类似的片段。他们之间的差距?
经过一番思考,我决定引入几个实用程序模式
(%all_before)和
(%all_after) ,其明显目的是确保忽略任何后续模式(掩码)之前源文本中可以包含的所有内容。 此外,如果
(%all_before)简单地忽略了所有这些任意包含,则
(%all_after)相反,允许在从前一个片段切换后将它们添加到所需的片段中。 听起来很简单,但是要实现这个概念,我不得不再次梳理gorp源以进行必要的修改,以免破坏已经实现的逻辑。
最后,我设法做到了(尽管即使是非常最初的,尽管我的解析器非常错误的实现都是在几周内编写的,甚至更快)。从现在开始,该系统采用了真正通用的形式-在首次尝试使其运行后至少十二年。当然,这不是最终的梦想。您仍然可以使用任何可用的库来完全重写C#中gorp模板的解析器,以实现免费语法。我认为应该大大简化代码,这将摆脱现有Java源代码形式的遗留问题。但是使用现有的引擎,也很有可能做各种有趣的事情,包括尝试实现我已经提到的元模板,更不用说解析来自各个网站的各种数据了(但是,我不排除现有的专用软件工具更适合于此) -我只是没有使用它们的相关经验)。顺便说一下,今年夏天,我已经收到来自一家使用Salesforce技术的公司的电子邮件邀请(原始Gorp的开发人员)通过采访,以进行在里加的进一步工作。不幸的是,目前我还不准备搬迁。第二部分更详细地描述了使用Salesforce Gorp中使用的实现示例编译和随后解析模板的技术(我自己添加的内容,除了已经描述的几个服务词之外,实际上并没有改变模板语法本身,因此几乎所有原始系统的文档戈尔普适合我的版本)。在那里,您将找到用于与此引擎进行交互的示例代码,以及指向我的版本Gorp.NET的存储库的链接。