What does my destructor need to be in this function? - c++

My program executes fine, except at the end, when I debug it, it's getting a segmentation error after calling my destructor. I'm not sure what the cause of the issue is. I've posted 2 of the relevant files.
Breakpoint 1, main () at Prog3.cc:12
12 cout << "Program executed" << endl;
(gdb) s
Program executed
~Lex (this=0x80375c4) at lex.cc:36
36 delete [] str;
(gdb) s
37 }
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0xfef49418 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string () from /usr/sfw/lib/libstdc++.so.6
(gdb) Quit
lex.h is below:
#ifndef LEX_H
#define LEX_H
#include "token.h"
#include <iostream>
#include <stdlib.h>
class Lex {
public:
Lex(istream& in, string fileName);
//Lex();
//Lex(const Lex& l);
~Lex();
static const int INTLIT = 1;
static const int FLOATLIT = 2;
static const int STRLIT = 3;
static const int IDENT = 4;
static const int PLUS = 5;
static const int MINUS = 6;
static const int TIMES = 7;
static const int DIVIDE = 8;
static const int REM = 9;
static const int ASSIGN = 10;
static const int LPAREN = 11;
static const int RPAREN = 12;
static const int COMMA = 13;
static const int EQ = 14;
static const int LT = 15;
static const int LE = 16;
static const int GT = 17;
static const int GE = 18;
static const int NE = 19;
static const int SET = 20;
static const int PRINT = 21;
static const int WHILE = 22;
static const int DO = 23;
static const int END = 24;
static const int AND = 25;
static const int OR = 26;
static const int IF = 27;
static const int THEN = 28;
static const int ELSE = 29;
static const int ENDIF = 30;
static const int PROGRAM = 31;
static const int ENDOFFILE = 32;
static const int ERROR = 33;
int charIndex;
int lineIndex;
int spaceIndex;
int lineNum;
int lineLength[100];
char ch;
bool hashCheck;
bool stopLoop;
Token nextToken();
char nextChar();
char str[256][256];
bool checkSet;
void printLex();
string idents[256];
int identCount;
friend ostream& operator<<(ostream& out, const Token& t);
};
#endif
#include "lex.h"
#include "token.h"
#include <iostream>
#include <fstream>
#include <stdlib.h>
lex.cc is here.
Lex::Lex(istream& in, string fileName) {
stopLoop = false;
charIndex = 0;
lineIndex = 0;
identCount = 0;
lineNum = 0;
hashCheck = false;
checkSet = false;
int tempSize;
ifstream file;
string temp;
for (int i = 0; i < 100; ++i)
lineLength[i] = 0;
if (!file.is_open()) { file.open(fileName.c_str()); }
while(!file.eof()) {
std::getline(file,temp);
tempSize = temp.size();
for (int i = 0; i < tempSize; ++i) {
str[lineNum][i] = temp[i];
lineLength[lineNum] += 1;
}
lineNum++;
}
file.close();
}
Lex::~Lex() {
delete [] str;
}
void Lex::printLex() {
charIndex = 0;
lineIndex = 0;
while (stopLoop == false) {
cout << nextToken();
// cout << "Line index: " << lineIndex << endl;
}
}
ostream& operator <<(ostream& out, const Token& t) {
out << t.type() << " \t " << t.lexeme() << " \t \t " << (t.line() + 1) << " \t \t " << t.pos() << endl;
return out;
}
bool isReal(char ch) {
string alphabet = "abcdefghijklmnopqrstuvwxyz1234567890(){}<>+-/=!*,%&|.";
if (alphabet.find(ch) != alphabet.npos) return true;
else return false;
}
bool isNum(char ch) {
string specialChars = "1234567890.";
if (specialChars.find(ch) != specialChars.npos) return true;
else return false;
}
bool isNumFinal(string b) {
int length = b.length();
const char* temp = b.c_str();
bool henry = true;
for (int i = 0; i < length; ++i) {
if (henry == false) { break; }
henry = isNum(temp[i]);
}
return henry;
}
bool isSpecialChar(char ch) {
string specialChars = "(){}<>+-/=!*,%&|";
if (specialChars.find(ch) != specialChars.npos) return true;
else return false;
}
char Lex::nextChar() {
if (lineIndex >= lineNum) {
// cout << "End of file reached\n";
stopLoop = true;
return '#';
}
else if (charIndex >= lineLength[lineIndex]) {
lineIndex++;
charIndex = 0;
return nextChar();
}
else if (str[lineIndex][charIndex] == '#') {
hashCheck = true;
while (hashCheck = true) {
if (str[lineIndex][charIndex] == '#') { hashCheck = false; }
charIndex++;
if (charIndex > lineLength[lineIndex]) {
charIndex = 0;
lineIndex++;
}
}
}
else {
ch = str[lineIndex][charIndex];
charIndex++;
return ch;
}
cout << "you shouldn't be here\n";
return str[lineIndex][charIndex];
}
Token Lex::nextToken() {
if (charIndex == lineIndex && charIndex == 0) { ch = nextChar(); }
while (ch == ' ') { ch = nextChar(); }
// cout << "CI: " << charIndex << endl;
string build;
int tempCharIndex = charIndex;
int tempLineIndex = lineIndex;
build += ch;
if (charIndex == lineIndex && charIndex == 0) { build = ""; }
if (checkSet == true) {
checkSet = false;
while (ch != ' ' && tempLineIndex == lineIndex) {
ch = nextChar();
if (ch != ' ' && tempLineIndex == lineIndex)
build += ch;
}
idents[identCount] = build;
identCount++;
return Token(IDENT, build, tempLineIndex, tempCharIndex);
}
else if (isSpecialChar(ch)) {
switch(ch) {
case '(':
ch = nextChar();
return Token(LPAREN, build, tempLineIndex, tempCharIndex);
case ')':
ch = nextChar();
return Token(RPAREN, build, tempLineIndex, tempCharIndex);
case '{':
ch = nextChar();
return Token(THEN, build, tempLineIndex, tempCharIndex);
case '}':
ch = nextChar();
return Token(ENDIF, build, tempLineIndex, tempCharIndex);
case '+':
ch = nextChar();
return Token(PLUS, build, tempLineIndex, tempCharIndex);
case '-':
ch = nextChar();
return Token(MINUS, build, tempLineIndex, tempCharIndex);
case '/':
ch = nextChar();
return Token(DIVIDE, build, tempLineIndex, tempCharIndex);
case '*':
ch = nextChar();
return Token(TIMES, build, tempLineIndex, tempCharIndex);
case '=':
ch = nextChar();
if (ch == '=') {
build += ch;
ch = nextChar();
return Token(EQ, build, tempLineIndex, tempCharIndex);
}
else {
return Token(ASSIGN, build, tempLineIndex, tempCharIndex);
}
case '>':
ch = nextChar();
if (ch == '=') {
build += ch;
ch = nextChar();
return Token(GE, build, tempLineIndex, tempCharIndex);
}
else return Token(GT, build, tempLineIndex, tempCharIndex);
case '<':
ch = nextChar();
if (ch == '=') {
build += ch;
ch = nextChar();
return Token(LE, build, tempLineIndex, tempCharIndex);
}
else return Token(LT, build, tempLineIndex, tempCharIndex);
case '!':
ch = nextChar();
if (ch == '=') {
build += ch;
ch = nextChar();
return Token(NE, build, tempLineIndex, tempCharIndex);
}
else return Token(ERROR, build, tempLineIndex, tempCharIndex);
case '%':
ch = nextChar();
return Token(REM, build, tempLineIndex, tempCharIndex);
case '&':
ch = nextChar();
return Token(AND, build, tempLineIndex, tempCharIndex);
case '|':
ch = nextChar();
return Token(OR, build, tempLineIndex, tempCharIndex);
default:
return Token(ERROR, build, tempLineIndex, tempCharIndex);
}
}
else if (isNum(ch)) {
tempCharIndex = charIndex;
while (ch != ' ' && tempLineIndex == lineIndex) {
ch = nextChar();
if (isSpecialChar(ch)) {
break;
}
if (ch != ' ' && tempLineIndex == lineIndex)
build += ch;
}
if (isNumFinal(build)) {
if (build.find('.') != build.npos)
return Token(FLOATLIT, build, tempLineIndex, tempCharIndex);
else return Token(INTLIT, build, tempLineIndex, tempCharIndex);
}
else return Token(ERROR, build, tempLineIndex, tempCharIndex);
}
else {
tempCharIndex = charIndex;
while (ch != ' ' && tempLineIndex == lineIndex) {
ch = nextChar();
// cout << "ch: " << ch << endl;
if (ch != ' ' && tempLineIndex == lineIndex)
//cout << "inserted: " << ch << endl;
build += ch;
}
if (build.compare("while") == 0)
return Token(WHILE, build, tempLineIndex, tempCharIndex);
else if (build.compare("if") == 0)
return Token(IF, build, tempLineIndex, tempCharIndex);
else if (build.compare("print") == 0)
return Token(PRINT, build, tempLineIndex, tempCharIndex);
else if (build.compare("end") == 0)
return Token(ENDOFFILE, build, tempLineIndex, tempCharIndex);
else if (build.compare("else") == 0)
return Token(ELSE, build, tempLineIndex, tempCharIndex);
else if (build.compare("do") == 0) { return Token(DO, build, tempLineIndex, tempCharIndex); }
else if (build.compare("set") == 0) {
checkSet = true;
// cout << "CI: " << str[lineIndex] << endl;
return Token(SET, build, tempLineIndex, tempCharIndex);
}
else {
for (int i = 0; i < identCount; ++i) {
if (build.compare(idents[i]) == 0) { return Token(IDENT, build, tempLineIndex, tempCharIndex); }
}
cout << "build:" << build << ".\n";
return Token(STRLIT, build, tempLineIndex, tempCharIndex);
}
}
}

