Prolog-반복 알고리즘을 재귀로 변환 (함수 파서)

도디 신

이런 종류의 함수를 구문 분석하는 함수 파서를 작성하고 있습니다.

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

문자열이 언어에서 허용되는지 확인하기 전에 목록으로 변환 한 다음 DCG 규칙으로 보냅니다. 나는 그것을 위해 이것을 썼다.

is_funct(A) :- term_to_atom(A, X), atom_chars(X, L), phrase(expr, L).

문제는 코드가 매우 잔인하고 모든 문자를 목록에 포함하므로 서명이나 문자가 한 문자보다 길거나 중첩 된 함수가있는 경우 작동하지 않습니다. 청킹에 대한 올바른 알고리즘은 다음과 같습니다.

List L, Z;
String F;

for(int i=0; i<L.length; i++){
  if(L[i]=="(" || L[i]==","){
    for(int j=i; L[j]!=")"||L[j]!=","; j++)
      F+=L[j];
    Z.append(F);
    if(Z[j-1]==")") Z.append(")");
  }
}

또는 쉼표 나 여는 대괄호를 찾을 때까지 목록을 스크롤 한 다음, 다른 대괄호 나 쉼표를 찾을 때까지 찾은 모든 문자로 문자열을 만들고 목록에 문자열을 추가하고 브래킷도 찾았습니다. 그래서 당신은 다음과 같은 것을 얻을 것입니다

[foo, "(", bar, fizz, "(", buzz, ")", hello, ")"]

올바르게 다음 언어에서 허용되는지 확인합니다.

이 알고리즘을 Prolog에서 재귀 적으로 어떻게 정확하게 번역합니까? 나는 해결책을 구상하려고 시도했다.

1) Split term at every comma (,) and put splitted strings in L
2) Find index of every bracket for ever element of L and split on the brackets
3) Reinsert brackets into list at the indexes saved

그러나 올바른 방법으로 들리지 않으며 재귀 적이지도 않습니다!

문자열을 구문 분석하는 올바른 방법은 무엇입니까? 미리 감사드립니다!

Daniel Lyons

여기에 당신이 묻는 것에 근거하여 당신의 문제에 접근하는 방법이 있습니다. 귀하의 질문은 내가 잘못된 접근 방식이라고 생각하는 기술적 세부 사항에 대해 무겁기 때문에 이것이 올바른 방향인지는 확실하지 않지만 내가 얻은 것입니다.

먼저, 문법이 정말 다음과 같다고 생각합니다.

function ::= name '(' termlist ')'.
termlist ::= [] | nonemptytermlist.
nonemptytermlist ::= term | term ',' nonemptytermlist.
term     ::= name
          |  function.
name     ::= [A-Za-z][A-Za-z0-9_-]*

우리는 여기서 Prolog를하고 있습니다. 그래서 여러분이 생각 해낼 수있는 가장 "선언적인"문제는 여러분이 코딩하고 싶은 것입니다. 그 후에야 최적화를 시도하고 싶습니까? BNF 문법은 Prolog에서 매우 일반적이므로 언어에 대한 지원이 내장되어 있습니다 : 명확한 절 문법.

이 문법에는 재귀가 있지만 일반적으로 첫 번째 또는 맨 왼쪽 위치가 아닌 올바른 위치에있는 한 문법에서는 큰 문제가 아닙니다 . 이것은 EBNF-ish로, DCG 표기법으로 상당히 쉽게 변환되어야합니다.

function --> fname, "(", termlist, ")".
termlist --> [] | nonemptytermlist.
nonemptytermlist --> term | term, ",", nonemptytermlist.
term    --> fname | function.
fname    --> [C], { char_type(C, alpha) }, namebody.
namebody --> [C], { char_type(C, alnum) ; C = '_' ; C = '-' }, namebody.
namebody --> [].

이것은 실제로 작동하는 것처럼 보이지만 그다지 유용하지는 않습니다.

?- atom_codes("foo(this,bar(that),another)", X), phrase(function, X).
X = [102, 111, 111, 40, 116, 104, 105, 115, 44|...] ;

여기서는 명확하지 않을 수 있지만 functionDCG 규칙 으로이 문장을 성공적으로 구문 분석했습니다 . 당신은 아무것도 다시 얻지 못하고 있습니다. 따라서 다음으로 할 일은 문법 규칙이 원하는 구조를 구축하도록하는 것입니다.

