2013-09-05 3 views
5

Ich habe mich mit dem Marpa-Parser beschäftigt und ein Problem festgestellt, wenn das erste Symbol optional ist. Hier ein Beispiel:Marpa-Parser scheint mit dem optionalen ersten Symbol nicht zurecht zu kommen?

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"); 

Als ich das laufen, bekomme ich folgende Fehlermeldung:

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 small.pl line 20 
at /usr/local/lib/perl/5.14.2/Marpa/R2.pm line 126 
     Marpa::R2::exception('Error in SLIF parse: No lexemes accepted at line 1, column 1\x{a}...') called at /usr/local/lib/perl/5.14.2/Marpa/R2/Scanless.pm line 1545 
     Marpa::R2::Scanless::R::read_problem('Marpa::R2::Scanless::R=ARRAY(0x95cbfd0)', 'no lexemes accepted') called at /usr/local/lib/perl/5.14.2/Marpa/R2/Scanless.pm line 1345 
     Marpa::R2::Scanless::R::resume('Marpa::R2::Scanless::R=ARRAY(0x95cbfd0)', 0, -1) called at /usr/local/lib/perl/5.14.2/Marpa/R2/Scanless.pm line 926 
     Marpa::R2::Scanless::R::read('Marpa::R2::Scanless::R=ARRAY(0x95cbfd0)', 'SCALAR(0x95aeb1c)') called at small.pl line 20 

Perl Version 5.14.2 (debian sid)
Marpa Version 2,068000

(ich sehe es gibt eine brandneue Marpa 2.069, die ich noch nicht ausprobiert habe)

Ist das etwas, was ich in meiner Grammatik falsch mache?

Antwort

6

In Marpa Scanless hat Ihre Grammatik zwei Ebenen: Die Hauptgrammatik auf hoher Ebene, auf der Sie Aktionen und ähnliches zuordnen können, und die Grammatik auf niedriger Ebene. Sie werden unabhängig ausgeführt (was erwartet wird, wenn Sie traditionelle Parser/Lexer verwendet haben, aber sehr verwirrend sind, wenn Sie von Regexes zu Marpa kommen).

Jetzt auf der niedrigen Grammatik, Marpa erkennt Ihre Eingabe als eine einzige X, nicht "Null a s und dann ein X". Die High-Level-Grammatik erfordert jedoch das optional a Symbol vorhanden zu sein.

Es bester Weg, um das ist die a optional in der High-Level-Grammatik zu machen:

<optional a> ::= <many a> 
<optional a> ::= # empty 

<many a> ~ a* # would work the same here with "a+" 
a ~ 'a' 
+2

amon es Recht hat. Ein Lexem kann niemals eine Länge von Null haben, also selbst wenn Sie ein * verwenden, hat es den Effekt eines +. Ich überlegte, Lexeme zu verbieten, die mit der Länge Null übereinstimmen, aber es ist oft sehr praktisch, das Lexem so zu schreiben. –

+0

+1: Danke dafür. Ich habe diese Unterscheidung der G0/G1-Regeln hier übersehen. Ihre Änderung funktionierte für mein Beispiel. –

+1

@ JeffreyKegler: BTW, als ich mein Beispiel vorbereitete, schrieb ich versehentlich die letzte G0-Regel als "a ~ a". Ich weiß, das kann nicht funktionieren, aber ich habe einen SEGV-Fehler und keine Nachricht. Würdest du das erwarten? –

Verwandte Themen