I need to write a multi-process prefix expressions parser and evaluator.
Given a prefix expression such as the following on standard input
for instance: (+ (* (+ 2 4) 5) (- (- 6 7) 8)).
The program should read each sub-expressions in a forked process.
The parent process must wait until the child process has finished reading its sub-expression, and continue from there.
It is not illegal to use scanf or printf functions.
Totally useless, but maybe fun.
You start by doing this in one process only.
Add that multiprocess stuff.
As a hint, I show you how to do this in C++. You have to translate this into C yourself:
int read_sequence()
{
int y;
if ((cin>>ws).peek() == '('){
cin.ignore( 1 );
char op = cin.get();
y = read_sequence();
while ((cin>>ws).peek() != ')'){
int b = read_sequence();
y = op == '+' ? y + b
: op == '-' ? y - b
: op == '*' ? y*b
: y / b;
}
cin.ignore( 1 );
} else {
cin >> y;
}
return y;
}
Related
I have written a stack based interpreted language in C. The interpreter works with reading a file line by line and executing the line depending on the operation. print(1 + 1) in python would become 1 1 + print.
Here is the function to check what the operation is and push it to the stack or do an operation on it:
if (strncmp(op, "+", 1) == 0 && is_definition == 0)
{
float a = pop(stack);
float b = pop(stack);
push(stack, a + b);
}
else if (strncmp(op, "-", 1) == 0 && is_definition == 0)
{
float a = pop(stack);
float b = pop(stack);
push(stack, b - a);
}
else if (strncmp(op, "*", 1) == 0 && is_definition == 0)
{
float a = pop(stack);
float b = pop(stack);
push(stack, a * b);
}
else if (strncmp(op, "/", 1) == 0 && is_definition == 0)
{
float a = pop(stack);
float b = pop(stack);
push(stack, b / a);
}
else if (strncmp(op, "print", 5) == 0 && is_definition == 0)
{
float a = pop(stack);
if(a == (int)a)
printf("%d\n", (int)a);
else
printf("%f\n", a);
}
else if (strncmp(op, "define", 6) == 0 && is_definition == 0)
{
is_definition = 1;
}
else if (is_definition == 1)
{
}
else if (strncmp(op, "end", 3) == 0 && is_definition == 1)
{
is_definition = 0;
}
else
{
push(stack, atoi(op));
}
This is inside a loop that iterates over every space separated operation in the code.
I want to add a definition system a bit like the one in C.
This is the syntax I would like to have
define TEST 10 end
I would like to use this a bit like a variable system where you can use TEST.
In pseudo code, you should do the following:
Read a line of source
If it is a definition, parse+store it and skip the rest
(it is not a definition) execute, much like the code you posted
About "parse+store" the definitions, you need - for example - a couple of arrays, or an array of structs. You need to store each "name" (the alias, or the name of the definition) and, along with each name, its value.
Then, in the code you posted, you should implement the push() instruction (you only mention pop()). The push() instruction reads an operand and determines if it is an alias (definition) or not:
(push pseudo code)
Get the operand
Determine if it is a definition. Basically, you iterate on all the stored definitions to find a correspondence
Got the final value, put it on the stack
There are several things that could be said... a couple of them, in sparse order:
The pushed operand is a number? In this case you can skip the definition(s) checking, assuming that it is illegal to say "define 10 20"
Would you allow to (re)define operators?
Would you allow a definition to refer to other definitions?
...
What does this function do that helps it to take input differently and how are the conditions in for loop executed?
void scanint(int &x)
{
int flag=0;
register int c = gc();
if(c == '-') flag=1;
x = 0;
for(;(c<48 || c>57);c = gc());//why is this used?
for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}//how is this executed ?
if(flag == 1)x=-x;
}
It's not c.
void scanint(int &x) {/* Whatever */}
// ^^
This defines a function accepting a reference to an int and there are no references in c, the arguments are passed by value to functions. You could of course use a pointer to an int, but then the body of the function should be changed accordingly, using *x instead of ant occurrences of x.
The following assumes that gc() stands for a function similar to getchar(), so that the posted code is a very bad way of extracting an int value from stdin:
void scanint(int &x) // Or 'int *x' in C
{
int c = gc(); // register was deprecated in C++17
bool is_negative = (c == '-'); // C has bool from C99 too
x = 0; // '*x = 0;' in C. The same applies to the following code
// Considering only ASCII, ignores non-digit characters
// E.g. from " 123" it ignores the first two spaces,
// but, given " -123", it will ignore the sign too. Bad, as I said.
for( ;
( c < '0' || c > '9');
c = gc() )
;
// Now computes the actual number using an old trick that should
// be left to the compiler to be exploited:
// 10 * x = (2 + 8) * x = 2 * x + 8 * x = x << 1 + x << 3 (bit shifts)
for( ;
'0' <= c && c <= '9';
c = gc() )
{
x = (x << 1) + (x << 3) + c - '0';
}
if ( is_negative )
x = -x;
}
I am very beginner in c and I am reading now the classic example of the TicTacToe game.
I am not sure about what this return statement does:
{.....
return (ch == X) ?O :X;
This must be some conditional statement on the variable ch (that in my case stands for the player (X or O) but I am not sure about its meaning. Can anyone please tell me what does it do?
It means
if (ch == X)
return O;
else
return X;
This is called a ternary operator, because unlike many other operators, it doesn't take one or two operands, but three. A boolean condition and two values. In your example, if the boolean condition (ch == X) validates to true, O is the result of the operator. Otherwise, X is the result.
This can be rewritten as:
if (ch == X)
return O;
else
return X;
If ch equals X return O else return X.
The ... ? ... : ... operator is called ternary operator. Its a shorthand for simple if statement. Lets see few examples,
Odd/Even
n % 2 ? printf ("Odd") : printf ("Even");
OR
printf ("%s\n", n % 2 ? "Odd" : "Even");
Factorial
int factorial(int n)
{
return (n == 0 ? 1 : n * factorial (n - 1));
}
I'm trying to draw a line in C language using Bresenham's algorithm.I'm using turbo C++ in dosbox for windows 7 to implement this code.While compiling i'm not getting any error but when i run the code the programs terminates after obtaining the 2 co-ordinates.Please Help..
the message on compiling is as follows..
the directories path is as follows
My code..
# include <stdio.h>
# include <conio.h>
# include <graphics.h>
void main()
{
int dx,dy,x,y,p,x1,y1,x2,y2;
int gd,gm;
clrscr();
printf("\n\n\tEnter the co-ordinates of first point : ");
scanf("%d %d",&x1,&y1);
printf("\n\n\tEnter the co-ordinates of second point : ");
scanf("%d %d",&x2,&y2);
dx = (x2 - x1);
dy = (y2 - y1);
p = 2 * (dy) - (dx);
x = x1;
y = y1;
detectgraph(&gd,&gm);
initgraph(&gd,&gm,"e:\\tc\\bgi");
putpixel(x,y,WHITE);
while(x <= x2)
{
if(p < 0)
{
x=x+1;
y=y;
p = p + 2 * (dy);
}
else
{
x=x+1;
y=y+1;
p = p + 2 * (dy - dx);
}
putpixel(x,y,WHITE);
}
getch();
closegraph();
}
OP should post input that was used.
The posted sample code does not work is x1 > x2 nor y1 > y2. This is one set of input that would stop the routine abruptly. To fix, the dx and dy should be based on the absolute value and the incremental x & y steps need to be independently +1 or -1.
An input of 3,4 instead of 3 4 (comma vs. whitespace) will also mess up the routine.
In the while loop, recommend if(p <= 0).
OP's "... code the programs terminates after obtaining the 2 co-ordinates." is not detailed enough, for of course the code should terminate sometime after obtaining the 2 co-ordinates. But OP does not detail where it terminates too early.
This is a typical perfect point to start the debugger and go through the code step-by-step, watching any variables. If a debugger is unavailable, printf debugging to the console is a backup alternative.
A first tip is to check that these lines do not generate an error/exception:
detectgraph(&gd,&gm);
initgraph(&gd,&gm,"e:\\tc\\bgi");
putpixel(x,y,WHITE);
Nice program. But, you haven't initialized any loop as well as lines coded in while-loop were partially incorrect. Here is my try:-
i = 1; // loop initialization
do {
putpixel(x, y, 15);
while(p >= 0) {
y = y + 1;
p = p - (2 * dx);
}
x = x + 1;
p = p + (2 * dy);
i = i + 1;
}
while(i <= dx);
A way to rectify the problem is by changing the path in the initgraph function according to the address mentioned in the screenshot.
detectgraph(&gd,&gm);
initgraph(&gd,&gm,"C:\\TURBOC3\\bgi");
putpixel(x,y,WHITE);
I have the below code to choose sin or cos to be integrated,
while( x !=1 || y !=(1||0) ){
printf("Sin (1) or Cos (0)?\n");
x = scanf("%d",&y);
_flushall();
if(y==1){
printf("Sin set\n");
}
else if(y==0){
printf("Cos set\n");
}
}
However the
y!= (1||0)
never evaluates to true for y == 0 , can someone explain what's wrong here? Thanks.
You need (y != 1 && y != 0) (or similar, it depends on what you really mean to express there). The || operator is being applied to the operands 1 and 0. Put another way, y != (1 || 0) means "Do (1 || 0) then do y != result".
You are attempting to effectively code directly Boolean algebra, and C doesn't accept it in the manner you've provided.
while( x !=1 || y !=(1||0) )
should be
while( (x!=1) || ( (y!=1) || (y!=0) ) )
Never underestimate the value of using excess parentheses in C. The optimizer will likely optimize the code to be more efficient anyways.
The part of code that generates this error evaluates as follows:
LHS (left hand side), RHS (right hand side)
LHS = y
!= (1||0) [definition given]
!= (1) [b/c (1||0) = (1)]
y != (0||1)
is equivalent to
y != 1
since 0||1 is 1. You'll need two comparisons if you want y != 0 or y != 1.