2014-05-09 1 views
2

Yacc을 사용하여 작성한 문법이 있습니다. 문법의 관련 부분은 접미사 정의를 보면 당신은 내가 네 번째 규칙의 기간에 큰 따옴표를 가지고 있음을 알 수 있습니다 여기에Yacc/Bison 단일 및 이중 인용문 리터럴의 차이점

postfix 
    : primary 
    | postfix '[' expr ']' 
    | postfix '[' expr ':' expr ']' 
    | postfix "." STRING 
    | postfix '(' ')' 
    | postfix '(' args ')' 
    ; 

unary 
    : postfix 
    | '!' unary 
    | '-' unary 
    | '+' unary 
    ; 

발췌. 나는 이것을 가져야했는데 왜냐하면 나는 그것없이 shift/reduce 충돌을 얻었 기 때문이다. 나는 시프트/감소 충돌이 사용 된 따옴표 유형을 변경할 때 사라지는 이유에 대해 약간 혼란스러워하며 내가 놓친 부분이 여기에 있다고 의심합니다. 누구나이 인용문의 차이점을 설명 할 수 있고 사용해야하는 것이 있다면 그것을 고맙게 생각합니다.

답변

4

들소에서는 작은 따옴표와 큰 따옴표가있는 리터럴이 서로 다른 토큰을 사용한다는 점에서 서로 다릅니다. 따라서 '.'"."은 서로 다른 두 개의 토큰입니다. 문법에 두 가지 모두 사용하는 것은 매우 혼란 스럽기 때문에 나쁜 형태로 간주됩니다.

' 기반의 단일 문자 토큰은 따옴표 사이의 실제와 관련이 있습니다. 그러한 토큰은 그 단일 문자에 대한 문자 코드와 동일한 토큰 코드를 얻습니다. 다른 모든 토큰은 바이슨에 의해 선택된 고유 토큰 값을 가지며 별명으로 선언되지 않는 한 모든 고유 토큰이 서로 다른 토큰 번호를 갖도록 선택됩니다.

토큰 '.'이 토큰 코드 46 (ascii라고 가정)을 얻는 동안 토큰 "."은 다른 코드 (256보다 큰 숫자)를 얻습니다. 어떤 이름의 토큰으로 "."의 별칭을 선언하지 않는 한, 렉서가 "."의 토큰 코드가 무엇인지 쉽게 알 수없고 리턴 할 수 없습니다.

위의 모든 내용은 들소에만 적용됩니다. 버클리 yacc와 AT & T yacc는 서로 다릅니다 (서로 또는 들소에서).


그래서 변화/문법에 '.'의 다른 사용과 서로 '.' 갈등의 두 가지 용도가 당신이 "."로 변경하면 충돌이 멀리 갔다 줄일 수 있습니다. 하나를 "."으로 변경하면 렉서가 해결해야하는 두 개의 별개의 토큰이되므로 충돌이 사라집니다. 물론, 당신의 렉서가 아마도 "." 토큰을 반환하지 않을 것이므로, 이것은 당신이 원하는 것이 아닐 것입니다.