[英]Bison Grammar For Basic Calculator Issue
所以我在“作品”下面的語法。 但是,現在有一點警告,我可以做類似
1.0-----------------2.0
它將在2到-2之間翻轉,直到達到1 op 2為止。 對野牛來說還很陌生,並且不清楚如何最好地實現此目的。 我有1個想法,每次以3遞增“ +”“-”的每個組合都會引發一個錯誤,但這是8個語法規則,我什至不知道如何在野牛中引發錯誤。 我想有一種更清潔,更易理解的方法來執行此操作。
Flex Lexer
%option nounistd
%option noyywrap
%{
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include "parser.tab.h"
#define isatty _isatty
#define fileno _fileno
%}
%%
[ \t]+
\n {return '\n';}
[0-9]+(\.[0-9]+)? {yylval.number=atof(yytext); return NUMBER;}
. {return yytext[0];}
%%
野牛語法
%{
#include <stdio.h>
#include <math.h>
extern int yylex(void);
int yyerror(const char* c) { printf("%s\n",c); return 0;}
%}
%union
{
double number;
}
%type <number> exp
%token <number> NUMBER
%left '+' '-'
%left '*' '/'
%right '^'
%start commands
%%
commands
: /*empty*/
| commands line
;
line
: '\n'
| exp '\n' {printf("=%f\n",$1);}
| error '\n' {printf("encountered an error!\n");}
;
exp
: NUMBER { $$ = $1;}
| exp '+' exp {$$ = $1 + $3;}
| exp '-' exp {$$ = $1 - $3;}
| exp '*' exp {$$ = $1 * $3;}
| exp '/' exp {$$ = $1 / $3;}
| exp '^' exp {$$ = pow($1,$3);}
| '-' exp {$$ = -$2;}
| '+' exp {$$ = $2;}
| '(' exp ')' {$$ = $2;}
;
%%
這是算術評估正確和期望的行為,你會發現它同樣工作在沒有實現任何語言--
減運算符。
如果您具有--
運算符,通常可以使用以下規則在詞法分析器中實現該運算符:
"--" { return DECREMENT; }
這樣可以確保a---b
的詞法為“ a”,“-”,“-”,“ b”,而a----b
詞法為“ a”,“-”,“-”, “ b”。 (后者是一種語法錯誤。)這是“最大嚼嘴”規則的結果,該規則是大多數語言標准所要求的,並且由大多數掃描儀生成器實施。 (通常不建議這樣寫代碼,但不禁止這樣做。)
在C中,您不能使用兩個連續的減后運算符,因為后減表達式不是左值。 可以通過要求前后減量和-增量運算符的參數為左值來強制執行該語法。 但是在C ++中,您不能輕松地從句法上確定正確性。 盡管這將是可怕的樣式,但是沒有什么可以阻止您重載operator--(int)
以便某些類型返回引用。
如果您的語言沒有減量運算符,但是出於某種審美原因,您希望使用兩個連續的一元運算符來禁止表達式,那么您可以按照上述提示的相同方式進行操作,例如:
value: NUMBER | '(' expr ')'
term: value | '-' value | '+' value
expr: term | expr '-' expr | expr '+' expr | expr '*' expr | expr '/' expr | ...
在這里,您不能使用--a
(或-+a
),因為一元運算符只能應用於一個value
並且value
不能以一元運算符開頭。 因此,最終用戶將不得不使用括號。 但是您至少應該為想要知道為什么您感到有必要施加此限制的最終用戶提供滿意的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.