function(F) -->
    fname(Name),
    "(", termlist(List), ")",
    { F =.. [Name|List] }.

termlist([])   --> [].
termlist(List) --> nonemptytermlist(List).

nonemptytermlist([X])    --> term(X).
nonemptytermlist([X|Xs]) --> term(X), ",", nonemptytermlist(Xs).

term(Term)     --> fname(Term).
term(Function) --> function(Function).

fname(Name)    --> [C], { char_type(C, alpha) }, namebody(Cs),
    { atom_codes(Name, [C|Cs]) }.

namebody([C|Cs]) -->
    [C],
    { char_type(C, alnum) ; C = '_' ; C = '-' },
    namebody(Cs).
namebody([]) --> [].

여기서 우리가 한 모든 것은 가볍게 재구성하고 각 규칙에 의해 구문 분석 된 DCG 규칙 인수 값을 통해 다시 전달하는 것입니다. 이제 복잡한 구조를 성공적으로 구문 분석하는 것을 볼 수 있습니다.

?- atom_codes("foo(this,bar(qwerty,uiop),that(),little())", X), phrase(function(F), X).
X = [102, 111, 111, 40, 116, 104, 105, 115, 44|...],
F = foo(this, bar(qwerty, uiop), that, little)

문법이 문자열을 프롤로그 용어로 성공적으로 변환했습니다. 불행히도 Prolog는 그다지 중요하지 않으므로 foo()괄호가 삭제되었습니다. 이는 =..함수 이름과 인수 목록을 Prolog 구조로 변환하는 데 사용 하는 "univ"연산자 때문입니다. Prolog 구조가 처리하기에 충분히 쉽지 않은 경우 일 수 있습니다. 이 경우 function다음과 같이 "univ"단계를 제거하십시오 .

function([Name|List]) -->
    fname(Name),
    "(", termlist(List), ")".

그것을 사용하면 다음이 반환됩니다.

?- atom_codes("foo(this,bar(qwerty,uiop),that(),little())", X), phrase(function(F), X).
X = [102, 111, 111, 40, 116, 104, 105, 115, 44|...],
F = [foo, this, [bar, qwerty, uiop], [that], [little]] ;
false.

여전히 용어를 빈 함수와 구별 할 수 없습니다. term//1좀 더 명시 적으로 만들어서 해결할 수 있습니다 .

function(Name, Args) -->
    fname(Name),
    "(", termlist(Args), ")".
% ...
term(term(Term))           --> fname(Term).
term(function(Name, Args)) --> function(Name, Args).

효과는 훨씬 더 장황합니다.

?- atom_codes("foo(this,bar(qwerty,uiop),that(),little())", X), phrase(function(F,A), X).
X = [102, 111, 111, 40, 116, 104, 105, 115, 44|...],
F = foo,
A = [term(this), function(bar, [term(qwerty), term(uiop)]), function(that, []), function(little, [])]

처리하기가 더 쉬울 수도 있고 어려울 수도 있습니다. 내가 경험하는 법칙은 가능한 한 Prolog 구조에 가깝게 유지하는 것이지만 이로 인해 불편할 수 있습니다.

어쨌든 이것이 도움이되기를 바랍니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

반복 함수를 재귀로 변환

분류에서Dev

파이썬에서 치환이있는 순열을위한 재귀 함수 알고리즘

분류에서Dev

재귀 가변 템플릿 함수를 반복으로 변환

분류에서Dev

재귀 함수를 반복 함수로 변환하려면 스택을 언제 사용해야합니까?

분류에서Dev

이 반복 함수를 재귀로 변환

분류에서Dev

재귀 순열 함수를 반복으로 변환하는 Python

분류에서Dev

재귀 함수를 반복으로 변환

분류에서Dev

파이썬에서 집합을 목록으로 변환하는 알고리즘 복잡성

분류에서Dev

재귀 메서드 (재귀가 루프 내에서 수행됨)를 반복 메서드로 변환

분류에서Dev

반복을 함수로 변환

분류에서Dev

이 재귀 파티션 알고리즘이 빈 배열을 반환하는 이유는 무엇입니까?

분류에서Dev

반복 함수 Java에 대한 더 많은 호출로 재귀 함수 변환

분류에서Dev

서로 더할 때 X와 같은 정수 쌍 목록을 반환하는 Erlang 알고리즘

