问题标签 [grammar]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
language-agnostic - 如何在解析器生成器(ANTLR、YACC 等)中解析名称=值对列表?
我想以以下形式解析(空格分隔)对的列表
在哪里:
- NAME 可以包含除空格和等号以外的任何内容
- VALUE 可以包含除空格以外的任何内容(包括等号!)
问题是让解析器匹配输入
作为单独'NAME EQUALS VALUE'
的令牌,而不是作为单个'VALUE'
令牌。
PS。我知道这对于直接编码来说是微不足道的,但我需要在更大的解析器的上下文中使用它。
parsing - 解决我的语法中的 shift-reduce 冲突的问题
我正在尝试用Irony编写一个小型解析器。不幸的是,我遇到了“减少班次冲突”。语法不是我的强项,我只需要完成这件小事。这是产生错误的简化语法:
“班次减少冲突”是什么意思,我该如何解决?我认为这意味着我的语法模棱两可,但我无法充分扭曲我的逻辑以了解如何。
补充:澄清 - “asd”只是一个文字字符串“asd”。所以我希望这个语法会解析以下表达式:
补充2:忘了说,语法的根是LogicalExpression
。
补充3:啊,我明白了!模棱两可是因为像这样的表达
可以用两种不同的方式来解释:
但是我该如何解决呢?好的,我可以将 AND 或 OR 中的一个设置为比另一个更强大(无论如何我都想这样做)。但是现在我看到即使只有一个操作员也会出现错误。换句话说,这也会产生同样的错误:
在这种情况下,我想要这个:
要解析为:
这样做的明确方式是什么?
补充4:知道了!
这会解析所有布尔表达式,运算符优先级为 NOT->AND->OR。“asd”可以替换为您的条款的表达方式。
regex - 有哪些奇特的解析技术?
在过去的一年里,我一直在解析扑克手牌的历史,并且在一般的解析方面学到了很多东西。
我们从正则表达式开始,但很快意识到这不会轻易扩展。我们跳过了从 ruby 到 c++ 的语言,最后意识到必须改变的是算法。
我们拿起了 Boost::Spirit 并看到我们的速度以我们原始速度的 10 倍以上的顺序急剧上升。然后我们跳到 java,目前正在使用 antlr 为每个站点创建语法。这绝对是迄今为止最快的方法,而且非常彻底,这很好,因为您确切地知道您在“完整”语法方面的立场。不幸的是,我花费了大量的时间来处理这些语法——它们工作得非常好,但还不完美。
无论如何,关于手头问题的背景已经足够了——是否有任何我不知道的“异国情调”或鲜为人知的解析技术?我只知道词法分析/解析语法和其他劣质正则表达式/循环方法。
对于那些不熟悉扑克手牌历史的人,我会发布一个,以便您了解结构是什么。
我很清楚其他收集信息的方法(例如屏幕抓取和 dll 注入),但仍然需要将手牌历史转换为结构化数据,所以我只关注获取信息的方法,例如正则表达式/语法...
我想如果我找不到东西,我会用 ocamllex/ocamlyacc 重写我们的语法。
更新
仅供参考:正则表达式速度约为 60 手/秒,而语法处理 600+ 手/秒...在数据全部整理好后,整只手都转换为 xml... 需要 20-30 个正则表达式(在最后一次计数)对于您要解析的每个站点....语法方面的每个站点都有自己的语法,其中包含大量的词法分析器/解析器规则(但它的代码量仍然较小)
我确实有龙书并且一直在阅读它——这让我对使用 ocamllex/ocamlyacc 失去了兴趣……速度是这里游戏的名称……
parsing - 可组合语法
有很多编程语言支持包含迷你语言。PHP 嵌入在 HTML 中。XML 可以嵌入到 JavaScript 中。Linq 可以嵌入到 C# 中。正则表达式可以嵌入到 Perl 中。
想一想,大多数编程语言都可以建模为不同的迷你语言。例如,Java 可以分解为至少四种不同的迷你语言:
- 类型声明语言(包指令、导入指令、类声明)
- 成员声明语言(访问修饰符、方法声明、成员变量)
- 语句语言(控制流、顺序执行)
- 一种表达式语言(文字、赋值、比较、算术)
能够将这四种概念语言实现为四种不同的语法肯定会减少我通常在复杂的解析器和编译器实现中看到的许多意大利面。
我之前已经为各种不同类型的语言实现了解析器(使用 ANTLR、JavaCC 和自定义递归下降解析器),当语言变得非常庞大和复杂时,您通常会得到一种 huuuuuuge 语法,并且解析器实现得到真的很丑真的很快。
理想情况下,当为其中一种语言编写解析器时,最好将其实现为可组合解析器的集合,在它们之间来回传递控制。
棘手的是,包含语言(例如,Perl)通常会为包含的语言(例如,正则表达式)定义自己的终点哨兵。这是一个很好的例子:
在这段代码中,主要的 perl 代码定义了一个非标准的终点“|” 对于正则表达式。实现与 perl 解析器完全不同的正则表达式解析器将非常困难,因为正则表达式解析器不知道如何在不咨询父解析器的情况下找到表达式终点。
或者,假设我有一种语言允许包含 Linq 表达式,但不是以分号结尾(如 C# 那样),我想强制 Linq 表达式出现在方括号内:
如果我在父语言语法中定义了 Linq 语法,我可以轻松地为“LinqExpression”编写一个明确的产生式,使用语法前瞻来查找括号包围。但是我的父语法必须吸收整个 Linq 规范。这是一个拖累。另一方面,一个单独的子 Linq 解析器将很难确定在哪里停止,因为它需要为外来标记类型实现前瞻。
这几乎可以排除使用单独的词法分析/解析阶段,因为 Linq 解析器将定义一组与父解析器完全不同的标记化规则。如果您一次扫描一个标记,您怎么知道何时将控制权交还给母语的词法分析器?
你们有什么感想?当今可用于实现不同的、解耦的和可组合的语言语法以将迷你语言包含在更大的父语言中的最佳技术是什么?
parsing - 如何解决明确语法中的 shift-reduce 冲突
我正在尝试使用 LALR(1) 解析器生成器(Bison,但问题并非特定于该工具)解析一个简单的语法,并且我遇到了 shift-reduce 冲突。我发现的有关修复这些问题的文档和其他资源往往会说以下一项或多项:
- 如果语法有歧义(例如 if-then-else 歧义),请更改语言以修复歧义。
- 如果是运算符优先级问题,请明确指定优先级。
- 接受默认分辨率并告诉生成器不要抱怨它。
然而,这些似乎都不适用于我的情况:据我所知,语法是明确的(当然它只有一个前瞻字符是模棱两可的),它只有一个运算符,默认分辨率会导致解析错误在正确格式的输入上。是否有任何技术可以重新定义语法以消除不属于上述存储桶的移位减少冲突?
具体而言,这是有问题的语法:
目的是解析“[A-Za-z]+”或“[A-Za-z] -> [A-Za-z]+”形式的分号分隔的行。
sql - 为什么 SQL 的语法是由内而外的?
在几乎任何正式结构化的信息集中,您要么从头到尾阅读,要么偶尔从尾到头阅读(例如街道地址)。但是在 SQL 中,尤其是 SELECT 查询中,为了正确理解它的意思是你必须从中间开始,从 FROM 子句开始。这会使长查询非常难以阅读,特别是如果它包含嵌套的 SELECT 查询。
通常在编程中,当某些事情似乎没有任何意义时,背后有一个历史原因。从 SELECT 而不是 FROM 开始是没有意义的。有谁知道这样做的原因?
algorithm - 从具有给定数量终端的语法中产生一个句子
假设您有一个玩具语法,例如:(更新后输出看起来更自然)
例如,“狗踢红巫师”,“鸟遇到斑点鱼或巫师嫁给条纹狗”
根据它必须包含总共n Vs + As + Ns的约束,你如何从这个语法中产生一个句子。给定一个整数,句子必须包含那么多终结符。(当然,在这个语法中,最小可能的n是 3)。
code-generation - ANTLR:可选参数的语法测试(使用 ? 运算符)
我有一个 ANTLR 语法,并且正在用我的语言定义一个允许可选参数的函数。如何检查代码生成块中是否传入了可选参数?
我基本上是在寻找语法来做这个假设的树语法语句:
非常感谢任何有关文档的建议或指针!
parsing - javacc parseException...前瞻问题?
我正在为 javacc 中的一个非常简单的语法编写一个解析器。它开始融合在一起,但目前我完全陷入了这个错误:
有问题的输入行是z = y + z + 5
给我带来问题的产生是我从 varDecl() 调用的表达式:
表达式如下所示:
我不知道为什么会出现此错误 - 任何见解都将不胜感激。
grammar - 如何构建生成这种语言的语法?
我正在学习有限自动机和语法测试,但我遇到了这个问题:
我相信我的作品应该遵循以下原则:
我的 C 产品如何记住 m 和 n 的数字?我猜这一定是一个上下文无关的语法,如果是这样,它应该是怎样的?