2016-03-16 2 views
1

Я пытаюсь привести некоторые ошибки синтаксического анализа, указав неассоциативный приоритет. Вот часть моего файла грамматики:Правило неассоциативного правила Bison

Comparison : 
    Value ComparisonOp Value 
    { 
     $2->Left($1); 
     $2->Right($3); 
     $$ = $2; 
    } 
    ; 

Выражения типа 1 = 2 следует разобрать, но выражения как 1 = 2 = 3, не допускаются в грамматике. Чтобы учесть это, я пытался сделать мой оператор нон ассоциативную следующим образом:

%nonassoc NONASSOCIATIVE 
. 
.(rest of the grammar) 
. 
Comparison : 
    Value ComparisonOp Value %prec NONASSOCIATIVE 
    { 
     $2->Left($1); 
     $2->Right($3); 
     $$ = $2; 
    } 
    ; 

1 = 2 = 3 все еще проходит, Может кто-то пожалуйста, скажите мне, что я делаю неправильно?

ответ

3

Вам необходимо установить ассоциативность маркеров ComparisonOp. Либо

%nonassoc ComparisonOp NONASSOCIATIVE 

если ComparisonOp является маркером или что-то вроде

%nonassoc '=' '<' '>' NOT_EQUAL GREATOR_OR_EQUAL LESS_OR_EQUAL NONASSOCIATIVE 

, если у вас есть Mulitple жетоны и ComparisonOp это правило, которое расширяется до любого из них


В качестве конкретного примера , следующие работы точно так же, как вы запрашиваете:

%{ 
#include <stdio.h> 
#include <ctype.h> 
int yylex(); 
void yyerror(const char *); 
%} 
%nonassoc '=' '<' '>' CMPOP 
%left '+' '-' ADDOP 
%left '*' '/' '%' MULOP 
%token VALUE 
%% 
expr: expr cmp_op expr %prec CMPOP 
    | expr add_op expr %prec ADDOP 
    | expr mul_op expr %prec MULOP 
    | VALUE 
    | '(' expr ')' 
    ; 
cmp_op: '=' | '<' | '>' | '<' '=' | '>' '=' | '<' '>' ; 
add_op: '+' | '-' ; 
mul_op: '*' | '/' | '%' ; 
%% 
int main() { return yyparse(); } 
int yylex() { 
    int ch; 
    while(isspace(ch = getchar())); 
    if (isdigit(ch)) return VALUE; 
    return ch; 
} 
void yyerror(const char *err) { fprintf(stderr, "%s\n", err); } 

так что если у вас возникли другие проблемы, попробуйте размещая MVCE, который показывает реальную проблему вы имеете ...

+0

ComparisonOp является правилом, что расширяется токены EQ, NEQ, я попытался добавить правила приоритета для них но, по-видимому, приоритет не распространяется на родительское правило. – stopBugs

+0

. Вы должны правильно установить приоритет на обоих правилах, а разрешение приоритетов токенов - бизон, сравнивая приоритет правила, которое должно быть уменьшено, с приоритетом маркера сдвинуты. Если вы установите только один или другой, ничего не произойдет. –

+0

Я сделал оба, все равно это не работает. Один тонко здесь заключается в том, что в правиле для значения у меня есть – stopBugs