#ifndef AST_H #define AST_H #include #include 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 words; public: Heading(int l, std::vector w) { level = l; words = w; } ~Heading() { for (std::vector::size_type i = 0; i < words.size(); i++) { delete words[i]; } words.clear(); } int get_level() { return level; } std::vector* get_words() { return &words; } void* visit(ast_visitor *v) { return v->visit_Heading(this); } }; class List: public Line { int level, number; std::vector words; public: List(int l, int n, std::vector w) { level = l; number = n; words = w; } ~List() { for (std::vector::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* 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 words; public: ~Line_Word() { for (std::vector::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 *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> table; public: ~Block_Table() { for (std::vector>::size_type i = 0; i < table.size(); i++) { for (std::vector::size_type j = 0; j < table[i].size(); j++) { delete table[i][j]; } table[i].clear(); } table.clear(); } std::vector> get_table() { return table; } int add_row(std::vector 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 lines; public: ~Block_Line() { for (std::vector::size_type i = 0; i < lines.size(); i++) { delete lines[i]; } lines.clear(); } std::vector *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 blocks; public: Document(std::string *t, std::string *a, std::string *d) { title = t; author = a; date = d; } ~Document() { for (std::vector::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 *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