Questions tagged «parsing»

分析(非)结构化数据以将其转换为结构化标准化格式。


4
何时使用解析器组合器?何时使用解析器生成器?
最近,我想深入了解解析器领域,希望创建自己的编程语言。 但是,我发现存在两种不同的编写解析器的方法:解析器生成器和解析器组合器。 有趣的是,我找不到任何可以解释哪种资源更好的资源。相反,我查询的许多资源(和人员)都不知道另一种方法,只是将其方法解释为该方法,而根本没有提及另一种方法: 在著名的龙书进入词法/扫描,并提到(F)法,但都没有提到解析器组合。 语言实现模式在很大程度上依赖于Java内置的ANTLR解析器生成器,根本没有提到解析器组合器。 Parsec上的Parsec 简介教程(是Haskell中的Parser Combinator)根本没有提到Parser Generators。 Boost :: spirit(最著名的C ++解析器组合器)根本没有提到解析器生成器。 很棒的说明性博客文章“ 您可能已经发明了解析器组合器”根本没有提到解析器生成器。 简单概述: 解析器生成器 解析器生成器获取用DSL编写的文件,该文件是Extended Backus-Naur形式的某种方言,并将其转换为源代码,然后可以(在编译时)成为该DSL中描述的输入语言的解析器。 这意味着编译过程分为两个单独的步骤。有趣的是,解析器生成器本身也是编译器(其中许多确实是自托管的)。 解析器组合器 解析器组合器描述了称为解析器的简单函数,这些函数均将输入作为参数,如果匹配则尝试提取此输入的第一个字符。它们返回一个元组(result, rest_of_input),如果解析器无法解析此输入中的任何内容,则该字段result可能为空(例如nil或Nothing)。一个例子是digit解析器。其他解析器当然可以将解析器作为第一个参数(最后一个参数仍保留在输入字符串中)来组合它们:例如,many1尝试尽可能多地匹配另一个解析器(但至少要匹配一次,否则它本身会失败)。 现在,您当然可以结合(组成)digit和many1创建新的解析器,例如integer。 同样,choice可以编写一个更高级别的解析器,该解析器获取解析器列表,依次尝试每个解析器。 这样,可以构建非常复杂的词法分析器/解析器。在支持运算符重载的语言中,这看起来也很像EBNF,尽管它仍然是直接用目标语言编写的(并且您可以使用所需的目标语言的所有功能)。 简单差异 语言: 解析器生成器使用EBNF-ish DSL和这些语句匹配时应生成的代码的组合编写。 解析器组合器直接以目标语言编写。 乐兴/解析: 解析器生成器在“词法分析器”(将字符串拆分成可能被标记以表明我们正在处理的值的标记)与“解析器”(从词法分析器获取标记的输出列表)之间有非常明显的区别并尝试将它们组合起来,形成一个抽象语法树)。 解析器组合器不需要/不需要这种区别;通常,简单的解析器执行“词法分析器”的工作,而更高级别的解析器将这些更简单的解析器称为确定要创建哪种AST节点。 题 但是,即使存在这些差异(这是差异列表,可能还远远不够!),我仍无法就何时使用哪一个做出明智的选择。我看不出这些差异的含义/后果。 哪些问题属性表明使用Parser Generator可以更好地解决问题?哪些问题属性表明使用Parser Combinator可以更好地解决问题?

4
如何精确创建抽象语法树?
我想我了解AST的目标,并且之前我已经构建了几个树结构,但从未构建过AST。由于节点是文本而不是数字,所以我很困惑,因此在解析某些代码时,我想不出一种输入令牌/字符串的好方法。 例如,当我查看AST的图表时,变量及其值是等号的叶节点。这对我来说很有意义,但是我将如何实施呢?我想我可以视情况而定,以便当我偶然遇到“ =”时,我将其用作节点,并将在“ =”之前解析的值添加为叶子。这似乎是错误的,因为根据语法的不同,我可能不得不为成千上万的东西辩护。 然后我遇到了另一个问题,那棵树是如何横穿的?我会一直下降到最低点吗,当我到达最低点时又返回一个节点,并对它的邻居也这样做吗? 我已经看到了大量关于AST的图表,但是我找不到一个简单的代码示例,这可能会有所帮助。

