问题标签 [boost-spirit-lex]
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.
c++ - 使用 Boost.Spirit Qi 和 Lex 时的空格跳过
让我们考虑以下代码:
它是具有值和变量的算术表达式的简单解析器。它被构建expression_lexer
用于提取令牌,然后expression_grammar
用于解析令牌。
在这样一个小案例中使用词法分析器可能看起来有点过头了,可能就是这样。但这是简化示例的成本。另请注意,词法分析器的使用允许使用正则表达式轻松定义标记,同时允许通过外部代码(特别是用户提供的配置)轻松定义它们。使用提供的示例,从外部配置文件中读取令牌定义完全没有问题,例如允许用户将变量从 更改%name
为$name
.
代码似乎运行良好(在 Visual Studio 2013 和 Boost 1.61 上进行了检查)。除了我注意到,如果我提供类似5++5
它的字符串正确失败,但报告为提醒,5
而不是+5
这意味着违规+
被“不可恢复”消耗。显然,生成但与语法不匹配的标记绝不会返回到原始输入。但这不是我要问的。只是我在检查代码时意识到的一个旁注。
现在的问题是空格跳过。我非常不喜欢它是如何完成的。虽然我这样做了,因为它似乎是许多示例提供的示例,包括 StackOverflow 上问题的答案。
最糟糕的事情似乎是(没有记录?)qi::in_state_skipper
。此外,似乎我必须添加这样的whitespace
令牌(带有名称),而不是像所有其他令牌一样使用lexer.whitespace
而"WS"
不是似乎不起作用。
最后不得不用Skipper
参数“弄乱”语法似乎不太好。我不应该摆脱它吗?毕竟,我想基于标记而不是直接输入来制作语法,并且我希望将空格从标记流中排除——那里不再需要它了!
我还有哪些其他选项可以跳过空格?像现在这样做有什么好处?
c++ - 使用来自 Boost.Spirit 的 Lex 和 Qi 在语法规则中使用词法分析器标记属性
让我们考虑以下代码:
它是具有值和变量的算术表达式的简单解析器。它被构建expression_lexer
用于提取令牌,然后expression_grammar
用于解析令牌。
在这样一个小案例中使用词法分析器可能看起来有点过头了,可能就是这样。但这是简化示例的成本。另请注意,词法分析器的使用允许使用正则表达式轻松定义标记,同时允许通过外部代码(特别是用户提供的配置)轻松定义它们。使用提供的示例,从外部配置文件中读取令牌定义完全没有问题,例如允许用户将变量从 更改%name
为$name
.
代码似乎运行良好(在 Visual Studio 2013 和 Boost 1.61 上进行了检查)。
具有附加到令牌的expression_lexer
属性。我猜他们在编译后就可以工作了。但我真的不知道如何检查。
最终,我希望语法为我构建一个std::vector
带有反向波兰符号的表达式。(其中每个元素都是一个boost::variant
或operator::type
或double
或std::string
。)
然而,问题是我未能在我的expression_grammar
. 例如,如果您尝试更改sum_operator
以下方式:
你会得到编译错误。我希望这会起作用,因为这operation::type
是两者的属性,operator_add
也是operator_sub
它们的替代方法。而且它仍然没有编译。从错误来看assign_to_attribute_from_iterators
,解析器似乎试图直接从输入流范围构建属性值。这意味着它忽略了[lex::_val = operation::add]
我在词法分析器中指定的内容。
将其更改为
也没有帮助。
我也尝试将定义更改为
也没有帮助。
如何解决这个问题?我知道我可以symbols
从 Qi 使用。但是我希望词法分析器可以轻松地为令牌配置正则表达式。我也可以assign_to_attribute_from_iterators
按照文档中的描述进行扩展,但是这种工作会加倍。我想我也可以跳过词法分析器上的属性,只在语法上使用它们。但这又不能很好地适应variable
令牌的灵活性(在我的实际情况下,那里的逻辑稍微多一些,因此它也可以配置令牌的哪一部分形成变量的实际名称 - 而在这里它被固定为只是跳过第一个字符)。还要别的吗?
还有一个附带问题-也许有人知道。有没有办法从令牌操作中捕获令牌的正则表达式组?所以,而不是有
相反,我将能够从捕获组中创建一个字符串,从而轻松处理$var$
.
已编辑!在使用 Boost.Spirit Qi 和 Lex 时,我已经改进了 Whitespace skipper 的结论。这是一种简化,不影响此处提出的问题。
c++ - 带有 boost::spirit::lex 的不区分大小写的关键字
有没有办法以不区分大小写的方式识别特定模式?
例如,如果我有
如何匹配true
, TRUE
,tRuE
同时避免[Tt][Rr][Uu][Ee]
为每个关键字编写?
c++ - 将 Boost Spirit Lex 语义动作转换为 Phoenix - 如何访问 _val?
我为我的 Boost Spirit Lexer 编写了一个语义操作,将字符串中的转义序列转换为它们所代表的内容。它运行良好,我想将其转换为 Boost Phoenix 表达式,但无法编译该表达式。
这是有效的:
这是我试图转换它:
Awstring
不能从 构造_val
。_val
也没有begin()
or end()
,到底应该怎么用?
这std::wstring(lex::_start, lex::_end)
也失败了,因为这些参数不被识别为迭代器。
在这个问题中,我发现了phoenix::construct<std::wstring>(lex::_start, lex::_end)
,但这也并没有真正导致wstring
.
如何获取wchar_t
当前令牌的字符串或一对迭代器?
c++ - 无法让 boost::spirit 解析器和词法分析器为 std::string 或 int 或 double 以外的令牌类型工作
这不会编译(下面的代码)。
这里还有另一个问题有同样的错误。但我不明白答案。我已经尝试在某些地方插入 qi::eps ——但没有成功。
我还尝试为使用的类型添加元函数(boost::spirit::raits::is_container)——但这也无济于事。
我还尝试使用相同的变体,其中包含我需要在任何地方使用的所有类型。同样的问题。
有没有人让这个词法分析器工作,返回除了 double 或 int 或 string 以外的东西?并且对于解析器还返回非平凡的对象?
我尝试在所有返回默认对象的地方实现语义函数。但这也无济于事。
代码如下:
c++ - 无法获得 Boost Spirit 语法以使用 std::map<> 的已知键
我似乎遇到了一些我无法忍受的 Boost Spirit 精神障碍。我需要处理一个相当简单的语法,我想将值放入一个结构中,该结构包含一个 std::map<> 作为它的成员之一。对的键名是预先知道的,因此只允许使用这些键名。映射中可能有一对多的键,按任何顺序,每个键名都通过 qi 验证。
例如,语法看起来像这样。
在此示例中,“添加”的键是 a1、a2 和 a3,“修改”的键也是 m1、m2、m3 和 m4,并且每个都必须包含一个值。对于“清除”,映射 c1、c2 和 c3 的键可能不包含值。此外,假设对于本示例,您最多可以拥有 10 个键(a1 ... a11、m1 ... m11 和 c1 ... c11),它们的任意组合可以按任何顺序用于相应的操作。这意味着您不能将已知键 c X用于“添加”或 m X用于“清除”
结构遵循这个简单的模式
所以从上面的例子中,我希望结构包含......
我可以让每个单独的部分独立工作,但我似乎无法让他们一起工作。例如,我让主机和操作在没有地图<> 的情况下工作。
我改编了Sehe (此处)先前发布的示例,试图使其正常工作(顺便说一句:Sehe有一些很棒的示例,我一直在使用这些示例和文档一样多)。
这是一个摘录(显然不起作用),但至少显示了我想要去的地方。
我希望这个问题不是太模棱两可,如果你需要一个问题的工作示例,我当然可以提供。任何和所有的帮助都非常感谢,所以提前谢谢你!
c++ - 将 Boost actor_lexer 转换为静态:错误好像“actor_”未使用
我正在将 Boost Spirit Lex 程序转换为静态词法分析器模型。词法分析器具有语义操作,因此动态词法分析器的类型为actor_lexer
:
现在使用静态词法分析器进行编译时,出现错误
这正是人们使用语义动作但忘记更改lexer
为actor_lexer
. 我确实actor_lexer
在生成器程序中使用了该类型,据我所知,这似乎有效。
还有什么我想念的吗?或者目前不可能在静态词法分析器中使用语义动作?
c++ - Spirit 仅在似乎从 Lexer 获得第一个符号后无法解析
最近在这里问了一个问题: Boost Spirit Segfault In Parser
在这篇文章中,有人指出我正在使用的语法绝对是左递归的,并且精神是一个 PEG 解析器生成器,这意味着左递归是不可能的。
我使用 Dragon Book 中处理左递归部分的规则将语法转换为非左递归语法。
给定一个左递归文法
可以通过执行以下操作将其转换为等效的右递归文法:
这是生成的解析器,我认为是非左递归产生:
}
这是词法分析器
这是我的示例测试程序
这些修改引起了一些问题,首先,通过非正式地查看语法,没有构建完整的 LL(1) 解析表,我不相信这个语法是 LL(1)。我仍然需要验证这一点,但我想知道精神,能够解析这个语法吗?我知道 PEG 通常使用 / 运算符来进行前瞻,spirit 目前是否这样做?我在另一篇文章中看到精神可能没有?
其次,这个语法失败了,我注意到,在开始生产时,我简化了开始生产并使其成为:
然后将输入更改为:
语法调试语句表明解析成功。但是,我看到剩下的字符串是:
所以实际上只解析了第一个令牌。经过一些调试后,我不确定为什么解析成功以及为什么只使用一个符号,这可能是词法分析器的问题吗?
此外,当我将开始生产更改为:
并使用输入
然而,这无法解析并且只消耗字符 y。
最后,我的调试语句的输出不是很有帮助,当使用调试语句运行时,产生的输出是:
我假设这意味着在语法中尝试了 20 个产生式,从 20 个空 [],这是一个正确的假设吗?还有为什么 [] 是空的?我通常会看到它们带有一些对调试有用的文本。是不是因为正则表达式匹配,语法就自动成功了?如果是这种情况,有没有办法让调试语句在使用令牌枚举令牌而不是使用宏添加表达式时打印有用的输出?
感谢您提供正确方向的任何帮助或点,谢谢。
c++ - 为什么要提升精神 lex hang 而不是解析错误?
我很长时间没有使用 boost::spirit 并再次返回。并停留在简单的情况下(天哪,有时我想杀死这个库……为什么为什么这么简单的任务对 boost 如此复杂)。
我预计会出现解析错误,但在上面的示例中,boost::spirit 挂起处理器并消耗了所有内存。示例 - Coliru
我做错了什么以及如何解决?