Don't call delete[] unless you called new[]. str is a statically sized array in your class, you need neither new[] nor delete[] for it.
Your class consists entirely of objects which will either handle their own cleanup, or need no cleanup, so your destructor can simply be empty. Don't even declare it, and the compiler will provide the correct destructor for you in this case.

str does not have dynamic storage duration but you are trying to delete it in the destructor. Remove delete[] str from your destructor.
You also are not doing any bounds checking when you fill str. This may cause you to overwrite other member variables causing additional problems and is likely the cause of the fault you are experiencing.
// tempSize and/or lineNum may be greater than 256
for (int i = 0; i < tempSize; ++i) {
str[lineNum][i] = temp[i];
lineLength[lineNum] += 1;
}

You have
Lex::~Lex() {
delete [] str;
}
in your code, but str is not heap allocated. It is a data member of your Lex class
I believe a recent GCC invoked as g++ -Wall -g would probably have warned you about that mistake.

Well, cause you don't need to delete the str array at all, it's not created by you using new so you don't need to call delete.
VS gives me :
warning C4154: deletion of an array expression; conversion to pointer supplied

Related

Issue in reverse polish notation task in C++

The program analyzes the entered expression, converts it into reverse Polish notation and calculates the result.My program works correctly with expressions without brackets, but if I use an expression with brackets, I get an error: "Op" was nullptr. I have no idea why as my Stack "Op" must be initialized.(I marked where the error occurs in the code).
My code:
#include <iostream>
#include <string>
#include <iomanip>
struct Stack {
char info;
Stack* next;
} *begin;
int Prior(char);
Stack* InStack(Stack*, char);
Stack* OutStack(Stack*, char&);
double Result(char*);
double mas[201];
Stack* InStack(Stack* p, char in) {
Stack* t = new Stack;
t->info = in;
t->next = p;
return t;
}
Stack* OutStack(Stack* p, char& in) {
Stack* t = p;
in = p->info;
p = p->next;
delete t;
return p;
}
int Prior(char a) {
switch (a) {
case '^': return 4;
case '*': case '/': return 3;
case '-': case '+': return 2;
case '(': return 1;
}
return 0;
}
double Result(char* str) {
int i;
char ss, ss1, ss2, ssR = 'z' + 1;
double op1, op2, res = 0, mas[200];
std::cout << "Input data:" << std::endl;
for (i = 0; str[i] != '\0'; ++i)
{
ss = str[i];
if (ss >= 'a' && ss <= 'z')
{
std::cout << ss << " = ";
std::cin >> mas[int(ss)];
}
}
for (i = 0; str[i] != '\0'; ++i)
{
ss = str[i];
if (!(ss == '+' || ss == '-' || ss == '*' || ss == '/'))
{
begin = InStack(begin, ss);
}
else
{
begin = OutStack(begin, ss2);
begin = OutStack(begin, ss1);
op2 = mas[int(ss2)];
op1 = mas[int(ss1)];
switch (ss)
{
case'+':res = op1 + op2; break;
case'-':res = op1 - op2; break;
case'*':res = op1 * op2; break;
case'/':res = op1 / op2; break;
}
mas[int(ssR)] = res;
begin = InStack(begin, ssR);
ssR++;
}
}
return res;
}
int main()
{
Stack* t, * Op = NULL;
char a;
char In[81], Out[81];
int k = 0, l = 0;
std::cout << "Input form: " << std::endl;
std::cin >> In;
while (In[k] != '\0')
{
if (In[k] >= 'a' && In[k] <= 'z')
{
Out[l++] = In[k];
}
if (In[k] == '(')
{
Op == InStack(Op, In[k]);
}
if (In[k] == ')')
{
while ((Op->info) != '(') //ERROR HERE
{
Op = OutStack(Op, a);
if (!Op)
{
a = '\0';
}
Out[l++] = a;
}
t = Op;
Op = Op->next;
delete t;
}
if (In[k] == '+' || In[k] == '-' || In[k] == '*' || In[k] == '/')
{
while (Op != NULL && Prior(Op->info) >= Prior(In[k]))
{
Op = OutStack(Op, a);
Out[l++] = a;
}
Op = InStack(Op, In[k]);
}
k++;
}
while (Op != NULL)
{
Op = OutStack(Op, a);
Out[l++] = a;
}
Out[l] = '\0';
std::cout << "\nPolish: " << Out << std::endl;
std::cout << "\nRes = " << Result(Out) << std::endl;
}

