AFAIK bạn không thể thiết lập các toán tử infix và xác định quyền ưu tiên vv trong ngữ pháp. Đây chỉ hiện áp dụng cho việc mở rộng Perl 6.
Đây là cách tiếp cận có thể có. Nó phân tích các cụm từ nhân trước khi bổ sung và cũng cho phép các từ hoặc ký hiệu, ví dụ: times
hoặc *
.
use v6;
grammar TestGrammar {
rule TOP { <expr=.add> }
rule add { <expr=.multiply> +% [ <add-op> ] }
rule multiply { <digit> +% [ <mult-op> ] }
proto token mult-op {*}
token mult-op:sym<times> { <sym>|'*' }
token mult-op:sym<divided> { <sym>|'/' }
proto token add-op {*}
token add-op:sym<plus> { <sym>|'+' }
token add-op:sym<minus> { <sym>|'-' }
}
sub MAIN() {
for ("2+2", "2 + 2", "1 * 2", "1 + 2 * 6", "4 times 7 minus 3") {
say $_;
my $match = TestGrammar.parse($_);
say $match;
}
}
Lưu ý rằng %
là các nhà điều hành tách. <digit> +% [ <mult-op> ]
là danh sách các chữ số được phân cách bởi toán tử nhân (times
, *
, divided
hoặc /
).
Giải pháp thay thế tháng 9 năm 2014:
S05 không đề cập rằng mặc dù các quy tắc và thẻ là phương pháp đặc biệt, cả hai có thể được khai báo là đa và một vài tham số giống như các phương pháp thông thường.
Cách tiếp cận này tận dụng lợi thế của cả đệ quy và đa công văn để thực hiện các mức ưu tiên của toán tử.
use v6;
grammar TestGrammar {
rule TOP { <expr(3)> }
# operator multi-dispatch, loosest to tightest
multi token op(3) {'+'|'-'|add|minus}
multi token op(2) {'*'|'/'|times|divided}
multi token op(1) {'**'}
# expression multi-dispatch (recursive)
multi rule expr(0) { <digit> | '(' ~ ')' <expr(3)> }
multi rule expr($pred) { <expr($pred-1)> +% [ <op($pred)> ] }
}
sub MAIN() {
for ("2+2", "2 + 2", "1 * 2", "1 + 2**3 * 6", "4 times (7 minus 3) * 3") {
say $_;
my $match = TestGrammar.parse($_);
say $match;
}
}
Vâng, đây là cách tiếp cận tiêu chuẩn mà tôi đã hy vọng tránh. Cuối cùng tôi muốn định nghĩa nhiều toán tử của riêng mình (postcircumfix, list, etc) và perl nghĩ sẽ xử lý điều này. Bạn có biết điều tương tự có đúng với [Parrot Grammar Engine] không (http://docs.parrot.org/parrot/latest/html/docs/book/pct/ch04_pge.pod.html)? – user2660278
Từ những gì Perl6 kế thừa HLL :: Grammar từ nqp, có thể phù hợp với bạn. Bạn cũng có thể thử hỏi về bản cập nhật Perl 6 irc - http://perl6.org/community/irc – dwarring
: hiện có một số tài liệu và ví dụ đã được thực hiện để triển khai HLL và các ngôn ngữ cụ thể của miền bằng cách sử dụng chuỗi công cụ NQP! Xem http://edumentab.github.io/rakudo-and-nqp-internals-course/slides-day1.pdf. Ví dụ làm việc bắt đầu xung quanh trang 118 – dwarring