2
现代语言是否仍使用解析器生成器?
我是研究关于gcc编译器套件在维基百科这里,当这想出了: GCC开始使用由Bison生成的LALR解析器,但后来逐渐切换为手写递归下降解析器。2004年用于C ++,2006年用于C和Objective-C。目前,所有前端都使用手写递归下降解析器 因此,在最后一句话中,(以及我所信任的维基百科),我可以肯定地说:“ C(gcc),C ++(g ++),Objective-C,Objective-C ++,Fortran(gfortran),Java(gcj), Ada(GNAT),Go(gccgo),Pascal(gpc),... Mercury,Modula-2,Modula-3,PL / I,D(gdc)和VHDL(ghdl)”都是前端,不再使用解析器生成器。也就是说,它们都使用手写的解析器。 我的问题是,这种做法无处不在吗?具体来说,我在[Python,Swift,Ruby,Java,Scala,ML,Haskell]中寻找x的“ x的标准/官方实现是否具有手写的解析器”的确切答案?(实际上,这里也欢迎提供其他语言的信息。)我敢肯定,经过大量的挖掘,我可以自己找到它。但是,我也相信社区很容易对此负责。谢谢!

6
为什么未为HTML选择严格解析?
我经常想知道为什么在创建HTML时没有选择严格的解析。在大多数Internet历史上,浏览器都接受任何形式的标记,并尽力进行解析。该过程会降低性能,使人们书写乱码,并且很难中止过时的功能。 是否有严格解释HTML的特定原因?
38 html  history  parsing 


5
通常如何解析注释?
一般如何用编程语言和标记来处理注释?我正在为某些自定义标记语言编写解析器,并希望遵循最少惊喜的原则,因此我试图确定一般约定。 例如,注释是否应嵌入令牌中,从而“干扰”令牌?通常,是这样的: Sys/* comment */tem.out.println() 有效? 另外,如果语言对新行敏感,并且注释跨越新行,是否应考虑新行? stuff stuff /* this is comment this is still comment */more stuff 被视为 stuff stuff more stuff 要么 stuff stuff more stuff ? 我知道几种特定的语言在做什么,我也没有在寻求意见,而是在寻找是否:是否普遍达成共识,标记对代币和新行的一般期望是什么? 我的特定上下文是类似Wiki的标记。
31 parsing  comments 

1
Inglish解析器(适用于《霍比特人》 1982年)
着迷于阅读有关文本冒险游戏《霍比特人》的内容,该游戏的功能强大的解析器名为“ Inglish”: ... Inglish允许输入一些高级句子,例如“向Gandalf询问好奇的地图,然后拿剑并杀死巨魔”。解析器复杂而直观,引入了代词,副词(“恶意攻击地精”),标点符号和介词,并允许玩家以以前无法实现的方式与游戏世界互动。 我想知道是否有人知道Inglish解析器引擎以及开发它的程序员的历史和/或遗产。

8
是否可以静态地预测何时仅从源代码中释放内存?
在程序执行期间,确定性的时间将内存(和资源锁)返回给OS。程序本身的控制流足以知道可以在哪里释放给定资源。就像人类程序员fclose(file)在程序完成后如何知道在哪里写一样。 GC通过在执行控制流时在运行时直接解决问题来解决此问题。但是,有关控制流的真实性的真正来源是来源。因此,从理论上讲,应该可以free()通过分析源(或AST)来确定在编译之前将调用插入到哪里。 引用计数是实现此目的的一种明显方法,但是很容易遇到仍然引用指针(仍在范围内)但不再需要指针的情况。这只是将手动分配指针的职责转换为手动管理这些指针的作用域/引用的职责。 似乎可以编写一个可以读取程序源代码的程序,并且: 预测程序控制流的所有排列-达到与观看程序实时执行类似的准确性 跟踪所有对分配资源的引用 对于每个引用,遍历整个后续控制流,以找到保证绝对不会取消引用的最早点 在这一点上,在源代码的那一行插入一个delocation语句 那里有什么已经做到了吗?我不认为Rust或C ++智能指针/ RAII是同一回事。
27 parsing  memory 