c++ terminate std::logic error ......where did my code go wrong?

I'm encountering this really weird error and I dont know where I'm constructing a string with a null parameter, could someone please help me out? Thanks!
Here's the error:
terminate_called_after_throwing_an_instance_of_'std::logic_error'
__what():__basic_string::_M_construct_null_not_valid
Here's my code:
/*
ID: 2005amr1
TASK: friday
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
using namespace std;
vector <string> days = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
bool leap (int y){
if (y%100 == 0){
if (y%400 == 0){
return true;
}
else{
return false;
}
}
else if (y%4 == 0){
return true;
}
else{
return false;
}
}
int targetedSearch (vector<string> array, string key){
int index = 0;
while( (index < array.size( )) && (key != array[index])){
if (array[index] != key){
index++;
}
}
return (index);
}
string findLastDay(string FDAY, int daysInMonth){ // all good here
int indexOfString = targetedSearch(days, FDAY);
if (FDAY == "Mon" && daysInMonth == 28){
return ("Sun");
}
return (days[(daysInMonth - (7*(daysInMonth/7))-1) + indexOfString]);
}
string find13Day (string firstDay){ // all good here
int indexOfString = targetedSearch(days, firstDay);
return (days[indexOfString+5]);
}
string findFirstDayNextMonth (string LDAY){
int indexOfString = targetedSearch(days, LDAY);
if (indexOfString+1 > 6){
return (days[(indexOfString+1)-7]);
}
else{
return (days[indexOfString+1]);
}
}
int numDays (int month, int year){
switch(month) {
case 0:
return 31;
break;
case 1:
if (leap(year) == true){
return 29;
}
else{
return 28;
}
break;
case 2:
return 31;
break;
case 3:
return 30;
break;
case 4:
return 31;
break;
case 5:
return 30;
break;
case 6:
return 31;
break;
case 7:
return 31;
break;
case 8:
return 30;
break;
case 9:
return 31;
break;
case 10:
return 30;
break;
case 11:
return 31;
break;
}
return 31;
}
int main() {
ofstream fout ("friday.out");
ifstream fin ("friday.in");
string startDay = "Mon";
int dayValues[7] = {0,0,0,0,0,0,0};
int n;
fin >> n;
map <string,int> dayValue;
for (int i = 1900; i< 1900+n; i++){
for (int m =0; m<12; m++){
int PAN = numDays (m,i);
string tday = find13Day(startDay);
dayValues[targetedSearch(days,tday)]++;
string LDAY = findLastDay(startDay, PAN);
startDay = findFirstDayNextMonth(LDAY);
}
}
fout << " " << dayValues[5] << " " << dayValues[6]<< " " << dayValues[0]<< " " << dayValues[1]<< " " << dayValues[2]<< " " << dayValues[3]<< " " << dayValues[4];
}

How can i print this caculation? -DS stack question

this is data structure (stack) question. in c++. (no use STL)
i want input Infix Formula file(txt, if there is not file, input is user's typing.)
and convert Postfix Formula, then caculate formula.
how can i input Postfix Formula in caculate fuction ?
i try make file and read file, but is not work. (i try change endl position(delete), also not work.)
ArrayStack.h
#include <iostream>
#include <cstdlib>
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
inline void error(const char *message)
{
cout << message << endl;
exit(1);
}
const int MAX_STACK_SIZE = 20;
class ArrayStack
{
private:
int top;
int data[MAX_STACK_SIZE];
public:
ArrayStack()
{
top = -1;
}
~ArrayStack()
{
}
bool isEmpty()
{
return top == -1;
}
bool isFull()
{
return top == MAX_STACK_SIZE - 1;
}
void push(int e)
{
if (isFull())
error("스택 포화 에러");
data[++top] = e;
}
int pop()
{
if (isEmpty())
error("스택 공백 에러");
return data[top--];
}
int peek()
{
if (isEmpty())
error("스택 공백 에러");
return data[top];
}
void display()
{
printf("[스택 항목의 수 = %2d] ==> ", top + 1);
for (int i = 0; i < top; i++)
printf("<%2d>", data[i]);
printf("\n");
}
};
pg1_stack.cpp
#pragma warning(disable:4996)
#include "ArrayStack.h"
#include <string.h>
#include <fstream>
inline static int precedence(char op)
{
switch (op) {
case '(': case ')': return 0;
case '+': case '-': return 1;
case '*': case '/': return 2;
}
return -1;
}
void infixToPostfix(FILE *fp = stdin)
{
char c, op;
double val;
ArrayStack stack;
ofstream os;
os.open("stack_Data.txt");
while ((c = getc(fp)) != '\n')
{
if ('0' <= c && c <= '9')
{
ungetc(c, fp);
fscanf_s(fp, "%lf", &val);
printf("%4.1f ", val);
os << val;
}
else if (c == '(')
stack.push(c);
else if (c == ')')
{
while (!stack.isEmpty())
{
op = stack.pop();
if (op == '(') break;
else
printf("%c ", op);
os << op;
}
}
else if (c == '+' || c == '-' || c == '*' || c == '/')
{
while (!stack.isEmpty())
{
op = stack.peek();
if (precedence(c) <= precedence(op))
{
printf("%c ", op);
os << op;
stack.pop();
}
else break;
}
stack.push(c);
}
}
while (!stack.isEmpty()) {
char c2 = stack.pop();
os << c2;
printf("%c ", c2);
}os << endl;
os.close();
printf("\n");
}
double calcPostfixExpr(const char *filename)
{
FILE *fp = fopen(filename, "r");
if (fp == NULL)
error("Error: 파일 존재하지 않습니다.\n");
char ch;
ArrayStack stack;
while ((ch = getc(fp)) != '\n')
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
double right = stack.pop();
double left = stack.pop();
switch (ch) {
case '+':
stack.push(left + right);
break;
case '-':
stack.push(left - right);
break;
case '*':
stack.push(left * right);
break;
case '/':
stack.push(left / right);
break;
}
}
else if ('0' <= ch && ch <= '9')
{
ungetc(ch, fp);
double val;
fscanf_s(fp, "%lf", &val);
stack.push(val);
}
}
fclose(fp);
return stack.pop();
}
void main() {
infixToPostfix();
double res = calcPostfixExpr("stack_Data.txt");
printf("%f", res);
system("Pause");
}
this is before try make file and read file way
#pragma warning(disable:4996)
#include "ArrayStack.h"
#include <string.h>
#include <fstream>
inline static int precedence(char op)
{
switch (op) {
case '(': case ')': return 0;
case '+': case '-': return 1;
case '*': case '/': return 2;
}
return -1;
}
void infixToPostfix(FILE *fp = stdin)
{
char c, op;
double val;
ArrayStack stack;
while ((c = getc(fp)) != '\n')
{
if ('0' <= c && c <= '9')
{
ungetc(c, fp);
fscanf_s(fp, "%lf", &val);
printf("%4.1f ", val);
}
else if (c == '(')
stack.push(c);
else if (c == ')')
{
while (!stack.isEmpty())
{
op = stack.pop();
if (op == '(') break;
else
printf("%c ", op);
}
}
else if (c == '+' || c == '-' || c == '*' || c == '/')
{
while (!stack.isEmpty())
{
op = stack.peek();
if (precedence(c) <= precedence(op))
{
printf("%c ", op);
stack.pop();
}
else break;
}
stack.push(c);
}
}
while (!stack.isEmpty()) {
char c2 = stack.pop();
printf("%c ", c2);
}
printf("\n");
}
double calcPostfixExpr(FILE* fp = stdin)
{
char ch;
ArrayStack stack;
while ((ch = getc(fp)) != '\n')
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
double right = stack.pop();
double left = stack.pop();
switch (ch) {
case '+':
stack.push(left + right);
break;
case '-':
stack.push(left - right);
break;
case '*':
stack.push(left * right);
break;
case '/':
stack.push(left / right);
break;
}
}
else if ('0' <= ch && ch <= '9')
{
ungetc(ch, fp);
double val;
fscanf_s(fp, "%lf", &val);
stack.push(val);
}
}
return stack.pop();
}
void main() {
infixToPostfix();
system("Pause");
}

Link error when compiling basic assembler

I was trying to create a special assembler that will run with a specific machine type. I was trying to compile the program, but got a linker error:
/usr/bin/ld: lexer.o: in function `Lexer::lex(std::__cxx11::basic_string, std::allocator >)':
lexer.cpp:(.text+0x2ee): undefined reference to `Lexer::isSpecial(char)'
collect2: error: ld returned 1 exit status
Screenshot here
I have 3 main files: lexer.h, lexer.cpp, sasm.cpp. Here's the code.
lexer.h:
#ifndef LEXER_H
#define LEXER_H
#include <iostream>
#include <vector>
// type definitions
typedef uint8_t byte;
typedef std::vector<std::string> strings;
enum State : byte {
START,
READCHAR,
READBLOCK,
SKIP,
DUMP,
COMMENT,
END
};
// Instructions definitions
#define ADD 0x40000001
#define SUB 0x40000002
#define TIME 0x40000003
#define DIVIDE 0x40000004
#define HALT 0x40000000
class Lexer {
private:
bool isSpace(char c);
bool isSpecial(char c);
bool isGroup(char c);
char end_char, beg_char;
public:
strings lex(std::string s);
};
#endif
lexer.cpp:
#include "lexer.h"
strings Lexer::lex(std::string s) {
strings strLst;
char lexEme[256];
int i = 0;
int j = 0;
State state = START;
int done = 0;
int len = s.length();
int balance = 0;
while (i < len) {
switch (state) {
case START:
if (isSpace(s[i])) {
state = SKIP;
} else if (isGroup(s[i])) {
if (s[i] == '"') {
lexEme[j] = s[i];
j++;
i++;
}
state = READBLOCK;
} else if (s[i] == '/' && s[i + 1] == '/') {
i += 2;
state = COMMENT;
} else {
state = READCHAR;
}
break;
case READCHAR:
if (isSpace(s[i])) {
state = DUMP;
} else if (s[i] == '\\') {
i += 2;
} else if (isGroup(s[i])) {
if (s[i] == '"') {
lexEme[j] = s[i];
j++;
i++;
}
state = READBLOCK;
} else if (isSpecial(s[i])) {
if (j == 0) {
lexEme[j] = s[i];
j++;
i++;
}
state = DUMP;
} else if (s[i] == '/' && s[i + 1] == '/') {
i += 2;
state = COMMENT;
} else {
lexEme[j] = s[i];
j++;
i++;
}
break;
case READBLOCK:
if (s[i] == beg_char && s[i] != '"') {
balance++;
lexEme[j] = s[i];
j++;
i++;
} else if (s[i] == end_char) {
balance--;
lexEme[j] = s[i];
j++;
i++;
if (balance <= 0) {
state = DUMP;
}
} else if (end_char == '"' && s[i] == '\\') {
// TODO: fix this to actually record the chars
i += 2;
} else {
lexEme[j] = s[i];
j++;
i++;
}
break;
case SKIP:
if (isSpace(s[i])) {
i++;
} else {
state = READCHAR;
}
break;
case DUMP:
if (j < 0) {
lexEme[j] = 0;
strLst.push_back(lexEme);
j = 0;
}
state = START;
break;
case COMMENT:
if (s[i] != '\n') {
i++;
} else {
state = READCHAR;
}
break;
case END:
i = len;
break;
}
}
if (j > 0) {
lexEme[j] = 0;
strLst.push_back(lexEme);
}
return strLst;
}
// This function allows us what a space is
bool Lexer::isSpace(char c) {
switch (c) {
case '\n':
case '\r':
case '\t':
case '\v':
case ' ':
case '\f':
return true;
default:
return false;
}
}
bool Lexer::isGroup(char c) {
beg_char = c;
switch (c) {
case '"':
end_char = '"';
return true;
case '(' :
end_char = ')';
return true;
case ')':
return true;
default:
return false;
}
}
bool isSpecial(char c) {
switch (c) {
case '[':
case ']':
return true;
default:
return false;
}
}
sasm.cpp:
#include <fstream>
#include "lexer.h"
typedef uint32_t i32;
using namespace std;
vector<i32> compile(strings s);
bool isInteger(string s);
bool isPrimitive(string s);
i32 mapToNumber(string s);
int main (int argc, char* argv[]) {
// Check for input errors
if (argc != 2) {
cerr << "Usage: " << argv[0] << " <sasm-file>" << endl;
exit(1);
}
// Read input file
ifstream infile;
infile.open(argv[1]);
if (!infile.is_open()) {
cerr << argv[1] << ": file can't be found" << endl;
exit(1);
}
string line;
string contents;
while (getline(infile, line)) {
contents += line + "\n";
}
infile.close();
// Parse infile
Lexer lexer;
strings lexEmes = lexer.lex(contents);
// Compile binary
vector<i32> instructions = compile(lexEmes);
// Write instructions to file
ofstream ofile;
ofile.open("out.bin", ios::binary);
for (i32 i = 0; i < instructions.size(); i++) {
ofile.write(reinterpret_cast<char*>(&instructions[i]), sizeof(i32));
}
ofile.close();
return 0;
}
vector<i32> compile(strings s) {
vector<i32> instructions;
for (i32 i = 0; i < s.size(); i++) {
if (isInteger(s[i])) {
instructions.push_back(stoi(s[i]));
} else {
i32 instruction = mapToNumber(s[i]);
if (instruction != -1) {
instructions.push_back(instruction);
} else {
cerr << "\033[1;31m" << s[i] << "\033[0m Invalid instruction" << std::endl;
}
}
}
return instructions;
}
bool isInteger(string s) {
for (i32 i = 0; i < s.length(); i++) {
if (!isdigit(s[i])) {
return false;
}
}
return true;
}
i32 mapToNumber(string s) {
if (s == "+") {
return ADD;
} else if (s == "-") {
return SUB;
} else if (s == "*") {
return TIME;
} else if (s == "/") {
return DIVIDE;
}
return -1; // Invalid instruction
}
Thanks for your answers.
You are missing the class reference in the function definition.
bool Lexer::isSpecial(char c)
^^^^^^^

Infix/Postfix evaluator terminating issue

I've got a few different functions that on their own work fine. Now I am trying to put them together into one file. My debugger is throwing segmentation faults in the infixToPostfix function.
When I watch the ns variable, it does not show anything getting assigned to it, but it prints out the postfix expression when I actually run the code. When ns passes into PostfixEvaulation, it runs to the top member function of TemplateStack and crashes with:
terminate called after throwing an instance of "std::string"
This only happens when I pass a string with an operator. When I pass a string of just numbers, everything runs fine,
but it still does not seem to call PostfixEvaluation.
#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo>
using namespace std;
//Class Template Stack declaration
template <class T>
class TemplateStack {
public:
typedef T type;
TemplateStack()
{
max_size_ = 50;
TopOfStack = 0;
data_ = new T[max_size_];
} //Default Constructor taking no parameters
void push(T element)
{
if (TopOfStack == max_size_)
throw string("Stack's underlying storage is overflow");
TopOfStack++;
data_[TopOfStack] = element;
}
void pop() {
if (TopOfStack == -1)
throw string("Stack is empty");
TopOfStack--;
}
T top() {
if (TopOfStack == -1)
throw string("Stack is empty");
return data_[TopOfStack];
}
private:
int TopOfStack; //Generic data type for the top element of stack
size_t max_size_;
T* data_;
};
//Function to Evauluate the Postfix notation expresion
int PostfixEvaulation(string input){
//string input;
int operand1, operand2, result,number;
TemplateStack<char>operation;
stringstream temp;
int i=0;
while (i < input.length())
{
if (isdigit(input[i]))
{
operation.push(input[i]);
}
else
{
operand2 = operation.top();
temp << operation.top();
operation.pop();
operand1 = operation.top();
temp << operation.top();
operation.pop();
switch(operand1,operand2)
{
case '+': result=operand1 + operand2;
break;
case '-': result=operand1 - operand2;
break;
case '*': result=operand1 * operand2;
break;
case '/': result=operand1 / operand2;
break;
}
operation.push(result);
}
i++;
}
cout << "The result is: "<<temp.str()<<endl;
//cin.ignore(numeric_limits<streamsize>::max(), '\n');
return 0;
}
//Function to return precedence of operators
int prec(char c)
{
if(c == '^')
return 3;
else if(c == '*' || c == '/')
return 2;
else if(c == '+' || c == '-')
return 1;
else
return -1;
}
//Function: Convert Infix to Postfix
void infixToPostfix(string s)
{
TemplateStack<char> st;
st.push('N');
int l = s.length();
string ns;
for (int i = 0; i < l; i++) {
// If the scanned character is an operand, add it to output string.
if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {
ns += s[i];
}
// If the scanned character is an ‘(‘, push it to the stack.
else if (s[i] == '(') {
st.push('(');
}
// If the scanned character is an ‘)’, pop and to output string from the stack
// until an ‘(‘ is encountered.
else if (s[i] == ')') {
while (st.top() != 'N' && st.top() != '(') {
char c = st.top();
st.pop();
ns += c;
}
if (st.top() == '(') {
char c = st.top();
st.pop();
}
}
//If an operator is scanned
else {
while (st.top() != 'N' && prec(s[i]) <= prec(st.top())) {
char c = st.top();
st.pop();
ns += c;
}
st.push(s[i]);
}
}
//Pop all the remaining elements from the stack
while (st.top() != 'N') {
char c = st.top();
st.pop();
ns += c;
}
cout << "Here is the ns variable: "<< ns << endl;
PostfixEvaulation(ns);//Call the PostFixEvaluationFunction with the ns (postfix notation) variab
}
//Function: User inputs Expression
void GetInput(){
string input;
cout << "Enter Infix Expression: ";
getline(cin, input);
infixToPostfix(input);
}
int main()
{
GetInput();
}