#ifndef AST_H
|
#define AST_H
|
#include <vector>
|
#include <string>
|
|
class ast_node;
|
//class ast_visitor;
|
class Document;
|
class Block;
|
class Block_Table;
|
class Block_Code;
|
class Block_Line;
|
class Line;
|
class Word;
|
class Heading;
|
class List;
|
class MathDisp;
|
class Line_Word;
|
class Link;
|
class MathInline;
|
class Format;
|
class Format_Bold;
|
class Format_Italic;
|
class Format_Verbatim;
|
class Text;
|
|
class ast_visitor {
|
public:
|
virtual void* visit_Document(Document *d)=0;
|
virtual void* visit_Block_Table(Block_Table *bt)=0;
|
virtual void* visit_Block_Code(Block_Code *bc)=0;
|
virtual void* visit_Block_Line(Block_Line *bl)=0;
|
virtual void* visit_Heading(Heading *h)=0;
|
virtual void* visit_List(List *l)=0;
|
virtual void* visit_MathDisp(MathDisp *md)=0;
|
virtual void* visit_Line_Word(Line_Word *lw)=0;
|
virtual void* visit_Link(Link *l)=0;
|
virtual void* visit_MathInline(MathInline *mi)=0;
|
virtual void* visit_Format_Bold(Format_Bold *fb)=0;
|
virtual void* visit_Format_Italic(Format_Italic *fi)=0;
|
virtual void* visit_Format_Verbatim(Format_Verbatim *fv)=0;
|
virtual void* visit_Text(Text *t)=0;
|
};
|
|
class ast_node {
|
public:
|
virtual ~ast_node()=default;
|
virtual void* visit(ast_visitor *v)=0;
|
};
|
|
class Word: public ast_node {};
|
|
class MathInline: public Word {
|
std::string *expr;
|
public:
|
MathInline(std::string *e) {
|
expr = e;
|
}
|
~MathInline() {
|
delete expr;
|
}
|
std::string *get_expr() {
|
return expr;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_MathInline(this);
|
}
|
};
|
|
class Link: public Word {
|
std::string *link, *text;
|
public:
|
Link(std::string *l, std::string *t) {
|
link = l;
|
text = t;
|
}
|
~Link() {
|
delete link;
|
delete text;
|
}
|
std::string *get_link() {
|
return link;
|
}
|
std::string *get_text() {
|
return text;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Link(this);
|
}
|
};
|
|
class Format: public Word {};
|
|
class Text: public Format {
|
std::string t;
|
public:
|
Text(std::string tt) {
|
t=tt;
|
}
|
std::string *get_text() {
|
return &t;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Text(this);
|
}
|
};
|
|
class Format_Bold: public Format {
|
Format *f;
|
public:
|
Format_Bold(Format* ff) {
|
f=ff;
|
}
|
~Format_Bold() {
|
delete f;
|
}
|
Format *get_f() {
|
return f;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Format_Bold(this);
|
}
|
};
|
|
class Format_Italic: public Format {
|
Format *f;
|
public:
|
Format_Italic(Format* ff) {
|
f=ff;
|
}
|
~Format_Italic() {
|
delete f;
|
}
|
Format *get_f() {
|
return f;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Format_Italic(this);
|
}
|
};
|
|
class Format_Verbatim: public Format {
|
Format *f;
|
public:
|
Format_Verbatim(Format* ff) {
|
f=ff;
|
}
|
~Format_Verbatim() {
|
delete f;
|
}
|
Format *get_f() {
|
return f;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Format_Verbatim(this);
|
}
|
};
|
class Line: public ast_node {};
|
|
class Heading: public Line {
|
int level;
|
std::vector<Word*> words;
|
public:
|
Heading(int l, std::vector<Word*> w) {
|
level = l;
|
words = w;
|
}
|
~Heading() {
|
for (std::vector<Word*>::size_type i = 0; i < words.size(); i++) {
|
delete words[i];
|
}
|
words.clear();
|
}
|
int get_level() {
|
return level;
|
}
|
std::vector<Word*>* get_words() {
|
return &words;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Heading(this);
|
}
|
};
|
|
class List: public Line {
|
int level, number;
|
std::vector<Word*> words;
|
public:
|
List(int l, int n, std::vector<Word*> w) {
|
level = l;
|
number = n;
|
words = w;
|
}
|
~List() {
|
for (std::vector<Word*>::size_type i = 0; i < words.size(); i++) {
|
delete words[i];
|
}
|
words.clear();
|
}
|
int get_level() {
|
return level;
|
}
|
int get_number() {
|
return number;
|
}
|
std::vector<Word*>* get_words() {
|
return &words;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_List(this);
|
}
|
};
|
|
class MathDisp: public Line {
|
std::string *expr;
|
public:
|
MathDisp(std::string *e) {
|
expr = e;
|
}
|
~MathDisp() {
|
delete expr;
|
}
|
std::string *get_expr() {
|
return expr;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_MathDisp(this);
|
}
|
};
|
|
class Line_Word: public Line {
|
std::vector<Word*> words;
|
public:
|
~Line_Word() {
|
for (std::vector<Word*>::size_type i = 0; i < words.size(); i++) {
|
delete words[i];
|
}
|
words.clear();
|
}
|
int add_word(Word *w) {
|
words.push_back(w);
|
return 0;
|
}
|
std::vector<Word*> *get_words() {
|
return &words;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Line_Word(this);
|
}
|
};
|
|
class Block: public ast_node {};
|
|
class Block_Table: public Block {
|
std::vector<std::vector<Line_Word*>> table;
|
public:
|
~Block_Table() {
|
for (std::vector<std::vector<Line_Word*>>::size_type i = 0; i < table.size(); i++) {
|
for (std::vector<Line_Word*>::size_type j = 0; j < table[i].size(); j++) {
|
delete table[i][j];
|
}
|
table[i].clear();
|
}
|
table.clear();
|
}
|
std::vector<std::vector<Line_Word*>> get_table() {
|
return table;
|
}
|
int add_row(std::vector<Line_Word*> row) {
|
table.push_back(row);
|
return 0;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Block_Table(this);
|
}
|
};
|
|
class Block_Code: public Block {
|
std::string *c;
|
std::string *lang;
|
public:
|
Block_Code(std::string *l) {
|
lang = l;
|
c = new std::string();
|
}
|
~Block_Code() {
|
delete c;
|
delete lang;
|
}
|
int add_line(std::string *add) {
|
*c = *c + *add + "\n";
|
return 0;
|
}
|
std::string *get_lang() {
|
return lang;
|
}
|
std::string *get_code() {
|
return c;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Block_Code(this);
|
}
|
};
|
|
class Block_Line: public Block {
|
std::vector<Line*> lines;
|
public:
|
~Block_Line() {
|
for (std::vector<Line*>::size_type i = 0; i < lines.size(); i++) {
|
delete lines[i];
|
}
|
lines.clear();
|
}
|
std::vector<Line*> *get_lines() {
|
return &lines;
|
}
|
int add_line(Line* l) {
|
lines.push_back(l);
|
return 0;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Block_Line(this);
|
}
|
};
|
|
class Document: public ast_node {
|
std::string *title, *author, *date;
|
std::vector<Block*> blocks;
|
public:
|
Document(std::string *t, std::string *a, std::string *d) {
|
title = t;
|
author = a;
|
date = d;
|
}
|
~Document() {
|
for (std::vector<Block*>::size_type i = 0; i < blocks.size(); i++) {
|
delete blocks[i];
|
}
|
blocks.clear();
|
delete title;
|
delete author;
|
delete date;
|
}
|
std::string *get_title() {
|
return title;
|
}
|
std::string *get_author() {
|
return author;
|
}
|
std::string *get_date() {
|
return date;
|
}
|
std::vector<Block*> *get_blocks() {
|
return &blocks;
|
}
|
int add_block(Block *b) {
|
blocks.push_back(b);
|
return 0;
|
}
|
void* visit(ast_visitor *v) {
|
return v->visit_Document(this);
|
}
|
|
};
|
#endif
|