///|
// pub enum LexerOptions {
// N3LexerOptions(N3LexerOptions)
// TriGLexerOptions(TriGLexerOptions)
// // mut base_iri : Iri?
// } derive(Debug)
// struct LexerOptions(N3LexerOptions)
///|
pub(all) struct LexerOptions {
mut base_iri : Iri?
} derive(Debug)
///|
fn LexerOptions::default(base_iri : Iri?) -> LexerOptions {
{ base_iri, }
}
///|
pub(all) struct Lexer[RL] {
parser : RL
data : Array[Byte]
position : Position
mut previous_position : Position
mut is_ending : Bool
min_buffer_size : Int
max_buffer_size : Int
line_comment_start : Bytes?
mut current_token_start : Int
mut current_token_end : Int
}
///|
pub(all) struct Position {
mut line_start_buffer_offset : Int
mut buffer_offset : Int
mut global_offset : Int
mut global_line : Int
} derive(Debug, Default)
///|
pub struct SourcePos {
line : Int
column : Int
offset : Int
} derive(Debug)
///|
fn SourcePos::default() -> SourcePos {
SourcePos(0, 0, 0)
}
///|
fn SourcePos::SourcePos(line : Int, column : Int, offset : Int) -> SourcePos {
{ line, column, offset }
}
///|
pub fn SourcePos::end_position(self : Self, consumed_bytes : Int) -> SourcePos {
// 注意:这里简化处理,假设消耗的都是单字节 ASCII 或者你希望在字节层面计算 offset
// 如果需要精确的 UTF-8 列号计算,需要扫描 data[start..start+consumed]
SourcePos::SourcePos(
self.line,
self.column + consumed_bytes, // 简化列计算,实际可能需要 utf8 解析
self.offset + consumed_bytes,
)
}
///|
pub fn SourcePos::start_position(self : Self) -> SourcePos {
SourcePos::SourcePos(self.line, self.column, self.offset)
}
///|
impl Show for SourcePos with fn output(self, logger : &Logger) -> Unit {
logger.write_string("[")
logger.write_string(self.line.to_string())
logger.write_string(":")
logger.write_string(self.column.to_string())
logger.write_string(":")
logger.write_string(self.offset.to_string())
logger.write_string("]")
}
///|
pub fn[RL] Lexer::Lexer(
parser : RL,
data : Array[Byte],
is_ending : Bool,
min_buffer_size : Int,
max_buffer_size : Int,
line_comment_start : Bytes?,
current_token_start : Int,
current_token_end : Int,
) -> Lexer[RL] {
{
parser,
data,
position: Position::default(),
previous_position: Position::default(),
is_ending,
min_buffer_size,
max_buffer_size,
line_comment_start,
current_token_start,
current_token_end,
}
}
///|
pub fn[RL] Lexer::extend_from_slice(self : Lexer[RL], other : Bytes) -> Unit {
self.shrink_data()
self.data.append(BytesView::to_array(other))
}
///|
pub fn[RL] Lexer::end(self : Lexer[RL]) -> Unit {
self.is_ending = true
}
///|
pub async fn[RL] Lexer::extend_from_reader(
self : Lexer[RL],
reader : &Reader,
) -> Result[Int, LexerError] {
self.shrink_data()
// 1. 检查容量限制
if self.data.length() >= self.max_buffer_size {
return Err(
LexerError::OutOfMemory(
"Reached the buffer maximal size of \{self.max_buffer_size}",
),
)
}
// 2. 计算本次期望读取的大小
let remaining_space = self.max_buffer_size - self.data.length()
let want_read = Int::min(self.min_buffer_size, remaining_space)
if want_read <= 0 {
return Ok(0)
}
let old_len = self.data.length()
// 3. 预分配空间:将数组长度增加 want_read,新位置初始化为 0
self.data.resize(old_len + want_read, 0)
// 4. 获取指向新分配空间的可变视图 (MutArrayView)
let buf : FixedArray[Byte] = FixedArray::make(want_read, 0)
// 5. 执行读取
let read = reader.read(buf)
// 6. 【核心修复】将 buf 中的数据拷贝到 self.data 的末尾
// 使用 unsafe_blit 或者循环拷贝。这里使用安全的循环拷贝以确保兼容性。
// 如果性能敏感,且 Moonbit 版本支持 Array::unsafe_blit_fixed,可以使用它。
let mut i = 0
while i < read {
// 将 buf[i] 设置到 self.data[old_len + i]
self.data.set(old_len + i, buf.at(i))
i = i + 1
}
// 7. 截断多余预分配的空间(如果 read < want_read)
self.data.truncate(old_len + read)
// 8. 更新结束标志
self.is_ending = read == 0
Ok(read)
}
///|
pub async fn[RL] Lexer::extend_from_async_read(
self : Lexer[RL],
reader : &Reader,
) -> Result[Int, LexerError] {
self.shrink_data()
if self.data.length() >= self.max_buffer_size {
return Err(
LexerError::OutOfMemory(
"Reached the buffer maximal size of \{self.max_buffer_size}",
),
)
}
let remaining_space = self.max_buffer_size - self.data.length()
let want_read = Int::min(self.min_buffer_size, remaining_space)
if want_read <= 0 {
return Ok(0)
}
let old_len = self.data.length()
self.data.resize(old_len + want_read, 0)
let buf : FixedArray[Byte] = FixedArray::make(want_read, 0)
// 假设 reader.read 是异步方法
let read = reader.read(buf)
let mut i = 0
while i < read {
self.data.set(old_len + i, buf.at(i))
i = i + 1
}
self.data.truncate(old_len + read)
self.is_ending = read == 0
Ok(read)
}
///|
pub fn[RL] Lexer::shrink_data(self : Lexer[RL]) -> Unit {
// 策略1: 如果行起始偏移量大于0,说明前面有完整的行可以丢弃
if self.position.line_start_buffer_offset > 0 {
self.shrink_data_by(self.position.line_start_buffer_offset)
// 策略2: 如果缓冲区使用超过一半,尝试收缩已处理的部分
// 原代码使用 position.buffer_offset,意味着丢弃所有已消耗的字符
} else if self.position.buffer_offset > self.max_buffer_size / 2 {
self.shrink_data_by(self.position.buffer_offset)
}
}
///|
fn[RL] Lexer::shrink_data_by(self : Lexer[RL], shift_amount : Int) -> Unit {
if shift_amount <= 0 {
return
}
let current_len = self.data.length()
// 安全检查:确保不移动超出数组范围的数据
if shift_amount > current_len {
// 理论上不应发生,除非逻辑有误
return
}
let new_len = current_len - shift_amount
let _ = ArrayView::blit_to(self.data, self.data, dst_offset=shift_amount)
// 2. 截断数组
self.data.truncate(new_len)
// 3. 更新相对偏移量 (Buffer Offsets)
// 这些是数组索引,必须减去移走的字节数
self.position.buffer_offset -= shift_amount
self.position.line_start_buffer_offset -= shift_amount
// 确保 line_start_buffer_offset 不为负(虽然逻辑上 shift_amount <= line_start_buffer_offset 时才调用,或者针对 buffer_offset)
if self.position.line_start_buffer_offset < 0 {
self.position.line_start_buffer_offset = 0
}
if self.position.buffer_offset < 0 {
self.position.buffer_offset = 0
}
self.previous_position.buffer_offset -= shift_amount
self.previous_position.line_start_buffer_offset -= shift_amount
if self.previous_position.line_start_buffer_offset < 0 {
self.previous_position.line_start_buffer_offset = 0
}
if self.previous_position.buffer_offset < 0 {
self.previous_position.buffer_offset = 0
}
// previous_position 的 global_offset 和 global_line 也不需要变,因为它们代表历史绝对位置
}
///|
pub fn[RL] Lexer::location_from_buffer_offset_range(
self : Lexer[RL],
offset_range : Range,
) -> SourceRange {
let start_offset = self.previous_position.buffer_offset + offset_range.start
let view = self.data[self.previous_position.buffer_offset:self.previous_position.buffer_offset +
start_offset]
let (start_extra_line_jumps, start_line_start) = Lexer::find_number_of_line_jumps_and_start_of_last_line(
view,
)
let start_line_start = if start_extra_line_jumps > 0 {
start_line_start + self.previous_position.buffer_offset
} else {
self.previous_position.line_start_buffer_offset
}
let end_offset = self.previous_position.buffer_offset + offset_range.end
let view = self.data[self.previous_position.buffer_offset:self.previous_position.buffer_offset +
end_offset]
let (end_extra_line_jumps, end_line_start) = Lexer::find_number_of_line_jumps_and_start_of_last_line(
view,
)
let end_line_start = if end_extra_line_jumps > 0 {
end_line_start + self.previous_position.buffer_offset
} else {
self.previous_position.line_start_buffer_offset
}
SourceRange::SourceRange(
SourcePos::SourcePos(
self.previous_position.global_line + start_extra_line_jumps,
Lexer::column_from_bytes(self.data[start_line_start:start_offset]),
self.previous_position.global_offset + offset_range.start,
),
SourcePos::SourcePos(
self.previous_position.global_line + end_extra_line_jumps,
Lexer::column_from_bytes(self.data[end_line_start:end_offset]),
self.previous_position.global_offset + offset_range.end,
),
)
}
///|
pub fn[RL] Lexer::current_token_start_location(self : Lexer[RL]) -> SourcePos {
self.position_from_position(self.previous_position)
}
///|
/// 获取当前 Token 的**结束**位置 (即 Lexer 指针当前位置)
pub fn[RL] Lexer::current_token_end_location(self : Lexer[RL]) -> SourcePos {
self.position_from_position(self.position)
}
///|
/// 获取当前 Token 的完整范围
pub fn[RL] Lexer::current_token_source_range(self : Lexer[RL]) -> SourceRange {
SourceRange::SourceRange(
self.current_token_start_location(),
self.current_token_end_location(),
)
}
///|
fn[RL] Lexer::position_from_position(
self : Lexer[RL],
position : Position,
) -> SourcePos {
let view = self.data[position.line_start_buffer_offset:position.buffer_offset]
{
line: position.global_line,
column: Lexer::column_from_bytes(view),
offset: position.global_offset,
}
}
///|
pub fn[RL] Lexer::last_token_source(self : Lexer[RL]) -> String {
let arr_view = self.data[self.previous_position.buffer_offset:self.position.buffer_offset]
let bytes : Bytes = Bytes::from_array(arr_view) // 假设有此 API,或者 Bytes::of_array_view
@utf8.decode_lossy(bytes)
}
///|
pub fn[RL] Lexer::is_end(self : Lexer[RL]) -> Bool {
self.is_ending && self.data.length() == self.position.buffer_offset
}
///|
fn[RL] Lexer::skip_whitespaces(self : Lexer[RL]) -> Bool? {
let data = self.data
let mut pos = self.position.buffer_offset
let len = data.length()
while pos < len {
match data[pos] {
b' ' | b'\t' => pos += 1
b'\r' => {
// 处理 CR 或 CRLF
let mut incr = 1
if pos + 1 < len {
if data[pos + 1] == b'\n' {
incr = 2
}
} else if !self.is_ending {
// 如果后面可能还有数据,需要等待
return None
}
self.position.buffer_offset = pos + incr
self.position.line_start_buffer_offset = self.position.buffer_offset
self.position.global_offset += incr
self.position.global_line += 1
return Some(true)
}
b'\n' => {
// 处理 LF
self.position.buffer_offset = pos + 1
self.position.line_start_buffer_offset = self.position.buffer_offset
self.position.global_offset += 1
self.position.global_line += 1
return Some(true)
}
_ => {
self.position.buffer_offset = pos
return Some(false)
}
}
}
self.position.buffer_offset = pos
if self.is_ending {
Some(false)
} else {
None
}
}
///|
fn[RL] Lexer::skip_whitespaces_and_comments(self : Lexer[RL]) -> Bool? {
// 首先跳过空白字符
match self.skip_whitespaces() {
Some(true) => return Some(true)
Some(false) => ()
None => return None
}
// 检查是否有行注释
match self.line_comment_start {
Some(comment_start) => {
let buf = self.data[self.position.buffer_offset:]
// 检查是否以注释开始
if !array_view_has_prefix(buf, comment_start) {
// 不是注释,但可能是不完整的注释开始
if !self.is_ending && buf.length() < comment_start.length() {
return None
}
return Some(false)
}
// 查找注释结束位置(换行符)
let start_len = comment_start.length()
let end_pos = Lexer::find_line_end(buf, start_len)
match end_pos {
Some(end) => {
let comment_size = end + 1
self.position.buffer_offset += comment_size
self.position.line_start_buffer_offset = self.position.buffer_offset
self.position.global_offset += comment_size
self.position.global_line += 1
Some(true)
}
None =>
if self.is_ending {
self.position.buffer_offset = self.data.length()
Some(false)
} else {
None
}
}
}
None => return Some(false)
}
}
///|
fn Lexer::find_line_end(buf : ArrayView[Byte], start : Int) -> Int? {
let mut i = start
let len = buf.length()
while i < len {
match buf[i] {
b'\n' => return Some(i)
b'\r' => {
// 检查是否是 CRLF
if i + 1 < len && buf[i + 1] == b'\n' {
return Some(i + 1)
}
return Some(i)
}
_ => i += 1
}
}
None
}
///|
fn Lexer::find_number_of_line_jumps_and_start_of_last_line(
bytes : ArrayView[Byte],
) -> (Int, Int) {
let mut jumps : Int = 0
let mut last_start : Int = 0
let mut i : Int = 0
while i < bytes.length() {
match bytes[i] {
b'\n' => {
jumps += 1
last_start = i + 1
i += 1
}
b'\r' => {
jumps += 1
if i + 1 < bytes.length() && bytes[i + 1] == b'\n' {
last_start = i + 2
i += 2
} else {
last_start = i + 1
i += 1
}
}
_ => i += 1
}
}
(jumps, last_start)
}
///|
fn Lexer::column_from_bytes(bytes : ArrayView[Byte]) -> Int {
let mut count : Int = 0
let mut i : Int = 0
let len = bytes.length()
while i < len {
let b = bytes[i]
if (b & 0x80) == 0 {
// ASCII: 1 字节
i += 1
} else if (b & 0xE0) == 0xC0 {
// 2 字节 UTF-8
i += 2
} else if (b & 0xF0) == 0xE0 {
// 3 字节 UTF-8
i += 3
} else {
// 4 字节 UTF-8
i += 4
}
count += 1
}
count
}
///|
fn[T] Lexer::current_offset(self : Lexer[T]) -> Int {
self.position.buffer_offset + self.position.line_start_buffer_offset
}
///|
/// 获取当前行号
pub fn[T] Lexer::current_line(self : Lexer[T]) -> Int {
self.position.global_line
}
///|
/// 获取当前列号
fn[T] Lexer::current_column(self : Lexer[T]) -> Int {
let offset = self.current_offset()
let line_start = self.position.line_start_buffer_offset
offset - line_start + 1
}
///|
/// 获取当前位置(完整信息)
pub fn[T] Lexer::current_position(self : Lexer[T]) -> SourcePos {
SourcePos::SourcePos(
self.position.global_line,
self.current_column(),
self.current_offset(),
)
}
///|
/// 获取 token 范围
pub fn[T] Lexer::current_token_range(self : Lexer[T]) -> Range {
Range::Range(self.current_token_start, self.current_token_end)
}
///|
/// 记录 token 起始
pub fn[T] Lexer::record_token_start(self : Lexer[T]) -> Unit {
// 使用 global_offset 确保位置在数据收缩后依然有效
self.current_token_start = self.position.global_offset
}
///|
/// 记录 token 结束
pub fn[T] Lexer::record_token_end(self : Lexer[T]) -> Unit {
// 使用 global_offset 确保位置在数据收缩后依然有效
self.current_token_end = self.position.global_offset
}
///|
/// 获取上一个 token 的起始位置(解析完成后)
pub fn[RL] Lexer::last_token_start(self : Lexer[RL]) -> SourcePos {
self.position_from_position(self.previous_position)
}
///|
/// 获取上一个 token 的结束位置
pub fn[RL] Lexer::last_token_end(self : Lexer[RL]) -> SourcePos {
self.position_from_position(self.position)
}
///|
pub fn[RL] Lexer::last_token_range(self : Lexer[RL]) -> SourceRange {
SourceRange(self.last_token_start(), self.last_token_end())
}