完成Parser定义以及表达式解析
This commit is contained in:
@@ -20,6 +20,29 @@ namespace Fig
|
||||
String filePath;
|
||||
String source;
|
||||
std::vector<String> lines;
|
||||
std::vector<size_t> lineStartIndex; // 每行在整个源字符串中的起始 index
|
||||
|
||||
void preprocessLineIndices()
|
||||
{
|
||||
lineStartIndex.clear();
|
||||
lineStartIndex.push_back(0);
|
||||
|
||||
for (size_t i = 0; i < source.length(); ++i)
|
||||
{
|
||||
if (source[i] == U'\n')
|
||||
{
|
||||
lineStartIndex.push_back(i + 1);
|
||||
}
|
||||
else if (source[i] == U'\r')
|
||||
{
|
||||
// 处理 CRLF,只在 \n 处记录
|
||||
if (i + 1 < source.length() && source[i + 1] == U'\n')
|
||||
continue;
|
||||
|
||||
lineStartIndex.push_back(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool read = false;
|
||||
@@ -37,7 +60,12 @@ namespace Fig
|
||||
source += line + '\n';
|
||||
lines.push_back(String(line));
|
||||
}
|
||||
if (lines.empty())
|
||||
{
|
||||
lines.push_back(String()); // 填充一个空的
|
||||
}
|
||||
read = true;
|
||||
preprocessLineIndices();
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -49,7 +77,7 @@ namespace Fig
|
||||
return _line <= lines.size() && _line >= 1;
|
||||
}
|
||||
|
||||
String GetLine(size_t _line) const
|
||||
const String &GetLine(size_t _line) const
|
||||
{
|
||||
assert(_line <= lines.size() && "SourceManager: GetLine failed, index out of range");
|
||||
return lines[_line - 1];
|
||||
@@ -64,5 +92,36 @@ namespace Fig
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
std::pair<size_t, size_t> GetLineColumn(size_t index) const
|
||||
{
|
||||
if (lineStartIndex.empty())
|
||||
{
|
||||
return {1, 1};
|
||||
}
|
||||
|
||||
// clamp index 到合法范围(Parser报错可能传入EOF位置)
|
||||
// size_t lastLine = lineStartIndex.size() - 1;
|
||||
if (index < lineStartIndex[0])
|
||||
{
|
||||
return {1, 1};
|
||||
}
|
||||
|
||||
// upper_bound 找到第一个 > index 的行起点
|
||||
auto it = std::ranges::upper_bound(lineStartIndex.begin(), lineStartIndex.end(), index);
|
||||
|
||||
size_t line;
|
||||
if (it == lineStartIndex.begin())
|
||||
{
|
||||
line = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = static_cast<size_t>(it - lineStartIndex.begin() - 1);
|
||||
}
|
||||
|
||||
size_t column = index - lineStartIndex[line] + 1;
|
||||
return {line + 1, column};
|
||||
}
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user