Exception handling in parser implemented using Marpa::R2

时间:2018-04-20 01:01:00

标签: perl error-handling exception-handling syntax-error marpa

I have implemented a parser using Marpa::R2. Code appears like below:

I have a large number of test cases in a .t file, which i run to test my parser. So, if any exception arises in any of the input expression, testing shouldn't stop in mid and it should give proper error message for the one which has given an error (using exception handling) and rest of the test cases should run.

I want to do exception handling in this parser. If any sort of exception arrises even while tokenizing the input expression, I want to show appropriate message to the user, saying the position, string etc or any more details to show where the error came. Please help.

use strict;
use Marpa::R2;
use Data::Dumper;

my $grammar = Marpa::R2::Scanless::G->new({
    default_action => '[values]',
    source => \(<<'END_OF_SOURCE'),
    lexeme default = latm => 1

:start ::= expression

expression ::= expression OP expression
expression ::= expression COMMA expression
expression ::= func LPAREN PARAM RPAREN
expression ::= PARAM
PARAM ::= STRING | REGEX_STRING
REGEX_STRING ::= '"' QUOTED_STRING '"'

:discard    ~ sp
sp          ~ [\s]+

COMMA                      ~ [,]
STRING                     ~ [^ \/\(\),&:\"~]+
QUOTED_STRING              ~ [^ ,&:\"~]+
OP                         ~ ' - ' | '&'
LPAREN                     ~ '('
RPAREN                     ~ ')'
func                       ~ 'func'

END_OF_SOURCE
});

my $recce = Marpa::R2::Scanless::R->new({grammar => $grammar});
print "Trying to parse:\n$input\n\n";
$recce->read(\$input);
my $value_ref = ${$recce->value};
print "Output:\n".Dumper($value_ref);

my $input4 = "func(\"foo\")";

I want to do Proper error handling like :http://blogs.perl.org/users/jeffrey_kegler/2012/10/a-marpa-dsl-tutorial-error-reporting-made-easy.html

I dont know how to put all this stuff in place.

1 个答案:

答案 0 :(得分:1)

exception handler中包裹可能失败的行:

use Try::Tiny;
⋮
try {
    $recce->read(\$input);
    my $value_ref = ${$recce->value};
    print "Output:\n".Dumper($value_ref);
} catch {
    warn $_;
};

来自Marpa的完整错误消息将在$_中,它是一个包含换行符的长字符串。我选择使用warn将其打印到STDOUT,程序继续运行。正如您在下面的示例错误消息中所看到的,它包含解析失败的位置:

Error in SLIF parse: No lexeme found at line 1, column 5
* String before error: "fo\s
* The error was at line 1, column 5, and at character 0x006f 'o', ...
* here: o"
Marpa::R2 exception at so49932329.pl line 41.

如果需要,可以重新格式化,以便用户看起来更好。