Разбор на низови литерали в Prolog

Използвам определена граматика на клауза, за да анализирам низови литерали в Prolog, но това граматично правило може да анализира само низови литерали, които съдържат буквени знаци:

string_literal(S) --> "\"", symbol(S), "\"".
symbol([L|Ls]) --> letter(L), symbol_r(Ls).
symbol_r([L|Ls]) --> letter(L), symbol_r(Ls).
symbol_r([])     --> [].
letter(Let)     --> [Let], { code_type(Let, alpha) }.

Възможно ли е да се напише DCG правило, което може да анализира низови литерали с други типове символи?


person Anderson Green    schedule 24.03.2016    source източник


Отговори (1)


В SWI-Prolog библиотека(dcg/basics) има няколко готови за използване нетерминали. Кодът си струва да се проучи...

В противен случай, за да обобщите малко, можете да предадете типа код на съвпадението, след което да комбинирате примитивите по желание:

char(Type, C) --> [C], { code_type(C, Type) }.

letter(L) --> char(alpha, L).
digit(D) --> char(digit, D).
lower_or_num(C) --> char(lower, C) | digit(C).
...

възможност за пропускане на нежелани знаци (само нов ред или единични кавички)

string_literal(S) --> "\"", string_inner(S).

string_inner([]) --> "\"".
string_inner(Cs) --> [C],
    { ( C == 0'\n ; C == 0'' ) -> Cs = Rs ; Cs = [C|Rs] },
    string_inner(Rs).

редактиране

предотвратява съвпадението на низове, които съдържат двойни кавички

конструкцията if -> then ; else се проваля, ако пропуснем клона else, а if е невярно, така че опитът може да бъде:

...
{ ( C == 0'\n ; C == 0'' ) -> Cs = Rs ; C \== 0'" -> Cs = [C|Rs] },
...
person CapelliC    schedule 24.03.2016
comment
Би ли било възможно да се изключат кавички и нови редове от литерала на низа, като същевременно се разрешава всеки друг тип символ? - person Anderson Green; 24.03.2016
comment
разбира се, но какво искате да направите, когато са намерени кавички и/или нов ред? хвърлям изключение или ги пропускам? - person CapelliC; 24.03.2016
comment
Има още един проблем с този DCG. Как мога да го предотвратя от съпоставяне на низове, които съдържат двойни кавички без екраниращи знаци, като "hello" string"? - person Anderson Green; 02.04.2016
comment
Мисля, че има концептуален проблем за решаване преди да се заровим в подробности: тъй като двойните кавички са разделители, синтаксисът става двусмислен. Но игнорирайки това, вижте моята редакция. - person CapelliC; 02.04.2016
comment
В повечето езици за програмиране низовите литерали могат да съдържат кавички, предшествани от обратна наклонена черта, като \" или '\'. Реализацията по-горе не анализира правилно тези низове. - person Anderson Green; 06.05.2016
comment
@AndersonGreen: всъщност това е хубаво упражнение, оставено на вас, за да разширите DCG - до сърцето си. Това е много просто приложен Prolog. - person CapelliC; 06.05.2016