2013-09-05 27 views
5

Tôi đã nắm bắt được trình phân tích cú pháp Marpa và gặp phải sự cố khi biểu tượng đầu tiên là tùy chọn. Dưới đây là một ví dụ:Trình phân tích cú pháp Marpa dường như không thể đối phó với biểu tượng đầu tiên tùy chọn?

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

Khi tôi chạy này, tôi nhận được lỗi sau:

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 phiên bản 5.14.2 (debian khò khè)
phiên bản Marpa 2,068000

(tôi thấy có một Marpa 2.069 hoàn toàn mới mà tôi chưa thử)

Đây có phải là điều tôi đang làm sai trong ngữ pháp của mình không?

Trả lời

6

Trong Marpa Không quét, ngữ pháp của bạn có hai cấp độ: Ngữ pháp chính, cấp cao nơi bạn có thể phân bổ hành động và ngữ pháp lexing cấp thấp. Chúng được thực hiện độc lập (được mong đợi nếu bạn đã sử dụng các trình phân tích cú pháp/lexers truyền thống, nhưng rất khó hiểu khi bạn đến từ các regex đến Marpa).

Bây giờ trên ngữ pháp cấp thấp, Marpa nhận ra đầu vào của bạn dưới dạng một đơn X, không phải là "số a s và sau đó là X". Tuy nhiên, ngữ pháp cấp cao yêu cầu phải có biểu tượng optional a.

Có tốt nhất Để tránh điều này để làm cho a tùy chọn trong ngữ pháp cao cấp:

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

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

amon có nó ngay. Một lexeme không bao giờ có độ dài bằng 0, vì vậy ngay cả khi bạn sử dụng dấu *, nó sẽ có hiệu ứng của dấu +. Tôi đã xem xét cấm các từ vựng phù hợp với độ dài bằng không, nhưng thường rất thuận tiện để viết lexeme theo cách đó. –

+0

+1: Cảm ơn vì điều đó. Tôi bỏ qua sự phân biệt quy tắc G0/G1 ở đây. Sửa đổi của bạn đã làm việc cho ví dụ của tôi. –

+1

@ JeffreyKegler: BTW khi tôi đang chuẩn bị ví dụ của mình, tôi đã vô tình viết quy tắc G0 cuối cùng là 'a ~ a'. Tôi nhận ra điều này không thể làm việc nhưng tôi nhận được một lỗi SEGV chứ không phải là một tin nhắn. Bạn có mong đợi điều này? –

Các vấn đề liên quan