bisonti precedenza (in realtà utilizzando Jison ma dovrebbe essere lo stesso)
-
26-10-2019 - |
Domanda
Sto usando Jison (un javascript equivalente di Bison) e sto avendo il seguente problema di precedenza. Illustrerò utilizzando la calcolatrice demo http://zaach.github.com/jison/try/
Funziona bene come è. La precedenza è
%left '+' '-'
%left '*' '/'
%left '^'
%left UMINUS
e la grammatica è
e
: e '+' e
{$$ = $1+$3;}
| e '-' e
{$$ = $1-$3;}
| e '*' e
{$$ = $1*$3;}
| e '/' e
{$$ = $1/$3;}
| e '^' e
{$$ = Math.pow($1, $3);}
| '-' e %prec UMINUS
{$$ = -$2;}
Se cambio la linea '*' per essere
| e '*' e %prec TIMESPREC
{$$ = $1*$3;}
e cambiare la precedenza a
%left '+' '-'
%left TIMESPREC '/'
%left '^'
%left UMINUS
non funziona più. Non è forse dovrebbe funzionare lo stesso? Questo potrebbe essere utile, ad esempio, se si volesse avere eventualmente una sintassi algebra dove 2 x + 3 viene analizzato come (2x) +3.
Grazie!
Soluzione
La ragione di questo è perché %prec
sarà solo impostare la precedenza della regola, non su tutti i singoli gettoni. Così, la precedenza individuale dei gettoni sul RHS della regola è ancora importante.
Quindi, l'impostazione %prec
sulla vostra regola di moltiplicazione non sarà alterare la precedenza del simbolo '*'
. Quando precedenza cerca di risolvere i conflitti che metterà a confronto il ridurre la priorità delle azioni con la priorità del token che deve essere spostato. Dal momento che *
non ha la priorità, la grammatica diventa ambigua con la modifica.