用于文本分析的DSL

时间:2014-08-13 01:05:51

标签: php regex parsing dsl

我有一组特定域(会计报告)的半结构化TEXT文档,它们在内容上都非常相似。但是,数据在每个文档模板上以不同的方式处理。

编写一些正则表达式并获取我想要的数据相当容易。但是必须为每个新的文档布局完成。

我想构建一个通用解析器,它接收一个脚本,告诉它应该如何读取特定布局的会计报告,这样对于每个新布局,我需要做的就是编写一个比写入更简单的新脚本。很多正则表达式。

类似的东西:

解析脚本:

declare collection_name {
  date,
  description,
  amount
}

get customer_name from line 3
get account_id from "AccountID <number>"

read data as <collection_name> from <pattern> until <pattern>

请告诉我从哪里开始,阅读有关内容,或者您​​是否已经看过类似的内容。我真的很感激任何帮助。

1 个答案:

答案 0 :(得分:4)

构建DSL并不容易,特别是像你提出的丰富语法,所以我假设你准备好了:)

管道是:

Script -> Compiler -> PHP code for specific template

然后您将使用PHP代码获取数据

TEXT -> PHP code for that template -> data(structured JSON,XML,...)

因此,要构建编译器,您需要了解流程:

Script -> Lexer(Tokenizer) -> Parser -> AST/CFG -> PHP code generation

定义https://stackoverflow.com/a/380487/877594

  • Tokenizer 将文本流分解为标记,通常是查找空格(标签,空格,新行)。

  • Lexer 基本上是一个标记化器,但它通常会为标记附加额外的上下文 - 这个标记是一个数字,该标记是一个字符串文字,另一个标记是一个相等运算符

  • Parser 从词法分析器获取标记流并将其转换为表示原始文本所代表的(通常)程序的抽象语法树。

抽象语法树http://en.wikipedia.org/wiki/Abstract_syntax_tree

  

源的抽象语法结构的树表示   用编程语言编写的代码。树的每个节点表示   源代码中出现的构造。语法是&#34; abstract&#34;在   不代表真实语法中出现的每个细节。对于   例如,分组括号隐含在树结构中,并且   像if-condition-then表达式这样的句法结构可能是   用具有两个分支的单个节点表示。

如果您正在考虑在DSL中使用表达式,它们适用于表达式而非指令。

控制流程图http://en.wikipedia.org/wiki/Control_flow_graph

  

使用图表符号表示可能存在的所有路径   在执行过程中遍历了一个程序。

每个节点都是一个带有属性的指令对象(声明,获取,读取......)。例如:

get {
    target: customer_name,
    from: line {n: 3}
}

建筑

PHP是一个非常糟糕的选择,因为没有高质量的库来构建词法分析器和解析器,比如C / C ++中的Flex / Bison。在这个问题中有一些工具,但我不推荐它们Flex/Bison-like functionality within PHP

我建议您自己构建它: