2015-11-13 5 views
1

Я представляю программу, которая принимает аргумент (атом). Затем расщепляет его на части, как это определено в программе, например, я хотел быКак определить, содержит ли атом дополнительный атом в Prolog

func(argv) :- 
    atom_split(argv,'else:',Commands), 
    atom_split(argv,'+',Commands), 
    atom_split(argv,'==',Commands), 
    atom_split(argv,'>',Commands), 
    atom_split(argv,'<',Commands), 
    atom_split(argv,'!=',Commands), 

расщеплять атом в его основных частей, предпочтительно в порядке очереди для разбора позже. Кроме того, не все части обязательно будут частью входного атома, что добавит его сложности. В идеале, в конце концов, я бы стек с отдельными частями атома раздельным, например

func('A+B==C'). 
func(argv) :- 
    atom_split(argv,'else:',Commands), 
    atom_split(argv,'+',Commands), 
    atom_split(argv,'==',Commands), 
    atom_split(argv,'>',Commands), 
    atom_split(argv,'<',Commands), 
    atom_split(argv,'!=',Commands), 

Commands = [A,+,B,==,C]. 

я затем использовать эти команды, чтобы сказать, если что-то вписывается в грамматике:

?- func(‘E+d;’). 
true. 
?-func(‘if:a and b’). 
false. 
+2

Обратите внимание, что 'atom_split/3' специфичен для некоторых реализаций - и не полностью определен. Стандарт ИСО представлен в [8.16] (http://www.complang.tuwien.ac.at/ulrich/iso-prolog/prologue#8.16): 'sub_atom/5',' atom_concat/2'. – false

ответ

3

Простой ответ: используйте sub_atom/5. Он должен быть доступен в каждой реализации Prolog.

Но ваш подход очень сомнительный. Вы уверены, что ваши выражения должны быть атомами? С верхнего уровня Prolog (интерпретатор) вы уже можете бесплатно получить парсинг большинства выражений, которые вы показываете в вопросе. Например:

?- Expr = (a + b == c), write_canonical(Expr). 
==(+(a,b),c) 
Expr = (a+b==c). 

В этом примере каждый из =, + и == уже определены как операторы Пролога, так что-то вроде a + b == c на самом деле действительный член Пролога. Вы можете, конечно, define your own operators.

Другой вариант - написать правильный «парсер» для выражений, который не слишком сложный в Prolog. Вероятно, вы можете начать, сделав свое выражение list of chars or a list of codes. Затем то, что вам кажется, является токенизатором, возможно, проще всего реализовать в более удобном DCG notation. Я думаю, что для этого нужно найти примеры кода, и ваш вопрос, поскольку он в настоящий момент не предоставляет достаточной информации, чтобы попытаться показать фактический код для выполнения токенизации или синтаксического анализа.

+0

Я вижу, что вы говорите, однако я использую BNF для определения правильности заданного синтаксиса, поэтому мне нужно уметь разбивать все на базовую форму, на которую я верю. Мне нужно сказать что-то вроде '? - func ('E + d;'). правда. ? -func ('if: a и b'). false.' –

Смежные вопросы