Skip to content

Instantly share code, notes, and snippets.

@ptr-yudai
Created December 22, 2016 13:25
Show Gist options
  • Save ptr-yudai/2a1ac004716f503e8079097e72ba24dc to your computer and use it in GitHub Desktop.
Save ptr-yudai/2a1ac004716f503e8079097e72ba24dc to your computer and use it in GitHub Desktop.
きつねさんとLLVMで作った電卓2
%{
#include <stdio.h>
#include "y.tab.h"
int yywrap(void) { return 1; }
%}
%%
"+" return OPERATOR_ADD;
"-" return OPERATOR_SUB;
"*" return OPERATOR_MUL;
"/" return OPERATOR_DIV;
"^" return OPERATOR_POW;
[1-9][0-9]* {
double temp_box;
sscanf(yytext, "%lf", &temp_box);
yylval.double_value = temp_box;
return DOUBLE_LITERAL;
}
"0" {
yylval.double_value = 0.0;
return DOUBLE_LITERAL;
}
[0-9]*\.[0-9]* {
double temp_box;
sscanf(yytext, "%lf", &temp_box);
yylval.double_value = temp_box;
return DOUBLE_LITERAL;
}
[ \t] ; // [追加]タブや空白は無視
"\n" return EOL;
%%
%{
#include <stdio.h>
#include <stdlib.h>
%}
%union {
double double_value;
}
%token <int_value> INT_LITERAL
%token <double_value> DOUBLE_LITERAL
%token OPERATOR_ADD
OPERATOR_SUB
OPERATOR_MUL
OPERATOR_DIV
OPERATOR_POW // [追加]累乗
EOL
%type <double_value> expression
expression_addsub
expression_muldiv
expression_power
expression_term
%%
source_code
: line
| source_code line
;
line
: expression EOL
{
printf(">> %lf\n", $1);
}
;
/* [変更]
expressionやらtermやらややこしいので、
expression_演算子
に変更。
優先順位が高いほどexpression_termに近く、
優先順位が同じものは同じexpressionに記述する。
*/
expression
: expression_addsub
;
expression_addsub
: expression_muldiv
| expression_addsub OPERATOR_ADD expression_muldiv
{
$$ = $1 + $3;
}
| expression_addsub OPERATOR_SUB expression_muldiv
{
$$ = $1 - $3;
}
;
expression_muldiv
: expression_power
| expression_muldiv OPERATOR_MUL expression_power
{
$$ = $1 * $3;
}
| expression_muldiv OPERATOR_DIV expression_power
{
$$ = $1 / $3;
}
;
expression_power
: expression_term
| expression_power OPERATOR_POW expression_term
{
int i;
double ret;
// 累乗とは
for(i = 0, ret = 1.0; i < (int)$3; i++) {
ret *= $1;
}
$$ = ret;
}
;
expression_term
: DOUBLE_LITERAL
;
%%
int yyerror(char const* str)
{
extern char *yytext;
fprintf(stderr, "Error near %s\n", yytext);
return 0;
}
int main(void)
{
// yaccが勝手に解析してくれる関数
extern int yyparse(void);
// コンパイルすべきファイル
extern FILE *yyin;
// 今回はファイルではなくstdinからの入力
yyin = stdin;
if (yyparse()) {
// エラー発生
fprintf(stderr, "ERROR!\n");
exit(1);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment