-
Notifications
You must be signed in to change notification settings - Fork 0
/
uParser.h
155 lines (126 loc) · 6.29 KB
/
uParser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//---------------------------------------------------------------------------
#ifndef uParserH
#define uParserH
#include "uFormat.h"
#include <vcl.h>
#include <list>
#include "uLanguageDefinition.h"
#include <windows.h>
#include <queue>
#include "config.h"
namespace SHEdit
{
class NSpan;
class TSHEdit;
class Drawer;
class Mark;
class Format;
class FontStyle;
class Iter;
class DrawTaskText;
/*!
* Parser
* ======
* Parser's task is to parse lines and keep information about highlighting that is neccessary for correct highlighting. Perser keeps a ParserState at each endline, which specifies in which state parser was at that point. Each time buffer is altered, the component is supposed to call Parser::ParseFromLine function, to tell the Parser to reparse text from given line. Parser then parses code and updates ParserStates of lines it goes over until it reaches a ParserState that is same as the Parser's own. Parser does not parse text right away, but pushes the items into 2 queues (normal queue and priority queue (the latter for lines that are supposed to be reparsed first - as visible lines, which are supposed to be redrawn as soon as possible)). Parsing is done when Parser::Execute method is called.
*
* Parser::Execute() first sorts both queues, and then picks tke tasks one by one (first from priority queue). Each time it picks new task, it checkes it's screen position to know whether to paint line or just parse. In the former case it also initializes formats (reconstructs it from markupStack and searches through Iterator handled markup. Then it copies the line's parser State into it's own, and calls Parser::ParseLine, and continues to do so until some conditions are met. On Each line, the queues are checked and corresponding tasks removed. If priority queue is not empty, and parser has gone out of visible area of screen, then current line is pushed onto non-priority queue, and next task from priority queue is picked. When all priority tasks are reparsed, Parser calls Paint, to actually refresh all what has been painted. If non-priority queue is non empty, parser places itself into Application's OnIdle event handler and parsing of non-priority queue continues later. Such parsing is broken each PARSEINONEGO (currently 100) lines, to allow Application to get from "Idle event loop". Non-priority queue is parsed until all tasks under a specified Parser::upperbound are parsed. Upperbound is now set to be component's line Iter + 1000 lines. Reason is mainly so that inserting of " followed by another " few seconds later does not throttle CPU on chasing the already reparsed results of such edits.
*
* Parser::ParseLine() parses line char by char using its LanguageDefinition. Each char is given to the LanguageDefinition with current lexer position, and is returned new lexer position altogether with state. Upon the state depends what is done next - usually current char is pushed into String Parser::actText, where it waits until some "matched" state is returned, when it is drawn. ParseLine() also checks changes in markup.
* */
class Parser
{
private:
/*struct Node
{
Node(Format * format, Node * node);
Format * format;
Node * node;
};*/
public:
struct ParserState
{
ParserState();
~ParserState();
void InitBanks(int count);
bool operator==(const ParserState& state);
bool operator!=(const ParserState& state);
ParserState& operator=(const ParserState& p);
short parseid;
Stack<LanguageDefinition::SearchIter> searchStateStack;
Stack<Format*> markupStack;
short globalMask;
};
/*!
* ParseTask represents a task for Parser. It is passed from TSHEdit to the Parser whenever component wants anything to be reparsed or repainted
* */
struct ParseTask
{
ParseTask(NSpan * line, int linenum);
ParseTask();
NSpan * line;
int linenum;
bool operator==(const ParseTask & pt)const;
bool operator<(const ParseTask & pt)const;
};
private:
ParserState state;
LanguageDefinition * langdef;
TSHEdit * parent;
Drawer * drawer;
bool newline;
short linenum;
short currentparseid;
int dbgscb;
bool onidleset;
bool inword;
TIdleEvent oldidle;
int upperbound;
/*
String * outString;
String * actString;
TColor * actColor;
TColor * outColor;
bool outMarked;
bool actMarked; */
String actText;
FontStyle actFormat;
FontStyle actMarkupCombined;
FontStyle actMarkup;
FontStyle actIMarkup;
int recurse;
void ReconstructMarkup(); /*!< Reconstructs ActMarkup (that holds positionless markup). Does not update actMarkupCombined. */
void Flush();
void FlushAll();
void SendEof();
void AddChar(Iter * itr, int & pos);
//void PerformPush(LanguageDefinition::SearchIter *& sit);
void PerformJumpPush(LanguageDefinition::SearchIter *& sit);
bool PerformPop(LanguageDefinition::SearchIter *& sit);
inline void CheckMarkup(Iter * itr, bool paint);
bool CanGoFurther(LanguageDefinition::SearchIter sit, Iter * itr, bool inword, bool checkbefore = false, bool recursive = false);
std::list<ParseTask> tasklistprior;
std::list<ParseTask> tasklist;
void ParseLine(Iter * itr, LanguageDefinition::SearchIter * searchiter, bool paint);
void __fastcall Draw();
#ifdef SHEDIT_DEBUG
void Write(AnsiString message);
void DumpStackState();
#endif
public:
#ifdef SHEDIT_DEBUG
bool dbgLogging;
#endif
friend class TSHEdit;
void __fastcall OnIdle(TObject * Sender, bool& Done);
bool __fastcall Execute(bool paint = true);
void InvalidateAll();
__fastcall Parser(TSHEdit * parent, Drawer * drawer);
virtual __fastcall ~Parser();
void SetLangDef(LanguageDefinition * langdef);
LanguageDefinition* GetLangDef();
void ParseFromLine(NSpan * line, int linenum, int prior);
void ParseFromToLine(NSpan * line, int linenum, int count, int prior);
};
}
//---------------------------------------------------------------------------
#endif