diff options
| author | crupest <crupest@outlook.com> | 2021-11-22 20:53:01 +0800 | 
|---|---|---|
| committer | crupest <crupest@outlook.com> | 2021-11-22 20:53:01 +0800 | 
| commit | 226bfe84c5f690462adbf386dc66316cc21fdb28 (patch) | |
| tree | d2a3ed9ab5f176cd0f848b1febf741f201c19f03 /works/life/compile-principle-experiment | |
| parent | 205f243379919b7830726f9dcc4ae7d33c84e857 (diff) | |
| download | crupest-226bfe84c5f690462adbf386dc66316cc21fdb28.tar.gz crupest-226bfe84c5f690462adbf386dc66316cc21fdb28.tar.bz2 crupest-226bfe84c5f690462adbf386dc66316cc21fdb28.zip  | |
import(life): Add compile principle codes.
Diffstat (limited to 'works/life/compile-principle-experiment')
| -rw-r--r-- | works/life/compile-principle-experiment/1/hoc.y | 65 | ||||
| -rw-r--r-- | works/life/compile-principle-experiment/1/makefile | 5 | ||||
| -rw-r--r-- | works/life/compile-principle-experiment/2/hoc.y | 106 | ||||
| -rw-r--r-- | works/life/compile-principle-experiment/2/makefile | 5 | 
4 files changed, 181 insertions, 0 deletions
diff --git a/works/life/compile-principle-experiment/1/hoc.y b/works/life/compile-principle-experiment/1/hoc.y new file mode 100644 index 0000000..c4452ad --- /dev/null +++ b/works/life/compile-principle-experiment/1/hoc.y @@ -0,0 +1,65 @@ +%{ +#define  YYSTYPE  double   /* data type of yacc stack */ +#include <stdio.h> +#include <ctype.h> +#include <math.h> + +int yylex(); +int yyerror(const char * s); +%} +%token  NUMBER +%left  '+' '-'    /* left associative, same precedence */ +%left  '*' '/' '%'   /* left assoc., higher precedence */ +%left	UNARYMINUS +%% +list:    /* nothing */ +  | list '\n' +  | list expr '\n'    { printf("%lf\n", $2); } +  ; +expr:    NUMBER  { $$ = $1; } +  | expr '+' expr  { $$ = $1 + $3; } +  | expr '-' expr  { $$ = $1 - $3; } +  | expr '*' expr  { $$ = $1 * $3; } +  | expr '/' expr  { $$ = $1 / $3; } +  | expr '%' expr  { $$ = fmod($1, $3); } +	| '-' expr  %prec UNARYMINUS { $$ = -$2; } +  | '(' expr ')'  { $$ = $2; } +  ; +%% +   +int lineno = 1; + +int main(int argc, char** argv) +{ +  yyparse(); +  return 0; +} + +int yylex() +{ +  int c; + +  do { +    c = getchar(); +  } while (c == ' ' || c == '\t'); + +  if (c == EOF) +    return 0; + +  if (c == '.' || isdigit(c)) { +    ungetc(c, stdin); +    scanf("%lf", &yylval); +    return NUMBER; +  } + +  if (c == '\n') +    lineno++; + +  return c; +} + +int yyerror(const char* s) +{ +  fprintf(stderr, "Error occured near line %d\n", lineno); +  return 0; +} diff --git a/works/life/compile-principle-experiment/1/makefile b/works/life/compile-principle-experiment/1/makefile new file mode 100644 index 0000000..65bcca2 --- /dev/null +++ b/works/life/compile-principle-experiment/1/makefile @@ -0,0 +1,5 @@ +hoc:	hoc.c +	cc hoc.c -o hoc + +hoc.c:	hoc.y +	bison hoc.y -o hoc.c diff --git a/works/life/compile-principle-experiment/2/hoc.y b/works/life/compile-principle-experiment/2/hoc.y new file mode 100644 index 0000000..14500bb --- /dev/null +++ b/works/life/compile-principle-experiment/2/hoc.y @@ -0,0 +1,106 @@ +%{ +#include <stdio.h> +#include <ctype.h> +#include <math.h> + +int yylex(); +int yyerror(const char * s); +void execerror(const char* s, const char* t); +void warning(const char* s, const char* t); + +double	mem[26];	/* memory for variables 'a'..'z' */ +%} + +%union {		/* stack type */ +	double	val;	/* actual value */ +	int	index;	/* index into mem[] */ +} +%token	<val>	NUMBER +%token	<index>	VAR +%type	<val>	expr +%right	'=' +%left	'+' '-' +%left	'*' '/' +%left	UNARYMINUS +%% +list:	  /* nothing */ +	| list '\n' +	| list expr '\n'	{ printf("\t%.8g\n", $2); } +	| list error '\n'	{ yyerrok; } +	; +expr:	  NUMBER +	| VAR		{ $$ = mem[$1]; } +	| VAR '=' expr	{ $$ = mem[$1] = $3; }	 +	| expr '+' expr	{ $$ = $1 + $3; } +	| expr '-' expr	{ $$ = $1 - $3; } +	| expr '*' expr	{ $$ = $1 * $3; } +	| expr '/' expr	{ +		if ($3 == 0.0) +			execerror("division by zero", ""); +		$$ = $1 / $3; } +	| '(' expr ')'	{ $$ = $2; } +	| '-' expr  %prec UNARYMINUS  { $$ = -$2; } +	; +%% +	/* end of grammar */ + +int	lineno = 1; +#include <signal.h> +#include <setjmp.h> +jmp_buf	begin; + +void fpecatch(int s); + +int main(int argc, char** argv) +{ +	(void)setjmp(begin); +	signal(SIGFPE, fpecatch); +	yyparse(); +} + +int yylex() +{ +	int c; + +	while ((c=getchar()) == ' ' || c == '\t') +		; +	if (c == EOF) +		return 0; +	if (c == '.' || isdigit(c)) {	/* number */ +		ungetc(c, stdin); +		scanf("%lf", &yylval.val); +		return NUMBER; +	} +	if (islower(c)) { +		yylval.index = c - 'a';	/* ASCII only */ +		return VAR; +	} +	if (c == '\n') +		lineno++; +	return c; +} + +int yyerror(const char *s) +{ +	warning(s, (char *)0); +	return 0; +} + +void execerror(const char* s, const char* t) +{ +	warning(s, t); +	longjmp(begin, 0); +} + +void fpecatch(int s) +{ +	execerror("floating point exception", (char *) 0); +} + +void warning(const char* s, const char* t) +{ +	fprintf(stderr, "%s", s); +	if (t && *t) +		fprintf(stderr, " %s", t); +	fprintf(stderr, " near line %d\n", lineno); +} diff --git a/works/life/compile-principle-experiment/2/makefile b/works/life/compile-principle-experiment/2/makefile new file mode 100644 index 0000000..65bcca2 --- /dev/null +++ b/works/life/compile-principle-experiment/2/makefile @@ -0,0 +1,5 @@ +hoc:	hoc.c +	cc hoc.c -o hoc + +hoc.c:	hoc.y +	bison hoc.y -o hoc.c  | 
