modified something
This commit is contained in:
parent
2637899ed7
commit
977cb2a9ae
2 changed files with 108 additions and 23 deletions
1
interp.l
1
interp.l
|
@ -22,7 +22,6 @@ var ([_]|{alpha})([_]|{alpha}|{dig})*
|
||||||
{ws} {yycharno = yycharno + yyleng;}
|
{ws} {yycharno = yycharno + yyleng;}
|
||||||
{var} {yylval.strVal = strdup(yytext);
|
{var} {yylval.strVal = strdup(yytext);
|
||||||
yycharno = yycharno + yyleng;
|
yycharno = yycharno + yyleng;
|
||||||
printf("yyval.strVal = %s",yylval.strVal);
|
|
||||||
return T_VAR;}
|
return T_VAR;}
|
||||||
{number} {yylval.floatVal = atof(yytext);
|
{number} {yylval.floatVal = atof(yytext);
|
||||||
yycharno = yycharno + yyleng;
|
yycharno = yycharno + yyleng;
|
||||||
|
|
130
interp.y
130
interp.y
|
@ -1,12 +1,16 @@
|
||||||
%{
|
%{
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
void yyerror(const char* msg) {}
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void yyerror(const char* msg);
|
||||||
extern FILE* yyin;
|
extern FILE* yyin;
|
||||||
|
extern int yylex();
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{null, opera, var, val} NodeType;
|
{null, opera, var, val} NodeType;
|
||||||
|
typedef enum {false, true} bool;
|
||||||
typedef struct Node {
|
typedef struct Node {
|
||||||
float val;
|
float val;
|
||||||
char * name; // val_name
|
char * name; // val_name
|
||||||
|
@ -60,21 +64,23 @@ void run_through_tree (Node *node){
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
bool escape_recursion = false;
|
||||||
float eval_node(float var_val, Node * node){
|
float eval_node(float var_val, Node * node){
|
||||||
|
|
||||||
switch ((*node).node_type){
|
switch ((*node).node_type){
|
||||||
case var:
|
case var:
|
||||||
if (var_name == ""){
|
if (strcmp(var_name,"")==0){
|
||||||
var_name = node->name;
|
var_name = node->name;
|
||||||
printf("%s",node->name);
|
|
||||||
return var_val;
|
return var_val;
|
||||||
}
|
}
|
||||||
else if (var_name == node->name){
|
else if (strcmp(var_name,node->name)==0){
|
||||||
return var_val;
|
return var_val;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
printf("Error: Too many variable, eg. %s, %s.\n",
|
printf("Error: Too many variable, eg. %s, %s.\n",
|
||||||
var_name,node->name);
|
var_name,node->name);
|
||||||
|
escape_recursion = true;
|
||||||
|
return NAN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,26 +89,85 @@ float eval_node(float var_val, Node * node){
|
||||||
case val:
|
case val:
|
||||||
return (*node).val;
|
return (*node).val;
|
||||||
break;
|
break;
|
||||||
case opera:
|
case opera:{
|
||||||
if (node->opr == "+"){
|
float left_num, right_num;
|
||||||
return (eval_node(var_val,node->left) + eval_node(var_val,node->right));
|
|
||||||
|
left_num = eval_node(var_val,node->left);
|
||||||
|
if (escape_recursion){return NAN; break;}
|
||||||
|
|
||||||
|
right_num = eval_node(var_val,node->right);
|
||||||
|
if (escape_recursion){return NAN; break;}
|
||||||
|
|
||||||
|
if (node->opr == "+"){
|
||||||
|
return left_num + right_num;
|
||||||
}
|
}
|
||||||
else if (node->opr == "-"){
|
else if (node->opr == "-"){
|
||||||
return (eval_node(var_val,node->left) - eval_node(var_val,node->right));
|
return left_num - right_num;
|
||||||
}
|
}
|
||||||
else if (node->opr == "*"){
|
else if (node->opr == "*"){
|
||||||
return (eval_node(var_val,node->left) * eval_node(var_val,node->right));
|
return left_num * right_num;
|
||||||
}
|
}
|
||||||
else if (node->opr == "/"){
|
else if (node->opr == "/"){
|
||||||
return (eval_node(var_val,node->left) / eval_node(var_val,node->right));
|
return left_num / right_num;
|
||||||
}
|
}
|
||||||
break;
|
break;}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node * main_node;
|
Node * main_node;
|
||||||
|
float solve(Node * m_node){
|
||||||
|
escape_recursion = false;
|
||||||
|
var_name = "";
|
||||||
|
float x0 = 0.0;
|
||||||
|
float y0 = eval_node(x0,m_node);
|
||||||
|
float x1 = 1.0;
|
||||||
|
float y1 = eval_node(x1,m_node);
|
||||||
|
float x2 = 10.0;
|
||||||
|
float y2 = eval_node(x2,m_node);
|
||||||
|
|
||||||
|
if (isnan(y0) || isnan(y1) || isnan(y2)){
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
else if(strcmp(var_name,"")==0){
|
||||||
|
var_name = "[var]";
|
||||||
|
|
||||||
|
if (y0 == 0.0){
|
||||||
|
printf("%s can be any numbers; the following is just a solution.",
|
||||||
|
var_name);
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
float slope1 = (y1-y0) / (x1-x0);
|
||||||
|
float slope2 = (y2-y0) / (x2-x0);
|
||||||
|
|
||||||
|
if (slope1 == slope2){
|
||||||
|
if (slope1 == 0.0){
|
||||||
|
if (y0 == 0){
|
||||||
|
printf("%s can be any numbers; the following is just a solution.",
|
||||||
|
var_name);
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
float ans = -y0 / slope1;
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
printf("Error: the formula is not linear.\n");
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union{
|
%union{
|
||||||
|
@ -126,15 +191,23 @@ Node * main_node;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
S : S E T_NEWLINE { main_node = $2;run_through_tree(main_node); /*printf("TOTAL_VALUE: %f",eval_node(5.0,main_node));*/}
|
S : S E T_NEWLINE { main_node = $2;
|
||||||
|
printf("ANSWER: %s = %f",var_name,solve(main_node));}
|
||||||
| {}
|
| {}
|
||||||
;
|
;
|
||||||
|
|
||||||
E : E T_ADD E {Node * op_node = (Node *) malloc(sizeof(Node));*op_node = create_op_node("+"); connect_node(op_node,$1,$3);$$ = op_node;}
|
E : E T_ADD E {Node * op_node = (Node *) malloc(sizeof(Node));
|
||||||
| E T_SUB E {Node * op_node = (Node *) malloc(sizeof(Node));*op_node = create_op_node("-"); connect_node(op_node,$1,$3);$$ = op_node;}
|
*op_node = create_op_node("+");
|
||||||
| E T_MUL E {Node * op_node
|
connect_node(op_node,$1,$3);$$ = op_node;}
|
||||||
= (Node *) malloc(sizeof(Node));*op_node = create_op_node("*"); connect_node(op_node,$1,$3);$$ = op_node;}
|
| E T_SUB E {Node * op_node = (Node *) malloc(sizeof(Node));
|
||||||
| E T_DIV E {Node * op_node = (Node *) malloc(sizeof(Node));*op_node = create_op_node("/"); connect_node(op_node,$1,$3);$$ = op_node;}
|
*op_node = create_op_node("-");
|
||||||
|
connect_node(op_node,$1,$3);$$ = op_node;}
|
||||||
|
| E T_MUL E {Node * op_node = (Node *) malloc(sizeof(Node));
|
||||||
|
*op_node = create_op_node("*");
|
||||||
|
connect_node(op_node,$1,$3);$$ = op_node;}
|
||||||
|
| E T_DIV E {Node * op_node = (Node *) malloc(sizeof(Node));
|
||||||
|
*op_node = create_op_node("/");
|
||||||
|
connect_node(op_node,$1,$3);$$ = op_node;}
|
||||||
| T_SUB E %prec NEG {
|
| T_SUB E %prec NEG {
|
||||||
Node * op_node = (Node *) malloc(sizeof(Node));
|
Node * op_node = (Node *) malloc(sizeof(Node));
|
||||||
Node * zero_node = (Node *) malloc(sizeof(Node));
|
Node * zero_node = (Node *) malloc(sizeof(Node));
|
||||||
|
@ -142,8 +215,12 @@ E : E T_ADD E {Node * op_node = (Node *) malloc(sizeof(Node));*op_node = cre
|
||||||
* op_node = create_op_node("-");
|
* op_node = create_op_node("-");
|
||||||
connect_node(op_node,zero_node,$2);
|
connect_node(op_node,zero_node,$2);
|
||||||
$$ = op_node;}
|
$$ = op_node;}
|
||||||
| T_NUM {Node * val_node = (Node *) malloc(sizeof(Node));* val_node = create_val_node($1); $$ = val_node;}
|
| T_NUM {Node * val_node = (Node *) malloc(sizeof(Node));
|
||||||
| T_VAR {Node * var_node = (Node *) malloc(sizeof(Node));* var_node = create_var_node($1); $$ = var_node;}
|
* val_node = create_val_node($1);
|
||||||
|
$$ = val_node;}
|
||||||
|
| T_VAR {Node * var_node = (Node *) malloc(sizeof(Node));
|
||||||
|
* var_node = create_var_node($1);
|
||||||
|
$$ = var_node;}
|
||||||
| T_LPATH E T_RPATH {$$ = $2;}
|
| T_LPATH E T_RPATH {$$ = $2;}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -152,9 +229,18 @@ E : E T_ADD E {Node * op_node = (Node *) malloc(sizeof(Node));*op_node = cre
|
||||||
int main(){
|
int main(){
|
||||||
yyin = stdin;
|
yyin = stdin;
|
||||||
do{
|
do{
|
||||||
|
printf(
|
||||||
|
"A program to solve f(x) = 0 such that f(x) is a 1-var linear function.\n");
|
||||||
|
printf("Please Enter a 1-var linear function: ");
|
||||||
yyparse();
|
yyparse();
|
||||||
|
|
||||||
}while(!feof(yyin));
|
}while(!feof(yyin));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void yyerror (const char *msg)
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf (stderr, "%s\n", msg);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue