Pergunta

Estou olhando para a fonte do calc aqui http://epaperpress.com/lexandyacc/

Eu vejo essas linhas em calc.y

| expr '+' expr         { $$ = opr('+', 2, $1, $3); }
| expr '-' expr         { $$ = opr('-', 2, $1, $3); }
| expr '*' expr         { $$ = opr('*', 2, $1, $3); }
| expr '/' expr         { $$ = opr('/', 2, $1, $3); }
| expr '<' expr         { $$ = opr('<', 2, $1, $3); }
| expr '>' expr         { $$ = opr('>', 2, $1, $3); }

Existe uma maneira de agrupar -os? Então, posso escrever algo como o abaixo?

| expr mathOp expr         { $$ = opr(mathOp, 2, $1, $3); }
| expr cmpOp  expr         { $$ = opr(cmpOp, 2, $1, $3); }

Nota: Estou usando o bisonte.

Foi útil?

Solução

O problema de agrupá -los assim é que você perde as precedências sobre as regras - você tem apenas uma regra que tem precedência diferente, dependendo de qual é o Mathop, que o bisonte/yacc não pode lidar. Dito isto, você pode agrupar as operações do mesmo nível de precedência juntas

expr: expr mulOp expr { $$ = opr($2, 2, $1, $3); } %prec '*'
    | expr addOp expr { $$ = opr($2, 2, $1, $3); } %prec '+'
    | expr relOp expr { $$ = opr($2, 2, $1, $3); } %prec '<'
             :

mulOp: '*' { $$ = '*'; }
     | '/' { $$ = '/'; }
;

Outras dicas

Você pode fazer isso de 2 maneiras:

  • No Stage Lex, define o reconhecimento dos operadores e forneça símbolo de terminal (na sua sintaxe Mathop) com o valor do operador '+', '-' ...
  • Usando o Mathop como não terminal, você pode retornar algum valor associado:

    MATHOP: '+' {$$ = '+'; } | '-' {$$ = '-'; } ...

Em seguida, o uso será (preste atenção a US $ 2):

| expr mathOp expr         { $$ = opr($2, 2, $1, $3); }

Pode ser que você gostaria de definir Mathop mais complicado e do que o tipo %

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top