분류에서Dev

GC Overhead Limit Exceeded 오류를 방지하기 위해 재귀 조합 찾기 알고리즘을 반복으로 변환

분류에서Dev

변수 알고리즘을 기반으로 배열 결과 정렬-MYSQL & PHP

분류에서Dev

키 값을 일치시키고 중첩 사전에서 경로를 반환하는 Python 재귀 함수

분류에서Dev

재귀 함수에서 매개 변수로 전달 된 일반 함수 호출

분류에서Dev

재귀 함수 호출에서 현재 함수 값을 반환하는 방법

분류에서Dev

튜플을 반환하는 재귀 함수 파이썬

분류에서Dev

재귀 : 재귀 함수에서 값 -1을 반환하는 방법

분류에서Dev

반복 함수를 변환하는 자바 재귀 할

분류에서Dev

재귀 함수에서 값 반환

분류에서Dev

알파 베타 가지 치기로 다른 값을 반환하는 minimax 알고리즘

분류에서Dev

파이썬 : for 루프를 재귀 함수로 변환

분류에서Dev

재귀 알고리즘 시간 복잡성 : 코인 변경

분류에서Dev

종속 변수를 처리하는 재귀 알고리즘

분류에서Dev

이 재귀 함수를 반복 함수로 변환하는 방법은 무엇입니까?

분류에서Dev

이 재귀 함수를 반복 함수로 변환하는 방법은 무엇입니까?

분류에서Dev

정렬 된 순서로 5로 나눌 수있는 요소 배열을 반환하는 알고리즘을 만드는 데 도움이 필요합니다.

Related 관련 기사

  1. 1

    반복 함수를 재귀로 변환

  2. 2

    파이썬에서 치환이있는 순열을위한 재귀 함수 알고리즘

  3. 3

    재귀 가변 템플릿 함수를 반복으로 변환

  4. 4

    재귀 함수를 반복 함수로 변환하려면 스택을 언제 사용해야합니까?

  5. 5

    이 반복 함수를 재귀로 변환

  6. 6

    재귀 순열 함수를 반복으로 변환하는 Python

  7. 7

    재귀 함수를 반복으로 변환

  8. 8

    파이썬에서 집합을 목록으로 변환하는 알고리즘 복잡성

  9. 9

    재귀 메서드 (재귀가 루프 내에서 수행됨)를 반복 메서드로 변환

  10. 10

    반복을 함수로 변환

  11. 11

    이 재귀 파티션 알고리즘이 빈 배열을 반환하는 이유는 무엇입니까?

  12. 12

    반복 함수 Java에 대한 더 많은 호출로 재귀 함수 변환

  13. 13

    서로 더할 때 X와 같은 정수 쌍 목록을 반환하는 Erlang 알고리즘

  14. 14

    GC Overhead Limit Exceeded 오류를 방지하기 위해 재귀 조합 찾기 알고리즘을 반복으로 변환

  15. 15

    변수 알고리즘을 기반으로 배열 결과 정렬-MYSQL & PHP

  16. 16

    키 값을 일치시키고 중첩 사전에서 경로를 반환하는 Python 재귀 함수

  17. 17

    재귀 함수에서 매개 변수로 전달 된 일반 함수 호출

  18. 18

    재귀 함수 호출에서 현재 함수 값을 반환하는 방법

  19. 19

    튜플을 반환하는 재귀 함수 파이썬

  20. 20

    재귀 : 재귀 함수에서 값 -1을 반환하는 방법

  21. 21

    반복 함수를 변환하는 자바 재귀 할

  22. 22

    재귀 함수에서 값 반환

  23. 23

    알파 베타 가지 치기로 다른 값을 반환하는 minimax 알고리즘

  24. 24

    파이썬 : for 루프를 재귀 함수로 변환

  25. 25

    재귀 알고리즘 시간 복잡성 : 코인 변경

  26. 26

    종속 변수를 처리하는 재귀 알고리즘

  27. 27

    이 재귀 함수를 반복 함수로 변환하는 방법은 무엇입니까?

  28. 28

    이 재귀 함수를 반복 함수로 변환하는 방법은 무엇입니까?

  29. 29

    정렬 된 순서로 5로 나눌 수있는 요소 배열을 반환하는 알고리즘을 만드는 데 도움이 필요합니다.

뜨겁다태그

보관