YACC/Bison, 수학 작전을 그룹화하여 금액을 최소화합니다.
문제
나는 여기에 Calc 소스를보고 있습니다 http://epaperpress.com/lexandyacc/
나는 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); }
그것들을 그룹화하는 방법이 있습니까? 그래서 대신 아래와 같은 것을 쓸 수 있습니까?
| expr mathOp expr { $$ = opr(mathOp, 2, $1, $3); }
| expr cmpOp expr { $$ = opr(cmpOp, 2, $1, $3); }
참고 : Bison을 사용하고 있습니다.
해결책
그와 같이 그룹화하는 문제는 규칙에 대한 우선 순위를 잃는다는 것입니다. 당신은 그것이 어떤 수학자인지, Bison/YACC가 처리 할 수없는 것에 따라 다른 우선 순위를 가진 한 가지 규칙 만 있습니다. 즉, 동일한 우선 순위 수준의 OP를 함께 그룹화 할 수 있습니다.
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: '*' { $$ = '*'; }
| '/' { $$ = '/'; }
;
다른 팁
두 가지 방법으로 할 수 있습니다.
- Lex Stage에서 연산자의 인식을 정의하고 연산자 '+', '-'...
Mathop을 비 터미널로 사용하면 관련 값을 반환 할 수 있습니다.
Mathop : '+'{$$ = '+'; } | '-'{$$ = '-'; } ...
그렇다면 사용법은 다음과 같습니다 ($ 2에주의를 기울이면) :
| expr mathOp expr { $$ = opr($2, 2, $1, $3); }
더 복잡한 Mathop을 정의하고 %유형을 사용하고 싶을 수도 있습니다.
제휴하지 않습니다 StackOverflow