5
此类解析器的名称,或为何不存在
常规解析器消耗其全部输入并生成单个解析树。我正在寻找一个消耗连续流并产生一个解析林的人[ 编辑:请参见注释中有关为什么使用该术语可能不合常规的讨论 ]。我的直觉说我不能成为第一个需要(或认为我需要)这样的解析器的人,但是我已经反复搜索了几个月,无济于事。 我认识到我可能会被XY问题所困扰。我的最终目的是解析文本流,忽略其中的大部分内容,并从识别出的部分中生成解析树流。 所以我的问题是有条件的:如果存在具有这些特征的一类解析器,那叫什么呢? 如果没有,为什么不呢? 有什么选择?也许我缺少使常规解析器执行我想要的方式的某种方式。
27 parsing 

6
反对解析克苏鲁方式的论点是什么?
我的任务是为一种可能对公司非常重要的工具实现领域特定的语言。该语言很简单,但并非无关紧要,它已经允许嵌套循环,字符串连接等,并且实际上可以确定,随着项目的进行,还会添加其他构造。 我从经验中知道,除非语法很琐碎,否则手工编写词法分析器/解析器是一个耗时且容易出错的过程。因此,我有两个选择:解析器生成器y yacc或组合器库(如Parsec)。前者也很好,但是我出于各种原因选择了后者,并以功能语言实现了该解决方案。 结果在我看来非常壮观,代码非常简洁,优雅,可读/流利。我承认,如果您从未使用Java / c#以外的任何程序进行编程,它可能看起来有些怪异,但是对于未使用Java / c#编写的任何内容,这都是正确的。 但是在某个时候,我确实遭到了同事的攻击。快速浏览一下我的屏幕后,他宣布代码令人难以理解,并且我不应该重新发明解析方法,而应该像所有人一样使用堆栈和String.Split。他大声喧noise,我无法说服他,部分是因为我感到惊讶,没有明确的解释,部分是因为他的观点是不变的(没有双关语)。我什至提出要给他解释语言,但无济于事。 我很肯定讨论将再次出现在管理层面前,因此我正在准备一些扎实的论据。 这些是我想到避免基于String.Split的解决方案的前几个原因: 您需要大量的if来处理特殊情况,而事情很快就会失控 大量的硬编码数组索引使维护工作陷入困境 很难处理像函数调用那样的方法参数(例如add((add a,b),c) 如果出现语法错误,很难提供有意义的错误消息(极有可能发生) 我全都是为了简单,清楚和避免不必要的智能加密,但我也认为,精简代码库的每个部分以使汉堡包都可以理解它是一个错误。我听到的是相同的论点,即不使用接口,不采用关注点分离,在周围粘贴粘贴代码等。毕竟,在软件项目上需要最低的技术能力和学习意愿。(我不会使用这个论点,因为它可能听起来令人反感,发动战争不会帮助任何人) 您最喜欢反对解析克苏鲁方式的论点是什么?* *当然,如果您能说服我说他是对的,我也会很高兴

3
在哪个过程中发生语法错误?(标记或解析)
我正在尝试了解编译和解释,逐步找出总体图像。因此,在阅读http://www.cs.man.ac.uk/~pjj/farrell/comp3.html本文时,我遇到一个问题 它说 : 编译器的下一个阶段称为解析器。编译器的这一部分对语言的语法有所了解。它负责识别语法错误,并将无错误程序转换为可以用另一种语言解释或写出的内部数据结构。 但是我无法弄清楚令牌化器如何正确地令牌化具有语法错误的给定流。 它应该卡在此处或向解析器提供一些错误的信息。我的意思是标记化不是一种翻译器吗? 因此,它如何在标记化时克服了词汇中的错误代码行。 在Tokenizer标题上方的链接中有一个令牌示例。 据我了解,令牌的形式似乎是,如果代码中有错误,令牌也会被破坏。 您能澄清一下我的误会吗?

