HAL  v4.5.0-254-g8f9f6a423
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
python_syntax_highlighter.cpp
Go to the documentation of this file.
2 
4 namespace hal
5 {
6  PythonSyntaxHighlighter::PythonSyntaxHighlighter(QTextDocument* parent) : QSyntaxHighlighter(parent), mTrippleSingleQuote("'''"), mTrippleDoubleQuote("\"\"\"")
7  // //mKeywordColor(177, 240, 0),
8  // //mKeywordColor("#ffd200"),
9  // mKeywordColor("#CC7832"),
10  // //mKeywordColor("#6419E6"),
11  // //mKeywordColor("#9019E6"),
12  // //mOperatorColor("#0A81FF"),
13  // mOperatorColor("#A9B7C6"), mBraceColor("#A9B7C6"), mDefclassColor("#A9B7C6"),
14  // //mSingleQuotedStringColor("#17de4c"),
15  // //mDoubleQuotedStringColor("#17de4c"),
16  // mSingleQuotedStringColor("#A5C25C"), mDoubleQuotedStringColor("#A5C25C"),
17  // mSelfColor("#A9B7C6"),
18  // //mNumberColor(236, 118, 0),
19  // //mNumberColor("#DB8000"),
20  // //mNumberColor("#89F406"),
21  // //mNumberColor("#F4EC06"),
22  // mNumberColor("#6897BB"),
23  // //mCommentColor("#6F7B7B")
24  // //mCommentColor(222, 233, 175)
25  // //mCommentColor("#556062")
26  // //mCommentColor("#30474B") //2.0
27  // //mCommentColor("#3A565A") //2.5
28  // mCommentColor("#629755") //2.98
29  {
30  HighlightingRule rule;
31 
32  rule.mPattern = QRegularExpression("\\b(and|as|assert|break|class|continue|def|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|"
33  "nonlocal|not|or|pass|raise|return|try|while|with|yield|False|None|True)\\b");
34  rule.mPattern.optimize();
35  rule.mFormat = PythonQssAdapter::instance()->mKeywordFormat;
36  mHighlightingRules.append(rule);
37 
38  rule.mPattern = QRegularExpression("=|==|!=|<|<=|>|>=|\\+|-|\\*|/|//|%|\\*\\*|\\+=|-=|\\*=|/=|%=|\\^|\\||&|~|>>|<<");
39  rule.mPattern.optimize();
40  rule.mFormat = PythonQssAdapter::instance()->mOperatorFormat;
41  mHighlightingRules.append(rule);
42 
43  rule.mPattern = QRegularExpression("{|}|\\(|\\)|\\[|]");
44  rule.mPattern.optimize();
45  rule.mFormat = PythonQssAdapter::instance()->mBraceFormat;
46  mHighlightingRules.append(rule);
47 
48  rule.mPattern = QRegularExpression(R"('(?:[^'\\]|\\.)*')");
49  rule.mPattern.optimize();
50  rule.mFormat = PythonQssAdapter::instance()->mSingleQuotedStringFormat;
51  mHighlightingRules.append(rule);
52 
53  rule.mPattern = QRegularExpression(R"("(?:[^"\\]|\\.)*")");
54  rule.mPattern.optimize();
55  rule.mFormat = PythonQssAdapter::instance()->mDoubleQuotedStringFormat;
56  mHighlightingRules.append(rule);
57 
58  rule.mPattern = QRegularExpression("\\bself\\b");
59  rule.mPattern.optimize();
60  rule.mFormat = PythonQssAdapter::instance()->mSelfFormat;
61  mHighlightingRules.append(rule);
62 
63  rule.mPattern = QRegularExpression("(\\b([1-9][0-9]*|0)[.]?[0-9]*[eE][+-]?[0-9]+[jJ]?\\b)|"// Exponent float
64  "(\\b([1-9][0-9]*|0)\\.[0-9]*[jJ]?)|" // Point float
65  "(\\b0[xX][0-9A-Fa-f]+[lL]?\\b)|" // Hexadecimal integer
66  "(\\b0[oO][0-7]+[lL]?\\b)|" // Octal integer
67  "(\\b([1-9][0-9]*|0)[lLjJ]?\\b)"); // Decimal integer
68 
69  rule.mPattern.optimize();
70  rule.mFormat = PythonQssAdapter::instance()->mNumberFormat;
71  mHighlightingRules.append(rule);
72 
73  // a '#' starts a comment, and a ''' or """ a multi-line string, only outside of string literals
74  //
75  // \G anchor the match at the offset it is given
76  // (?: ... )* consume everything that cannot start a comment or a multi-line string:
77  // [^"'#\\] an ordinary character
78  // \\. an escape, so \" does not end a string
79  // """...""" a complete triple quoted string, likewise '''...'''
80  // "..." a complete double quoted string, unless the quote opens a """
81  // '...' a complete single quoted string, unless the quote opens a '''
82  // \K drop all of that from the reported match
83  //
84  // print("#") # here
85  // |________| |
86  // consumed reported as the match
87  //
88  // an unterminated quote never gets past the loop, so a '#' inside an
89  // unclosed string or after an opening """ is left alone
90  const QString skip_strings = R"(\G(?:[^"'#\\]|\\.|"""(?:[^"\\]|\\.|"(?!""))*"""|'''(?:[^'\\]|\\.|'(?!''))*'''|"(?!"")(?:[^"\\]|\\.)*"|'(?!'')(?:[^'\\]|\\.)*')*\K)";
91  mSingleLineComment = QRegularExpression(skip_strings + "#.*");
92  mSingleLineComment.optimize();
93  mMultiLineCommentDelimiter = QRegularExpression(skip_strings + R"(('''|"""))");
94  mMultiLineCommentDelimiter.optimize();
95  }
96 
97  void PythonSyntaxHighlighter::highlightBlock(const QString& text)
98  {
99  for (const HighlightingRule& rule : mHighlightingRules)
100  {
101  QRegularExpressionMatchIterator it = rule.mPattern.globalMatch(text);
102  while (it.hasNext())
103  {
104  QRegularExpressionMatch match = it.next();
105  int index = match.capturedStart();
106  int length = match.capturedLength();
107  setFormat(index, length, rule.mFormat);
108  }
109  }
110 
111  // 0 no open comment in block
112  // 1 contains tripple single quote start and no tripple single quote end OR follows a "1" block and also doesnt contain the end
113  // 2 contains tripple double quote start and no tripple double quote end OR follows a "2" block and also doesnt contain the end
114 
115  int current_index = 0;
116 
117  if (previousBlockState() == 1)
118  {
119  current_index = closeMultilineComment(text, mTrippleSingleQuote);
120 
121  if (current_index < 0)
122  {
123  setCurrentBlockState(1);
124  return;
125  }
126  }
127 
128  if (previousBlockState() == 2)
129  {
130  current_index = closeMultilineComment(text, mTrippleDoubleQuote);
131 
132  if (current_index < 0)
133  {
134  setCurrentBlockState(2);
135  return;
136  }
137  }
138 
139  int comment_index = mSingleLineComment.match(text, current_index).capturedStart();
140  if (comment_index >= 0)
141  setFormat(comment_index, text.length() - comment_index, PythonQssAdapter::instance()->mCommentFormat);
142 
143  QRegularExpressionMatch match = mMultiLineCommentDelimiter.match(text, current_index);
144 
145  while (match.hasMatch() && (comment_index < 0 || match.capturedStart() < comment_index))
146  {
147  // check which delimiter was found
148  // check for closing delimiter
149  // found -> loop again
150  // not found -> set block state and return
151 
152  int comment_start_index = match.capturedStart();
153  QChar comment_type = text.at(comment_start_index);
154 
155  if (comment_type == '\'')
156  {
157  QRegularExpressionMatch single_match = mTrippleSingleQuote.match(text, comment_start_index + 3);
158  int single_match_index = single_match.capturedStart();
159 
160  if (single_match_index < 0)
161  {
162  setCurrentBlockState(1);
163  setFormat(comment_start_index, text.length() - comment_start_index, PythonQssAdapter::instance()->mCommentFormat);
164  return;
165  }
166  else
167  {
168  setFormat(comment_start_index, comment_start_index - single_match_index + 3, PythonQssAdapter::instance()->mCommentFormat);
169  match = mMultiLineCommentDelimiter.match(text, single_match_index + 3);
170  }
171  }
172  else
173  {
174  QRegularExpressionMatch double_match = mTrippleDoubleQuote.match(text, comment_start_index + 3);
175  int double_match_index = double_match.capturedStart();
176 
177  if (double_match_index < 0)
178  {
179  setCurrentBlockState(2);
180  setFormat(comment_start_index, text.length() - comment_start_index, PythonQssAdapter::instance()->mCommentFormat);
181  return;
182  }
183  else
184  {
185  setFormat(comment_start_index, comment_start_index - double_match_index + 3, PythonQssAdapter::instance()->mCommentFormat);
186  match = mMultiLineCommentDelimiter.match(text, double_match_index + 3);
187  }
188  }
189  }
190  setCurrentBlockState(0);
191  return;
192  }
193 
194  int PythonSyntaxHighlighter::closeMultilineComment(const QString& text, const QRegularExpression& delimiter, const int offset)
195  {
196  QRegularExpressionMatch match = delimiter.match(text, offset);
197  int index = match.capturedEnd();
198 
199  if (index < 0)
200  setFormat(offset, text.length() - offset, PythonQssAdapter::instance()->mCommentFormat);
201  else
202  setFormat(offset, index - offset, PythonQssAdapter::instance()->mCommentFormat);
203 
204  return index;
205  }
206 }
PythonSyntaxHighlighter(QTextDocument *parent=nullptr)
Definition: defines.h:45
std::unique_ptr< BasePluginInterface > instance
QRegularExpressionMatch match(const QString &subject, int offset, QRegularExpression::MatchType matchType, QRegularExpression::MatchOptions matchOptions) const const
int capturedEnd(int nth) const const
int capturedLength(int nth) const const
int capturedStart(int nth) const const
bool hasMatch() const const
QRegularExpressionMatch next()
const QChar at(int position) const const
int length() const const