上次版本,遇到字符串错误语法会终止,或者在字符串中
有引号,也会不正确:
修改后:
/// <summary>
/// 记录C,C++关键字的位置,跳过注释和字符串文本。
/// </summary>
/// <returns></returns>
/// 创建时间: 2022-12-19 最后一次修改时间:2022-12-21 已测试
DList<TextColor> Syntax::GetTextColorPosForC_Keywords3() const
{
DList<TextColor> dtResult;
if (_code.length() <= 0) return dtResult;
const _char* p = _code.c_str();
_string sWord(_t(""), 50); //50个_char缓冲
Color_ cKeyWordColor = GetColor(SyntaxType::关键字);
for (int i = 0; i < _code.length(); ++i)
{
if (p[i] == _t('/'))
{
++i;
if (i < _code.length())
{
if (p[i] == _t('/')) //是"//"注释,查找注释结束位置 \n ,跳过注释
{
++i;
bool bFind = false; //查找下一个 "\n"
while (i < _code.length())
{
if (p[i] == '\n')
{
++i;
bFind = true;
break;
}
++i;
}
if (!bFind) return dtResult;
}
else if (p[i] == _t('*')) //是"/*"注释,查找注释结束位置 */ ,跳过注释
{
++i;
bool bFind = false;
while (i + 1 < _code.length()) //查找下一个 "*/"
{
if (p[i] == '*' && p[i + 1] == '/')
{
i += 2;
bFind = true;
break;
}
++i;
}
if (!bFind) return dtResult;
}
}
else
{
return dtResult;
}
}
else if (p[i] == _t('\"')) //字符开始
{
if (i - 1 > 0 && p[i - 1] != '\\')
{
++i;
bool bFind = false; //查找下一个 "\""
while (i < _code.length())
{
if (p[i] == '\"' && p[i - 1] != '\\')
{
++i;
bFind = true;
break;
}
else if (p[i] == '\n') //当前行已结束,还未找到引号配对
{
ErrorInfo ei;
ei.Text = _t("当前行已结束,还未找到引号配对?");
ei.Text += _t("错误行号为第:");
ei.LineNumber = _code.GetLineIndexForCharIndex(i - 1);
ei.Text += _tostr(ei.LineNumber + 1);
ei.Text += _t("行。");
//输出错误信息
PrintSyntaxCheckError(ei.Text);
Error.Add(ei);
++i;
bFind = true;
break;
}
++i;
}
if (!bFind) return dtResult;
}
else
{
++i;
}
}
if (gs.s_Syntax_IsWordSeparator(p[i]))
{
//关键字最小长度大于2,且全是小写字母
if (sWord.length() >= 2 && sWord.IsAllLowerCaseEnglishLetter())
{
if (C_Keyword.findNoteItem(sWord) != null) //是关键字,记录位置
{
dtResult.Add(TextColor(i - sWord.length(), sWord.length(), cKeyWordColor));
}
//log::d(_getc(sWord));
}
sWord.Clear(); //清空
}
else
{
sWord.add(p[i]);
}
}
return dtResult;
}
之前版本:
依据第二版本,可以写一个跳过注释的查找函数
C_IndexOfWord
Java_IndexOfWord
CSharp_IndexOfWord
还有一种方法,可以先把所有注释用空格代替,查出的字符位置也不变。
以前版本:
DList<TextColor> Syntax::GetTextColorPosForC_Keywords1() const
{
DList<TextColor> dtResult;
int nPos = -1;
if (_LanguageType == LanguageType::C)//-----------------------------------C&C++ Begin
{
//-----------------------------------------------------------------关键字
for (_string s : C_Keyword)
{
nPos = _code.IndexOfWord(s);
while (nPos != -1)
{
dtResult.Add(TextColor(nPos, s.length(), GetColor(SyntaxType::关键字)));
nPos = _nh_en.IndexOfWord(s, nPos + s.length());
}
}
}
return dtResult;
}
修改版本:
/// <summary>
/// 记录C,C++关键字的位置,跳过注释和字符串文本。
/// </summary>
/// <returns></returns>
/// 创建时间: 2022-12-19 最后一次修改时间:2022-12-19
DList<TextColor> Syntax::GetTextColorPosForC_Keywords2() const
{
DList<TextColor> dtResult;
if (_code.length() <= 0) return dtResult;
const _char *p = _code.c_str();
_string sWord(_t(""), 50); //50个_char缓冲
Color_ cKeyWordColor = GetColor(SyntaxType::关键字);
for(int i = 0; i < _code.length(); ++ i)
{
if ( p[i] == _t('/'))
{
if (i + 1 < _code.length())
{
if (p[i + 1] == _t('/') ) //是"//"注释,查找注释结束位置 \n ,跳过注释
{
i += 2;
while (p[i] != 0 && p[i] != '\n')
{
++i;
}
}
else if (p[i + 1] == _t('*')) //是"/*"注释,查找注释结束位置 */ ,跳过注释
{
i += 2;
while (p[i] != 0 && p[i] != _t('*'))
{
if (p[i + 1] != 0 && p[i + 1] != '/') //结束位置
{
++i;
}
else
{
++i;
break;
}
}
}
}
else
{
return dtResult;
}
}
else if (p[i] == _t('\"')) //字符开始
{
++i;
while(p[i] != 0 && p[i] != '\"')
{
++i;
}
}
if (gs.s_Syntax_IsWordSeparator(p[i]))
{
//关键字最小长度大于2,且全是小写字母
if (sWord.length() >= 2 && sWord.IsAllLowerCaseEnglishLetter())
{
if (C_Keyword.findNoteItem(sWord) != null) //是关键字,记录位置
{
dtResult.Add(TextColor(i - sWord.length(), sWord.length(), cKeyWordColor));
}
//log::d(_getc(sWord));
}
sWord.Clear(); //清空
}
else
{
sWord.add(p[i]);
}
}
return dtResult;
}
/// <summary>
/// 记录C,C++关键字的位置,跳过注释和字符串文本。
/// </summary>
/// <returns></returns>
/// 创建时间: 2022-12-19 最后一次修改时间:2022-12-19
DList<TextColor> Syntax::GetTextColorPosForC_Keywords2() const
{
DList<TextColor> dtResult;
if (_code.length() <= 0) return dtResult;
const _char *p = _code.c_str();
_string sWord(_t(""), 50); //50个_char缓冲
Color_ cKeyWordColor = GetColor(SyntaxType::关键字);
for(int i = 0; i < _code.length(); ++ i)
{
if ( p[i] == _t('/'))
{
if (i + 1 < _code.length())
{
if (p[i + 1] == _t('/') ) //是"//"注释,查找注释结束位置 \n ,跳过注释
{
i += 2;
while (p[i] != 0 && p[i] != '\n')
{
++i;
}
}
else if (p[i + 1] == _t('*')) //是"/*"注释,查找注释结束位置 */ ,跳过注释
{
i += 2;
while (p[i] != 0 && p[i] != _t('*'))
{
if (p[i + 1] != 0 && p[i + 1] != '/') //结束位置
{
++i;
}
else
{
++i;
break;
}
}
}
}
else
{
return dtResult;
}
}
else if (p[i] == _t('\"')) //字符开始
{
++i;
while(p[i] != 0 && p[i] != '\"')
{
++i;
}
}
if (gs.s_Syntax_IsWordSeparator(p[i]))
{
//关键字最小长度大于2,且全是小写字母
if (sWord.length() >= 2 && sWord.IsAllLowerCaseEnglishLetter())
{
if (C_Keyword.findNoteItem(sWord) != null) //是关键字,记录位置
{
dtResult.Add(TextColor(i - sWord.length(), sWord.length(), cKeyWordColor));
}
//log::d(_getc(sWord));
}
sWord.Clear(); //清空
}
else
{
sWord.add(p[i]);
}
}
return dtResult;
}
其中:
/// <summary>
/// 判断字符是否单词的有效分隔符
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
inline static bool s_Syntax_IsWordSeparator(_char c) {
return (gs.c_IsPunctuation(c) || gs.c_IsControl(c) || Math_::strchr(IdentifierSpecial, c) != -1) && c != _t('_');
}
const _char* global_c_str::IdentifierSpecial = _t("~!@#$%^&*()+-/.{}[]|\\ `=");
虽然结果正确,但不严谨,以下修正:
/// <summary>
/// 记录C,C++关键字的位置,跳过注释和字符串文本。
/// </summary>
/// <returns></returns>
/// 创建时间: 2022-12-19 最后一次修改时间:2022-12-21 已测试
DList<TextColor> Syntax::GetTextColorPosForC_Keywords2() const
{
DList<TextColor> dtResult;
if (_code.length() <= 0) return dtResult;
const _char *p = _code.c_str();
_string sWord(_t(""), 50); //50个_char缓冲
Color_ cKeyWordColor = GetColor(SyntaxType::关键字);
for(int i = 0; i < _code.length(); ++ i)
{
if ( p[i] == _t('/'))
{
++i;
if (i < _code.length())
{
if (p[i] == _t('/') ) //是"//"注释,查找注释结束位置 \n ,跳过注释
{
++i;
bool bFind = false; //查找下一个 "\n"
while (i < _code.length())
{
if (p[i] == '\n')
{
++i;
bFind = true;
break;
}
++i;
}
if (!bFind) return dtResult;
}
else if (p[i] == _t('*')) //是"/*"注释,查找注释结束位置 */ ,跳过注释
{
++i;
bool bFind = false;
while (i + 1 < _code.length()) //查找下一个 "*/"
{
if (p[i] == '*' && p[i + 1] == '/')
{
i += 2;
bFind = true;
break;
}
++i;
}
if (!bFind) return dtResult;
}
}
else
{
return dtResult;
}
}
else if (p[i] == _t('\"')) //字符开始
{
++i;
bool bFind = false; //查找下一个 "\""
while (i + 1 < _code.length())
{
if (p[i] == '\"')
{
i += 2;
bFind = true;
break;
}
++i;
}
if (!bFind) return dtResult;
}
if (gs.s_Syntax_IsWordSeparator(p[i]))
{
//关键字最小长度大于2,且全是小写字母
if (sWord.length() >= 2 && sWord.IsAllLowerCaseEnglishLetter())
{
if (C_Keyword.findNoteItem(sWord) != null) //是关键字,记录位置
{
dtResult.Add(TextColor(i - sWord.length(), sWord.length(), cKeyWordColor));
}
//log::d(_getc(sWord));
}
sWord.Clear(); //清空
}
else
{
sWord.add(p[i]);
}
}
return dtResult;
}
另加上查找函数:
/// <summary>
/// 跳过注释和字符串值查找字符,这里假设注释和字符串书写模式正确,而且你
/// 不要去查找一个双引号( '\"') ,永远都返回-1。
/// </summary>
/// <param name="c"></param>
/// <param name="iFindStart"></param>
/// <param name="bMatchCase"></param>
/// <returns></returns>
/// 创建时间: 2021-12-21 最后一次修改时间:2022-12-21 已测试
int Syntax_C_IndexOf(const _char c, const int iFindStart = 0)const
{
int iStart = iFindStart <= 0 ? 0 : iFindStart;
if (c == 0 || _nLength <= 0 || iStart >= _nLength) return -1;
const _char* p = _pData;
for (int i = iStart; i < _nLength; ++i)
{
if (p[i] == _t('/'))
{
++i;
if (i < _nLength)
{
if (p[i] == _t('/')) //是"//"注释,查找注释结束位置 \n ,跳过注释
{
++i;
bool bFind = false;
while ( i < _nLength)
{
if (p[i] == '\n') //查找下一个 "\n"
{
bFind = true;
++i;
break;
}
++i;
}
if (!bFind) return -1;
}
else if (p[i] == _t('*')) //是"/*"注释,查找注释结束位置 */ ,跳过注释
{
++i;
bool bFind = false;
while (i + 1 < _nLength) //查找下一个 "*/"
{
if (p[i] == '*' && p[i + 1] == '/')
{
i += 2;
bFind = true;
break;
}
++i;
}
if (!bFind) return -1;
}
else
{
if (p[i] == c) { return i; }
}
}
else
{
return -1;
}
}
else if (p[i] == _t('\"')) //字符开始
{
++i;
bool bFind = false;
while (i < _nLength) //查找下一个 "\""
{
if (p[i] == '\"')
{
bFind = true;
++i;
break;
}
++i;
}
if (!bFind) return -1;
}
else
{
if (p[i] == c) { return i; }
}
}
return -1;
}