2017-02-03 3 views
1

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

<fsignature>"(" <term1>, <term2> ... <termn>")" 

Функция»подпись и условие также должно контролироваться в дальнейшем для функции будет принята. Я написал этот DCG в Prolog:

fsign --> {is_leg(A)}, [A]. 
terms --> (funct, funct; terms). 
terms --> (terms, terms; term). 
term --> {is_term(T)}, [T]. 

Но это, кажется, не работает, когда я пытаюсь использовать фразу (функц [Foo, "(", а, а, ")"]). он переходит в переполнение. is_leg просто проверяет, является ли строка законной (строка начинается с символа), а is_term должен проверить, является ли этот термин литералом (константа, переменная или функция).

Что это не работает? Я полагаю, вероятно, переменные - должен ли я ставить их как аргументы нетерминалов?

Спасибо за любую помощь.

+5

Что-то вроде «термины -> (термины, термины; термин).» - это то же самое, что: «термины -> термины, термины.» И «термины -> термин». Первое, очевидно, быть бесконечной рекурсией. Непонятно, что вы хотите, чтобы это правило говорило. – lurker

+0

Функции могут иметь arity n, поэтому у него может быть бесконечное количество аргументов, поэтому я ввел это правило. Язык должен быть бесконечным, но он должен сказать мне, какие строки приняты, а какие нет, не так ли? – Dodicin

+1

Вы не имеете в виду, что у вас будет бесконечное количество аргументов, не так ли? Вы действительно имеете в виду, что оно может иметь * любое * количество аргументов, но любой заданный член имеет конечное число. Там просто нет предела тому, сколько. В какой-то момент синтаксический разбор должен заканчиваться, то есть входная последовательность имеет конечное число элементов. – lurker

ответ

3

Если ваши выражения все выглядеть следующим образом:

<fsignature> "(" <term1> <term2> ... <termn> ")" 

Тогда пишу это в терминах ВСО, он должен выглядеть следующим образом (минус любая проверка строки предикаты вы предлагаете):

expression --> fsignature, ['('], terms, [')']. 
fsignature --> ...  % whatever fsignature looks like 
terms --> term.   % "terms" is a single term, or... 
terms --> terms, term. % ... more terms followed by a single term. 
term --> ...   % whatever a term looks like 

Вы также можете написать определение terms как:

terms --> term | terms, term. 

Обратите внимание, что нерекурсивное определение terms происходит до рекурсивного. Кроме того, определение для terms выше предполагает, что у вас должен быть хотя бы один термин (это требование не было указано в вашем вопросе).

+0

Вот и все, я очень благодарен! Правило 'terms -> terms, terms' было неправильным, я рассуждал, удваивая количество терминов в функции, а не увеличивая его с помощью одного термина в каждой рекурсии - мои рассуждения были неправильными в любом случае. Большое спасибо за ваше время! – Dodicin

+0

@ Dodicin рад, что это было полезно! Кстати, чтобы сделать фрагмент кода в вашем комментарии, используйте обратные тики. :) – lurker

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