Я пытаюсь переобучить биты о наследовании C++, а также написать программу, которая оценивает простые математические выражения (как строки) с нуля для практики, но я сталкиваюсь с большим количеством проблемы. Мой единственный предыдущий опыт работы с lexing, как это, с OCaml (и Ocamllex/yacc), и это совсем немного отличается.C++ Tokenizing математическое выражение с использованием классов
Во всяком случае, я создал простой токен класса:
class Token{
public:
string type;
string characters;
};
Где type
является строкой, которая сообщает тип маркеров (плюс, минус, и т.д.) и characters
является строкой, что маркер на самом деле состоит из. Из этого я сделал производные классы для каждого токена. Вот один для +:
class Plus: public Token{
public:
Plus(){
type = "plus";
characters = "+";
}
};
Minus
, Times
, DividedBy
, LeftParenthesis
, RightParenthesis
и Number
все сделали то же самое. Однако для Number
я хотел добавить в double
, в котором хранится значение токена, поэтому он также включает в себя общедоступную переменную double value
, и ее конструктор устанавливает это значение. Вероятно, вы можете увидеть, где здесь возникнут проблемы, и я немного доберусь до них.
У меня есть функция, которая считывает строку, разбивает его на эти подстроки, и сохраняет его как вектор строк (So "3.2 +( -1.83)"
возвращает вектор со струнами "3.2"
, "+"
, "("
, "-1.83"
и ")"
). У меня есть еще один, который превращает все это в объекты Token и сохраняет его как вектор Token (так он делает вещи вроде tokens.push_back(LeftParenthesis());
).
Теперь я хочу взять этот вектор токена и сделать с ним все. (Цель состоит в том, чтобы использовать алгоритм маневрового двора, чтобы поместить его в обратную польскую нотацию, а затем оценить его.) Однако у меня много проблем, в основном из-за того, что я использую вектор Token, и каждый элемент это производный тип токена.
Самая большая проблема в том, что я не могу получить доступ к элементу value
маркеров Number
. Я пробовал другие вещи, такие как использование виртуальных функций getter, и он все еще не работает правильно. Другая проблема заключается в том, что единственный способ определить, что такое токен, - это прочитать элемент characters
, который, кажется, делает всю вещь подкласса бессмысленной.
Возможно ли продолжить использование метода, который я начал, или просто отказаться от всего класса Token и его подклассов и просто работать со строками? Это было бы не самым худшим, так как я изучал материал о наследовании со всеми ошибками, которые я получал.
Edit: В ответ на Thomas Matthews: я играл с виртуальными методами (которые не работают либо), так вот фактический Токен класс и номер, а также:
class Token{
public:
string type;
string characters;
virtual double getValue();
};
class Number: public Token{
public:
double value;
Number(string chars){
type = "number";
characters = chars;
value = atof(chars.c_str());
}
virtual double getValue(){
return value;
}
};
И вот основной метод, который я играю с, который просто принимает случайную строку, я сделал и попытки напечатать его обратно, но при обращении к value
элемент любого числа при этом:
int main(){
vector<Token> tvec = tokenize("5 + 4 - 11 * (-3.2 + .19)");
for(vector<Token>::iterator it = tvec.begin(), end = tvec.end(); it != end; ++it)
if(it->type == "number")
cout << it->getValue(); // doesn't work
else
cout << it->characters;
cout << endl;
return 0;
}
Показать класс для 'Number' и простую программу' main', которая демонстрирует использование класса. –
Обратите внимание, что при использовании вашего вектора «токенов» вы, вероятно, страдаете [срезом объектов] (http://stackoverflow.com/questions/274626/what-is-object-slicing) при вставке токенов в вектор. См. [Здесь] (http://stackoverflow.com/questions/9241680/list-of-polymorphic-objects) для использования в контейнерах. – Diego
Я добавил класс и простую программу. – chetlin