Created
July 22, 2011 06:16
-
-
Save siritori/1098973 to your computer and use it in GitHub Desktop.
test.y
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
test.l:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘yylloc’ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <math.h> | |
#include "test.h" | |
#include "test.tab.h" | |
extern YYLTYPE yylloc; | |
void next_location(); | |
#define DEF_FUNC(func) do{ yylval.fp = func; return FUNC; } while(0) | |
double round(double n); | |
%} | |
NONZERO [1-9] | |
DIGIT [[:digit:]] | |
FLOAT ({NONZERO}{DIGIT}*\.?|0\.|\.{DIGIT}){DIGIT}*|0 | |
EXPONENT [eE](-|\+?){DIGIT}+ | |
NUMBER {FLOAT}{EXPONENT}? | |
ID [_[:alpha:]][_[:alnum:]]* | |
WSPACE [[:blank:]]+ | |
%% | |
{NUMBER} { | |
yylval.number = atof(yytext); | |
return NUM; | |
} | |
{WSPACE} ; | |
sin DEF_FUNC(sin); | |
cos DEF_FUNC(cos); | |
tan DEF_FUNC(tan); | |
sinh DEF_FUNC(sinh); | |
cosh DEF_FUNC(cosh); | |
tanh DEF_FUNC(tanh); | |
asin DEF_FUNC(asin); | |
acos DEF_FUNC(acos); | |
atan DEF_FUNC(atan); | |
log DEF_FUNC(log10); | |
ln DEF_FUNC(log); | |
exp DEF_FUNC(exp); | |
sqrt DEF_FUNC(sqrt); | |
floor DEF_FUNC(floor); | |
ceil DEF_FUNC(ceil); | |
int DEF_FUNC(round); | |
{ID} { | |
strncpy(yylval.string, yytext, VARNAME_SIZE); | |
yylval.string[VARNAME_SIZE] = '\0'; | |
return VAR; | |
} | |
\n { | |
return yytext[0]; | |
} | |
. { | |
return yytext[0]; | |
} | |
<<EOF>> { | |
return 0; | |
} | |
%% | |
double round(double n) { | |
return floor(n + 0.5); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <math.h> | |
#include "test.h" | |
void yyerror(const char* s); | |
int yylex(void); | |
static double* get_var(const char* name); | |
typedef struct { | |
double val; | |
char name[VARNAME_SIZE + 1]; | |
} symbol; | |
static int num_symbols = 0; | |
static symbol symbol_table[128]; | |
%} | |
%defines | |
%union { | |
double number; | |
double (*fp)(double); | |
char string[VARNAME_SIZE + 1]; | |
} | |
%token <number> NUM | |
%token <string> VAR | |
%token <fp> FUNC | |
%type <number> expr | |
%left '+' '-' | |
%left '*' '/' | |
%left NEG | |
%right '^' | |
%% | |
/* input */ | |
input : /* empty */ | |
| input line | |
; | |
/* statement */ | |
line: '\n'| | |
expr '\n' { | |
*get_var("ans") = $1; | |
printf("-->%lg\n\n", $1); | |
}| | |
VAR '=' expr '\n' { | |
*get_var("ans") = *get_var($1) = $3; | |
printf("-->%lg\n\n", $3); | |
}| | |
error '\n' { | |
fprintf(stderr, "-->ERROR\n\n"); | |
yyerrok; | |
}; | |
/* expression */ | |
expr: | |
NUM| | |
VAR { | |
$$ = *get_var($1); | |
}| | |
FUNC '(' expr ')' { | |
$$ = $1($3); | |
}| | |
expr '+' expr { | |
$$ = $1 + $3; | |
}| | |
expr '-' expr { | |
$$ = $1 - $3; | |
}| | |
expr '*' expr { | |
$$ = $1 * $3; | |
}| | |
expr '/' expr { | |
if($3 != 0) $$ = $1 / $3; | |
else { | |
fprintf(stderr, "ERROR: Division by ZERO\n"); | |
$$ = 0; | |
} | |
}| | |
expr '^' expr { | |
double integer; | |
double fraction = modf($3, &integer); | |
if($1 < 0 && fraction != 0 || $1 == 0 && $3 <= 0) { | |
printf("%d", @$.last_column); // ここを外すと何故かコンパイルが通らない。printf | |
$$ = 1; | |
} | |
else { | |
$$ = pow($1, $3); | |
} | |
}| | |
'+' expr %prec NEG { | |
$$ = $2; | |
}| | |
'-' expr %prec NEG { | |
$$ = -$2; | |
}| | |
'(' expr ')' { | |
$$ = $2; | |
}; | |
%% | |
int main(void) { | |
*get_var("pi") = M_PI; | |
*get_var("e") = M_E; | |
return yyparse(); | |
} | |
void yyerror(const char* s) { | |
fprintf(stderr, "Error: %s\n", s); | |
} | |
double* get_var(const char* name) { | |
int i; | |
for(i = 0; i < num_symbols; ++i) { | |
if(!strcmp(symbol_table[i].name, name)) { | |
return &(symbol_table[i].val); | |
} | |
} | |
strcpy(symbol_table[i].name, name); | |
++num_symbols; | |
return &(symbol_table[i].val); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment