Pagini recente » Cod sursa (job #2511256) | Cod sursa (job #3250040) | Cod sursa (job #2836601) | Cod sursa (job #706731) | Cod sursa (job #2149787)
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <cstring>
const int MAX_MEM = 1000;
std::string AND = std::string("AND"),
OR = std::string("OR"),
NOT = std::string("NOT"),
SPACE = std::string(" "),
TRUE = std::string("TRUE"),
FALSE = std::string("FALSE"),
OPEN_PARENTHESES = std::string("("),
CLOSE_PARENTHESES = std::string(")");
class file
{
public:
file(FILE *fin)
{
m_fin = fin;
m_currentWord = SPACE;
m_currentChar = fgetc(fin);
}
void skipwhite()
{
while(m_currentWord == SPACE)
next();
}
void next()
{
char *c = &m_currentChar;
char buffer[1024];
if(*c == ' ' || *c == '(' || *c == ')' || *c == '\n')
{
buffer[0] = *c;
buffer[1] = 0;
*c = fgetc(m_fin);
}
else
{
char *pBuffer = buffer;
while(isalpha(*c))
*pBuffer = *c, pBuffer ++, *c = fgetc(m_fin);
*pBuffer = 0;
}
m_currentWord = std::string(buffer);
//printf("in next(), buffer = '%s'\n", buffer);
}
void unget()
{
ungetc(m_currentChar, m_fin);
}
std::string currentWord()
{
return m_currentWord;
}
private:
FILE *m_fin;
std::string m_currentWord;
char m_currentChar;
};
struct ValueTable
{
char m_value[128];
};
class Block
{
public:
virtual int eval(ValueTable *pValueTable) = 0;
};
class Expr
{
public:
virtual int eval(ValueTable *pValueTable) = 0;
void AddBlock(Block *pBlock)
{
m_blocks.push_back(pBlock);
}
protected:
std::vector<Block*> m_blocks;
};
class OrExpr: public Expr
{
public:
virtual int eval(ValueTable *pValueTable)
{
int result = 0;
for(auto i: m_blocks)
result = result || i->eval(pValueTable);
return result;
}
};
class AndExpr: public Expr
{
public:
virtual int eval(ValueTable *pValueTable)
{
int result = 1;
for(auto i: m_blocks)
result = result && i->eval(pValueTable);
return result;
}
};
class Variable: public Block
{
public:
Variable(char ref)
{
m_ref = ref;
}
virtual int eval(ValueTable *pValueTable)
{
return pValueTable->m_value[m_ref];
}
private:
char m_ref;
};
class Value: public Block
{
public:
Value(int value)
{
m_value = value;
}
virtual int eval(ValueTable *pValueTable)
{
return m_value;
}
private:
int m_value;
};
class Not
{
public:
virtual int eval(ValueTable *pValueTable)
{
return !m_pBlock->eval(pValueTable);
}
void SetPBlock(Block* pBlock){m_pBlock = pBlock;}
private:
Block* m_pBlock;
};
class MemTable
{
public:
MemTable(int size = MAX_MEM)
{
m_size = size;
m_memAndExpr = (AndExpr*)malloc(m_size * sizeof(AndExpr));
m_pLastAndExpr = m_memAndExpr + m_size;
m_memOrExpr = (OrExpr*)malloc(m_size * sizeof(OrExpr));
m_pLastOrExpr = m_memOrExpr + m_size;
m_memVariable = (Variable*)malloc(m_size * sizeof(Variable));
m_pLastVariable = m_memVariable + m_size;
m_memValue = (Value*)malloc(m_size * sizeof(Value));
m_pLastValue = m_memValue + m_size;
m_memNot = (Not*)malloc(m_size * sizeof(Not));
m_pLastNot = m_memNot + m_size;
}
AndExpr* new_AndExpr(AndExpr value)
{
auto *p = m_memAndExpr;
memcpy(p, &value, sizeof(value));
m_memAndExpr++;
return p;
}
OrExpr* new_OrExpr(OrExpr value)
{
auto *p = m_memOrExpr;
memcpy(p, &value, sizeof(value));
m_memOrExpr++;
return p;
}
Value* new_Value(Value value)
{
auto *p = m_memValue;
memcpy(p, &value, sizeof(value));
m_memValue++;
return p;
}
Variable* new_Variable(Variable value)
{
auto *p = m_memVariable;
memcpy(p, &value, sizeof(value));
m_memVariable++;
return p;
}
Not* new_Not(Not value)
{
auto *p = m_memNot;
memcpy(p, &value, sizeof(value));
m_memNot++;
return p;
}
private:
int m_size;
AndExpr *m_memAndExpr, *m_pLastAndExpr;
OrExpr *m_memOrExpr, *m_pLastOrExpr;
Variable *m_memVariable, *m_pLastVariable;
Value *m_memValue, *m_pLastValue;
Not *m_memNot, *m_pLastNot;
};
MemTable g_memTable;
Block* ParseOrExpr(file *f);
Block* ParseAndExpr(file *f);
Block* ParseNot(file *f);
int main()
{
FILE *fin = fopen("bool.in", "r");
FILE *fout = fopen("bool.out", "w");
file f = file(fin);
ValueTable vtable;
f.next();
Block *program = ParseOrExpr(&f);
f.unget();
int n;
fscanf(fin, " %d ", &n);
for(int i = 0; i < 128; i++) vtable.m_value[i] = 0;
for(int i = 0; i < n; i++)
{
char c;
fscanf(fin, " %c", &c);
//printf("%c", c);
vtable.m_value[c] = !vtable.m_value[c];
fprintf(fout, "%d", program->eval(&vtable));
}
fclose(fin);
fclose(fout);
return 0;
}
int OrId = 0;
Block* ParseOrExpr(file *f)
{
int id = OrId++;
OrExpr *pOrExpr = g_memTable.new_OrExpr(OrExpr());
pOrExpr->AddBlock(ParseAndExpr(f));
while(f->currentWord() == OR)
{
f->next();
f->skipwhite();
pOrExpr->AddBlock(ParseAndExpr(f));
f->skipwhite();
}
return (Block*)pOrExpr;
}
Block* ParseAndExpr(file *f)
{
AndExpr *pAndExpr = g_memTable.new_AndExpr(AndExpr());
f->skipwhite();
pAndExpr->AddBlock(ParseNot(f));
while(f->currentWord() == AND)
{
f->next();
f->skipwhite();
pAndExpr->AddBlock(ParseNot(f));
f->skipwhite();
}
return (Block*)pAndExpr;
}
Block* ParseNot(file *f)
{
Not *pNot = NULL;
Block *pSubBlock;
f->skipwhite();
if(f->currentWord() == NOT)
{
pNot = g_memTable.new_Not(Not());
f->next();
}
f->skipwhite();
if(f->currentWord() == OPEN_PARENTHESES)
{
f->next();
f->skipwhite();
pSubBlock = ParseOrExpr(f);
f->next();
f->skipwhite();
}
else if(f->currentWord() == TRUE)
{
pSubBlock = g_memTable.new_Value(Value(true));
f->next();
f->skipwhite();
}
else if(f->currentWord() == FALSE)
{
pSubBlock = g_memTable.new_Value(Value(false));
f->next();
f->skipwhite();
}
else
{
pSubBlock = g_memTable.new_Variable(Variable(*(f->currentWord().begin())));
f->next();
f->skipwhite();
}
if(pNot != NULL)
{
pNot->SetPBlock(pSubBlock);
return (Block*)pNot;
}
else return pSubBlock;
}