제 뇌가 튀어서 프로덕션 규칙에서 일부 왼쪽 재귀를 제거하려고합니다. 나는 JavaCC에있는 컴파일러를 짓고 있어요 그리고 난 다음이 생성 규칙을 사용해야합니다간접적 인 왼쪽 재귀를 제거합니다.
expression := fragment ((+ | - | * | /) fragment)*
fragment := identifier | number | (+ | -) fragment | expression
을 그러나 문제는 단편 조각, 즉 관련이 표현과 관련이 있다는 것입니다 : 간접 왼쪽 재귀.
저는 인터넷을 둘러 보았고 모든 사람들이이 알고리즘을 사용하는 것으로 보입니다.이 알고리즘은 here입니다.
void expression(): {}
{
fragment()
(
(<PLUS>|<MINUS>|<DIVIDE>|<ASTERISKS>)
fragment()
)*
}
void k(): {}
{
(
((<PLUS>|<MINUS>|<DIVIDE>|<ASTERISKS>)fragment())*k()
| fragment()
)
}
void fragment(): {}
{
(
<ID>k()
| number()k()
| (<PLUS>|<MINUS>)fragment()k()
)
}
그들은 JavaCC에 사용되는 코드로 작성하는 것은 너무 잘하면 당신이 그들을 이해할 수있다 : 그 사이트는이 같은 규칙을 끝낼 here
찾을 수 있습니다 직접 왼쪽 재귀 제거를 설명하지 않습니다 . 기본적으로 나는 K의 처음 부분은 아무 것도 없어 질 수 있기 때문에 문제가 여전히 존재한다는 것을 제외하고는 재귀를 다루기 위해 규칙 K를 도입했다. 왜냐하면 더 많이 남아있는 K -> k()로 당신을 떠나는 * (0 번 이상)이기 때문이다. 재귀 !!
여기에서 어디로 가야할지 모르고 머리를 많이 잃었습니다. 모든 통찰력은 인정 될 것입니다! 다음과 같이
대개 'term','expression' 그리고 터미널 심볼을 가질 수 있습니다. 왜 여기서 충분하지 않습니까? –
'fragment '가 잘못 정의 된 것 같습니다. 'expression : = ... '('expression ')''과 같은 식의 괄호 사이에 'expression'이 나타나면 안됩니까? 그렇지 않으면'fragment' 레벨에서'expression'을 갖는 것은 의미가 없습니다. 특히 JavaCC에 익숙하지는 않지만 다른 파서 생성기에서는 문제가 될 수 있습니다. – user1201210
나는 똑같은 것을 tenterhook라고 생각하고 있었다. 프래그먼트의 '표현식'이 사용되는 경우를 생각할 수 없습니다. 그러나 그들이 강사로 결정되면서 규칙은 꽤 많이 던져졌습니다. 아마도 나는 그에게 연락해야 할까? H2CO3 : 조금 더 설명해 주시겠습니까? '용어'규칙을 만들어야한다는 뜻입니까? 무엇이 포함됩니까? 나는 실제로 그물 주위에'term'을 사용하는 사람들을 보았지만 그 알고리즘을 따르는 것이 더 좋을 것이라고 생각했습니다. – carlmango11