Разбор строковых литералов в Прологе

Я использую грамматики с определенными предложениями для разбора строковых литералов в Прологе, но это грамматическое правило может анализировать только строковые литералы, содержащие алфавитные символы:

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. Как я могу предотвратить сопоставление строк, содержащих двойные кавычки без escape-символов, таких как "hello" string"? - person Anderson Green; 02.04.2016
comment
Я думаю, что есть концептуальная проблема, которую нужно решить прежде чем углубляться в детали: поскольку двойные кавычки являются разделителями, синтаксис становится двусмысленным. Но игнорируя это, см. мое редактирование. - person CapelliC; 02.04.2016
comment
В большинстве языков программирования строковые литералы могут содержать кавычки, которым предшествует обратная косая черта, например \" или '\'. Приведенная выше реализация неправильно анализирует эти строки. - person Anderson Green; 06.05.2016
comment
@AndersonGreen: на самом деле, вам осталось хорошее упражнение, чтобы расширить DCG - до вашего сердца. Это очень простой прикладной Пролог. - person CapelliC; 06.05.2016