Skip to content

Instantly share code, notes, and snippets.

@siritori
Created July 22, 2011 06:16
Show Gist options
  • Save siritori/1098973 to your computer and use it in GitHub Desktop.
Save siritori/1098973 to your computer and use it in GitHub Desktop.
test.y
test.l:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘yylloc’
%{
#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);
}
%{
#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