문제

나는 구문이 있습니다

%(var)

그리고

%var

그리고 (var)

내 규칙은 같은 것입니다

optExpr:
    | '%''('CommaLoop')'
    | '%' CommaLoop

CommaLoop:
    val | CommaLoop',' val

Expr:
    MoreRules
    | '(' val ')'

문제는) %(CommaLoop) 또는 % (val) 그러나 그것은 (도대체가 무엇입니까? (? 오류를 어떻게 해결해야합니까? 나는 생각한다 %( 토큰은 좋은 솔루션이지만 이유를 확신하고 싶습니다. $( 이 작업을 수행하기 전에 오류가 아닙니다.

도움이 되었습니까?

해결책

이것은 LR Parsing이 작동하는 방식 때문입니다. LR 파싱은 효과적으로 상향식으로, 문법 규칙의 RHS에 따라 토큰을 함께 그룹화하고 LHS로 대체합니다. 파서가 '이동'하면 스택에 토큰을 넣지 만 실제로는 규칙과 일치하지 않습니다. 대신, 현재 상태를 통해 부분적으로 일치하는 규칙을 추적합니다. 규칙의 끝에 해당하는 상태에 도달하면 스택에서 RHS의 기호를 팝업하고 LHS를 나타내는 단일 기호를 뒤로 밀 수 있습니다. 따라서 갈등이있는 경우, 파서가 어떤 규칙의 끝까지 도달 할 때까지 나타나지 않으며 감소 할 것인지 (또는 감소 할 것인지)를 결정할 수 없습니다.

당신의 예에서, 본 후 % ( , 그것이 스택에있을 것입니다 (상단은 오른쪽에 있습니다). 전망대가있을 때 ), 그것은 규칙을 통해 발을 터야하고 줄여야하는지 결정할 수 없습니다. Commaloop : Val, 또는 이동 해야하는 경우 ) 그러면 3 가지를 튀기고 규칙에 따라 줄일 수 있습니다. expr : '('val ')'

여기에 다음과 같은 추가 규칙이 있다고 가정합니다. commaloop : expr, 그렇지 않으면 문법은 실제로 아무것도 일치하지 않으며 Bison/YACC는 사용하지 않은 비 터미널에 대해 불평 할 것입니다.

다른 팁

지금, 당신의 설명과 문법은 일치하지 않는 것 같습니다. 당신의 설명에서, 당신은 세 가지 문구를 모두 'var'인 것으로 표시하지만, 문법은 '%'로 시작하는 문법이 쉼표로 구분 된 목록을 허용하는 것으로 표시되며, 하나는 단일 'val'만 허용합니다.

현재, 나는 세 가지 모두 쉼표로 구분 된 목록을 허용해야한다고 가정 할 것입니다. 이 경우, 나는 다음과 같은 문법을 더 고려합니다.

optExpr: '%' aList

aList: CommaLoop
    | parenList

parenList: '(' CommaLoop ')'

CommaLoop: 
    | val 
    | CommaLoop ',' val

Expr: MoreRules
    | parenList

나는 optexpr과 expr을 변경 했으므로 빈 순서와 일치 할 수는 없습니다. 제 생각에는 아마도 당신이 시작하려고하지 않았을 것입니다. 나는 이것을 BYACC를 통해 실행할만큼 충분히 살았습니다. 경고 나 오류가 발생하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top