可以根据现有的马尔巴解析器可以用来改善的Perl 5的解析(例如,取代现有的Perl解释器的解析器的全部或块)?
我在理论层面上提出要求,例如忽视实际考虑因素,例如"如果能够,则需要花费10,000个工时".
如果没有,阻止使用Marpa的具体问题是什么?(再次,最好是理论上的).
有关为什么这很有趣的背景,Jeffrey Kegler(Marpa的作者)于2008年在PerlMonks 上发表了一篇有着名的文章"Perl Can not Parsed:A Formal Proof",这篇文章受到当时他对Marpa的影响.
我正在使用marpa :: r2(Marpa-R2-2.065_002)的最新版本,它似乎非常快速地吃掉所有内存.我写下了波纹管脚本来测试它.
use strict;
use warnings FATAL => 'all';
use Marpa::R2;
use Data::Dumper;
my $grammar = Marpa::R2::Scanless::G->new({
action_object => __PACKAGE__,
source => \(<<'END_OF_SOURCE'),
:default ::= action => ::array
:start ::= path
path ::=
step action => _do_step
step ~ [a-z]+
END_OF_SOURCE
});
sub _do_step{ return {step => $_[1]}};
sub new {} #The Marpa::R2 needs it
sub compile{
my ($query) = @_;
return undef unless $query;
my $reader = Marpa::R2::Scanless::R->new({
grammar => $grammar,
trace_terminals => 0,
});
$reader->read(\$query);
print Dumper …
Run Code Online (Sandbox Code Playgroud) Perl的Marpa解析器的文档包含以下关于污染数据的部分:
Marpa :: R2的存在允许其输入以灵活和强大的方式改变执行.Marpa不应该与不受信任的输入一起使用.在Perl的污点模式中,使用Marpa的SLIF接口时会出现致命错误,该接口具有受污染的语法,受污染的输入字符串或受污染的令牌值.
如果我理解这种限制的后果,我不确定.我明白,语法一定不会被污染.但我不明白输入不应该被污染.对我来说,解析器的任务是验证输入.解析器必须信任其输入对我来说听起来不合理.
真的那样吗?用Marpa实现任何类型的公共网络服务是不可能的吗?
我之所以这样问是因为其中一个参考用例是Marpa HTML解析器,而且使用HTML解析器似乎是矛盾的,虽然大约99,99%的HTML可能被污染,但它不能与受污染的数据一起使用.
任何人都可以解释这个矛盾吗?
与我之前关于使用正则表达式进行不区分大小写的关键字匹配的问题相关.
在Marpa中是否可以不区分大小写地匹配字符串?如果是这样,怎么样?
假设我有语法
:start ::= script
identifier ~ [\w]+
script ::= 'script' identifier code
code ::= command*
command ::= 'run' | 'walk' | 'stop'
Run Code Online (Sandbox Code Playgroud)
我怎样才能使它符合任何script
,Script
,SCRIPT
或更低和大写字母任何其他组合?
我有一个相当大的Marpa语法(用于解析XPath),我遇到了令牌化的问题.我创建了一个最小的破解示例:
use strict;
use warnings;
use Marpa::R2;
my $grammar = Marpa::R2::Scanless::G->new(
{
source => \(<<'END_OF_SOURCE'),
:default ::= action => ::array
:start ::= Start
Start ::= Child DoubleColon Token
DoubleColon ~ '::'
Child ~ 'child'
Token ~
word
| word ':' word
word ~ [\w]+
END_OF_SOURCE
}
);
my $reader = Marpa::R2::Scanless::R->new(
{
grammar => $grammar,
trace_terminals => 1,
}
);
my $input = 'child::book';
$reader->read(\$input);
Run Code Online (Sandbox Code Playgroud)
此脚本打印以下内容:
Registering character U+0063 as symbol 10: [[\w]]
Registering character U+0063 as symbol 3: [[c]] …
Run Code Online (Sandbox Code Playgroud) 我知道Perl的"Marpa" Earley解析器有很好的错误报告.
但我无法在其文档中或通过谷歌搜索找到它是否有错误恢复.
例如,大多数C/C++编译器都有错误恢复,用于报告多个语法错误,而其他编译器通常会在第一个错误时停止.
我实际上正在解析自然语言,并想知道在输入的一部分失败之后是否有重新同步和恢复解析的方法.
例如,对于那些可以理解它的人:
我正用老挝语解析音节.在老挝,一些元音是变音符号,它们被编码为单独的字符并在前一个辅音上方呈现.在解析来自老挝维基百科的随机文章时,我遇到了一些文本,其中这样的元音加倍.这在老挝正字法中是不允许的,所以必须是拼写错误.但我知道,在几个字符内,文字再次好.
无论如何,这是一个真实的例子,它引起了我对错误恢复或与令牌流重新同步的普遍兴趣.
我正在Marpa中实现一个新的DSL(来自Regexp :: Grammars)我非常满意.我的语言支持一堆一元和二元运算符,带有C风格标识符的对象和使用熟悉的点符号的方法调用.例如:
foo.has(bar == 42 AND baz == 23)
我发现了Marpa的语法描述语言提供的优先规则功能,并且已经开始依赖于它,所以我几乎只有一条G1规则Expression
.摘录(为简洁省略了许多替代方案和语义操作):
Expression ::=
NumLiteral
| '(' Expression ')' assoc => group
|| Expression ('.') Identifier
|| Expression ('.') Identifier Args
| Expression ('==') Expression
|| Expression ('AND') Expression
Args ::= ('(') ArgsList (')')
ArgsList ::= Expression+ separator => [,]
Identifier ~ IdentifierHeadChar IdentifierBody
IdentifierBody ~ IdentifierBodyChar*
IdentifierHeadChar ~ [a-zA-Z_]
IdentifierBodyChar ~ [a-zA-Z0-9_]
NumLiteral ~ [0-9]+
Run Code Online (Sandbox Code Playgroud)
如您所见,我正在使用Scanless界面(SLIF).我的问题是,这也解析,例如:
foo.AND(5)
Run Code Online (Sandbox Code Playgroud)
Marpa知道点后面只能有一个标识符,因此它甚至不考虑AND
可能是关键字的事实.我知道我可以通过一个AND
明确标识为关键字的单独的lexing阶段来避免这个问题,但这个小小的剪切不值得努力.
SLIF中是否有办法仅将Identifier
规则限制为非关键字标识符?
我是Marpa的新手.我已经尝试了几种方法来描述我的语法中的0个或更多个术语的列表,我想避免使用多个解析树.
我的语言将只有1个组件,后跟0 +子组件:
package => component-rule [subcomponent-rule ...]
Run Code Online (Sandbox Code Playgroud)
我首先尝试的是这样的:
{ lhs => 'Package', rhs => [qw/component-rule subcomponents/] },
{ lhs => 'subcomponents', rhs => [qw/subcomponent-list/] },
{ lhs => 'subcomponent-list', rhs => [qw/subcomponent-rule/], action => 'do_subcomponent_list' },
{ lhs => 'subcomponent-list', rhs => [qw/subcomponent-list subcomponent-rule/], action => 'do_subcomponent_list' },
{ lhs => 'subcomponent-list', rhs => [qw//], action => 'do_subcomponent_empty_list' },
{ lhs => 'subcomponent-rule', rhs => [qw/subcomponent subcomponent-name/], action => 'do_subcomponent' },
Run Code Online (Sandbox Code Playgroud)
(帖子末尾的完整代码.)
这是我的意见:
$recce->read( 'component', );
$recce->read( 'String', 'MO …
Run Code Online (Sandbox Code Playgroud) 我一直在掌握Marpa解析器,当第一个符号是可选的时遇到了问题.这是一个例子:
use strict;
use warnings;
use 5.10.0;
use Marpa::R2;
use Data::Dump;
my $grammar = Marpa::R2::Scanless::G->new({source => \<<'END_OF_GRAMMAR'});
:start ::= Rule
Rule ::= <optional a> 'X'
<optional a> ~ a *
a ~ 'a'
END_OF_GRAMMAR
my $recce = Marpa::R2::Scanless::R->new({grammar => $grammar});
dd $recce->read(\"X");
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我收到以下错误:
Error in SLIF parse: No lexemes accepted at line 1, column 1
* String before error:
* The error was at line 1, column 1, and at character 0x0058 'X', ...
* here: X
Marpa::R2 exception at …
Run Code Online (Sandbox Code Playgroud) 我试图得到一个看似非常基本的Marpa语法工作.我使用的代码如下:
use strict;
use warnings;
use Marpa::R2;
use Data::Dumper;
my $grammar = Marpa::R2::Scanless::G->new(
{
source => \(<<'END_OF_SOURCE'),
:start ::= ExprSingle
ExprSingle ::= Expr AndExpr
Expr ~ word
AndExpr ~ word*
word ~ [\w]+
:discard ~ ws
ws ~ [\s]+
END_OF_SOURCE
}
);
my $reader = Marpa::R2::Scanless::R->new(
{
grammar => $grammar,
}
);
my $input = 'foo';
$reader->read(\$input);
my $value = $reader->value;
print Dumper $value;
Run Code Online (Sandbox Code Playgroud)
这打印$VAR1 = \'foo';
.所以它认出一个字就好了.但我希望它能识别出一串词
my $input='foo bar'
Run Code Online (Sandbox Code Playgroud)
现在脚本打印:
Error in SLIF G1 read: Parse exhausted, …
Run Code Online (Sandbox Code Playgroud) 在当前的Marpa解析器中的Scanless Interface(SLIF)实现中,词法分析器似乎以以下方式执行最长的令牌匹配(LTM):
当我的语法包含与最长子字符串匹配但无法在当前位置出现的标记时,这将导致令人沮丧的解析失败。考虑以下代码:
#!/usr/bin/env perl
use strict; use warnings; use feature qw/say/; use utf8;
use Marpa::R2;
use Data::Dump;
my @data = ('! key : value', '! key:value');
my $grammar = Marpa::R2::Scanless::G->new({
source => \<<'END_GRAMMAR',
:default ::= action => [values]
:start ::= record
:discard ~ ws
ws ~ [\s]+
record ::= ('!') key (':') value
key ~ [\w]+
value ~ [^\s]+
END_GRAMMAR
});
for my $data (@data) {
my $recce = Marpa::R2::Scanless::R->new({
grammar => $grammar, …
Run Code Online (Sandbox Code Playgroud)