3
为抽象语法树实现访问者模式
我正在创建自己的编程语言,出于学习目的。我已经为我的语言的一部分编写了词法分析器和递归下降解析器(我目前支持数学表达式,例如+ - * /和括号)。解析器将我交给一个抽象语法树,在该语法树上我调用该Evaluate方法以获取表达式的结果。一切正常。这大约是我目前的情况(C#代码示例,尽管这在很大程度上与语言无关): public abstract class Node { public abstract Double Evaluate(); } public class OperationNode : Node { public Node Left { get; set; } private String Operator { get; set; } private Node Right { get; set; } public Double Evaluate() { if (Operator == "+") return …

12
如何编写命令解释器/解析器?
此问题是从Stack Overflow 迁移而来的,因为可以在Software Engineering Stack Exchange上回答。 迁移 7年前。 问题:以字符串形式运行命令。 命令示例: /user/files/ list all; 相当于: /user/files/ ls -la; 另一个: post tw fb "HOW DO YOU STOP THE TICKLE MONSTER?;" 相当于: post -tf "HOW DO YOU STOP THE TICKLE MONSTER?;" 当前解决方案: tokenize string(string, array); switch(first item in array) { case "command": if …

4
RPG棋盘游戏规则的通用规则解析器-怎么做?
我想为笔和纸风格的RPG系统构建一个通用的规则解析器。规则通常可以包含1到N个实体,一个骰子的1个到N个角色,并基于一个实体的多个属性来计算值。 例如: 玩家拥有STR 18,他目前装备的武器使他获得+1 STR的加值,但获得了DEX -1的恶意。他攻击一个怪物实体,并且现在需要运行游戏逻辑来运行一组规则或动作: 玩家掷骰子,如果他获得例如8或更高(他需要传递的基本攻击值是其基本属性之一!),则攻击成功。然后,怪物掷骰子以计算攻击是否通过了它的装甲。如果是,则造成伤害,否则攻击将被阻止。 除了简单的数学规则外,还可能存在一些限制,例如仅适用于特定类别的用户(例如,战士还是向导)或任何其他属性。因此,这不仅限于数学运算。 如果您熟悉诸如Dungeon和Dragons之类的RPG系统,您会知道我在做什么。 我的问题是,现在我不知道如何以最佳方式准确地构建它。我希望人们能够设置任何种类的规则,之后再简单地执行一个操作,例如选择一个玩家和一个怪物,然后执行一个操作(一组规则,例如攻击)。 在数据库方面,我寻求的帮助较少,但更多地是关于如何提出结构和解析器的要求,以保持规则的灵活性。顺便说一下,为此选择的语言是php。 编辑我: 让我完善我的目标:我想创建一个用户友好的界面(不需要别人学习编程语言)来构建或多或少的复杂游戏规则。原因很简单:个人使用并不需要一直记住所有规则,我们只是没有那么频繁地玩,每次查看它们都是一个障碍。另外:做和学习东西看起来很有趣。:) 到目前为止,我已经尝试过:只考虑一个概念,而不是浪费时间构建错误的体系结构。到目前为止,我的想法是允许用户创建所需数量的属性,然后将所需数量的属性分配给任何类型的实体。实体可以是玩家,怪物,物品或其他任何东西。现在,当计算某些内容时,数据将可用于规则解析器,以便规则解析器应能够执行以下操作,例如Player.base_attack + dice(1x6)> Monster.armor_check然后Monster.health-1; 这里的问题是关于如何创建该解析器的。 编辑二: 这是一个非常基本的值的示例,但是要正确地计算它,需要考虑很多不同的事物和变量: 基本攻击加成(期限)您的基本攻击加成(通常由d20社区称为BAB)是从角色等级和等级获得的攻击掷骰加成。不同角色类别的基础攻击加成会以不同的速率增加。角色的基本攻击加值达到+6时,每回合会获得第二次攻击;基本攻击加成为+11或更高的角色获得三分之一;基本攻击加成为+16或更高的角色获得第四点。从不同类别获得的基础攻击加成,例如,针对多类别角色的叠加。角色的基本攻击加成在达到+16后不再给予任何更多攻击,不能小于+0,并且在角色等级达到20后不会由于职业等级而增加。某些专长需要最低基础攻击加成。 您可以在这里http://www.dandwiki.com/wiki/Base_Attack_Bonus_(Term)上阅读它,包括指向类和专长的链接,这些类和专长又具有自己的规则来计算基础攻击所需的值。 我开始认为,使其尽可能地通用将使完成良好的规则解析器变得相当困难。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.