// ===== 状态: TriGState::TriplesOrGraph =====
// 功能: 处理三元组或图的起始,识别主语或图名

///|
fn TriGRecognizer::handle_triples_or_graph_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "@@@ handling event: \{event} Token stack: \{@debug.to_string(self.stack)}",
  )
  
  match event {
    // 1. 处理 IRI
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      let term = NamedNodeRef::new_unchecked(iri).as_enum()
      Ok((self, TriGState::WrappedGraphOrPredicateObjectList(term~), None))
    }

    // 2. 处理前缀名称(如 :s, :p, :o)
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PrefixedName(prefix~, localx~, ..), _)
    ) => {
      self.debug_logger.info(
        "@@@ PrefixedName: prefix='\{prefix.to_string()}', local='\{localx.to_string()}'",
      )
      // 从 context 获取已注册的前缀
      let ctx = match _context {
        RdfContext::TriGRecognizerContext(c) => c
        _ =>
          return Err(
            RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
          )
      }

      // 查找前缀对应的 IRI base
      let base_iri = match ctx.prefixes.get(prefix) {
        Some(iri) => iri.to_string()
        None => prefix.to_string() // 如果没找到,使用原始 prefix
      }

      let iri = "\{base_iri}\{localx}"
      self.debug_logger.info(
        "PrefixedName resolved: \{prefix}:\{localx} -> \{iri}",
      )

      let term = NamedNodeRef::new_unchecked(iri).as_enum()
      Ok((self, TriGState::WrappedGraphOrPredicateObjectList(term~), None))
    }
    // 3. 处理 { 开始图块
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("{"), _)
    ) =>
      // let new_stack = self.stack
      // new_stack.push(TriGState::WrappedGraphPossibleEnd) // 图块结束后等待 }
      // new_stack.push(TriGState::TriplesOrGraph) // 图内三元组
      // let new_self = { ..self, stack: new_stack }
      Ok((self, TriGState::TriplesOrGraph, None))

    // 4. 处理 ( 开始集合
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("("), _)
    ) => {
      let new_stack = self.stack
      new_stack.push(TriGState::ExpectDot)
      new_stack.push(TriGState::PredicateObjectList)
      new_stack.push(TriGState::SubjectCollectionBeginning)
      Ok(
        (
          { ..self, stack: new_stack },
          TriGState::SubjectCollectionBeginning,
          None,
        ),
      )
    }
    // LocatedTokenOrLineJump::LocatedN3Token(tok) => {
    //   self.debug_logger.info("Token type: \{tok.0}")
    //   match tok.0 {
    //     // ... 现有处理 ...
    //     _ => {
    //       self.debug_logger.info("@@@ Unhandled token: \{tok.0}")
    //       Err(
    //         RuleRecognizerError::SyntaxError(
    //           "Unhandled token type",
    //           self.last_range,
    //         ),
    //       )
    //     }
    //   }
    // }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "TOKEN is not a valid subject or graph name",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::WrappedGraphOrPredicateObjectList =====
// 功能: 根据term判断是进入图块还是谓词对象列表

///|
fn TriGRecognizer::handle_wrapped_graph_or_predicate_object_list_m(
  self : TriGRecognizer,
  term : NamedOrBlankNodeRef, // 从状态中提取
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info(
    "WrappedGraphOrPredicateObjectList: event=\{event} Token stack: \{@debug.to_string(self.stack)}",
  )
  self.debug_logger.info(
    "Current subject: \{@debug.to_string(self.cur_subject)},Current predicate: \{@debug.to_string(self.cur_predicate)},Current object: \{@debug.to_string(self.cur_object)}",
  )

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("{"), _)
    ) if ctx.with_graph_name => {
      let new_self = { ..self, cur_graph: term.into_graph() }
      // 转移到 WrappedGraph
      Ok((new_self, TriGState::WrappedGraph, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword("a"), _)
    ) => {
      let new_self = self
      new_self.cur_subject.push(term)
      new_self.cur_predicate.push(lwTYPE)

      let new_stack = new_self.stack
      new_stack.push(TriGState::ExpectDot)
      // 不再压入 ObjectsList,直接准备进入 Object 状态
      // 但我们需要告诉引擎用同一个 token 调用 Object 状态
      // 由于当前架构每次 transition 都消费 token,我们需要直接返回 Object
      let new_self_with_stack = { ..new_self, stack: new_stack }
      // 直接转移到 Object 状态,让引擎用同一个 token 处理
      Ok((new_self_with_stack, TriGState::Object, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      self.debug_logger.info(
        "[Step 2] WrappedGraphOrPredicateObjectList: event=\{event}",
      )

      let new_self = self
      new_self.cur_subject.push(term)
      new_self.cur_predicate.push(NamedNodeRef::new_unchecked(iri))

      let new_stack = new_self.stack
      new_stack.push(TriGState::ExpectDot)

      // 直接转移到 Object 状态
      let new_self_with_stack = { ..new_self, stack: new_stack }
      Ok((new_self_with_stack, TriGState::Object, None))
    }
    // ✅ 处理 PrefixedName 作为 predicate
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          let new_self = self
          new_self.cur_subject.push(term)
          // match t {
          // NamedOrBlankNodeRef::NamedNodeRef(n) => {
          new_self.cur_predicate.push(t)
          // }
          // _ =>
          //   return Err(
          //     RuleRecognizerError::SyntaxError(
          //       "PrefixedName in predicate position must resolve to IRI",
          //       self.last_range,
          //     ),
          //   )
          // }

          let new_stack = new_self.stack
          new_stack.push(TriGState::ExpectDot)

          let new_self_with_stack = { ..new_self, stack: new_stack }
          Ok((new_self_with_stack, TriGState::Object, None))
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected a predicate or graph block",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::ObjectsList =====
// 功能: 路由到Object状态处理对象列表

///|
fn TriGRecognizer::handle_objects_list_m(
  self : TriGRecognizer,
  _event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {

  // ObjectsList 只是路由到 Object
  // 原代码: push Object, then recognize_next (which processes same token)
  self.debug_logger.info("ObjectsList: routing to Object state")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  let new_stack = self.stack
  new_stack.push(TriGState::Object) // 如果内部栈需要记录返回点? 原代码似乎没 push 返回点到内部栈,而是直接切换逻辑

  // 注意:原代码中 ObjectsList 是一个"瞬态"状态,它立即把控制权交给 Object。
  // 如果我们的状态机引擎在一次 transition 中只走一步,那么返回 Object 状态是正确的。

  let new_self = { ..self, stack: new_stack }
  Ok((new_self, TriGState::Object, None))
}

// ===== 状态: TriGState::Object =====
// 功能: 处理RDF对象(IRI、字面量、集合等)

///|
fn TriGRecognizer::handle_object_m(
  self : TriGRecognizer,
  event : Event,
  __context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "Object: handling event: \{event},Token stack: \{@debug.to_string(self.stack)}",
  )

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      let obj_term = TermRef::NamedNodeRef(NamedNodeRef::new_unchecked(iri))
      // let new_self = self
      self.cur_object.push(obj_term)
      // emit_quad 逻辑:生成一个 RdfOut
      // 假设 make_current_quad 或类似方法可用
      let quad = self.make_current_quad() // 假设此方法存在并正确构建 Quad
      self.debug_logger.info("[Step 4]Object: emitted quad: \{quad}")

      // 转移状态:根据原代码,push PredicateObjectListEnd
      let new_stack = self.stack
      new_stack.push(TriGState::PredicateObjectListEnd)

      let final_self = { ..self, stack: new_stack }
      // 返回生成的 Quad
      Ok((final_self, TriGState::PredicateObjectListEnd, Some(quad)))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("("), _)
    ) => {
      // 嵌套集合
      let new_stack = self.stack
      new_stack.push(TriGState::ObjectCollectionBeginning)

      let new_self = { ..self, stack: new_stack }
      // 转移到 ObjectCollectionBeginning
      Ok((new_self, TriGState::ObjectCollectionBeginning, None))
    }
    // ✅ 添加 String 处理
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::String(value), _)
    ) => {
      let new_self = self
      new_self.cur_object.push(
        TermRef::LiteralRef(LiteralRef::new_simple_literal(value)),
      )

      // 生成 quad
      let quad = new_self.make_current_quad()

      // 进入 PredicateObjectListEnd
      new_self.stack.push(TriGState::PredicateObjectListEnd)
      let final_self = { ..new_self, stack: new_self.stack }
      Ok((final_self, TriGState::PredicateObjectListEnd, Some(quad)))
    }

    // ✅ 添加 LongString 处理
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LongString(value), _)
    ) => {
      let new_self = self
      new_self.cur_object.push(
        TermRef::LiteralRef(LiteralRef::new_simple_literal(value)),
      )

      let quad = new_self.make_current_quad()
      new_self.stack.push(TriGState::PredicateObjectListEnd)
      let final_self = { ..new_self, stack: new_self.stack }
      Ok((final_self, TriGState::PredicateObjectListEnd, Some(quad)))
    }
    // ✅ 添加带数据类型注解的 String
    // LocatedTokenOrLineJump::LocatedN3Token(
    //   LocatedN3Token(N3Token::StringWithDatatype(value, dt~), _)
    // ) => {
    //   let new_self = self
    //   new_self.cur_object.push(
    //     TermRef::LiteralRef(LiteralRef::new_typed_literal(value, dt).as_ref()),
    //   )

    //   let quad = new_self.make_current_quad()
    //   new_self.stack.push(TriGState::PredicateObjectListEnd)
    //   let final_self = { ..new_self, stack: new_self.stack }
    //   Ok((final_self, TriGState::PredicateObjectListEnd, Some(quad)))
    // }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "TOKEN is not a valid RDF object",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::ObjectCollectionBeginning =====
// 功能: 处理 '(' 后的第一个元素或空集合情况

///|
fn TriGRecognizer::handle_object_collection_beginning_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  // let ctx = match context {
  //   RdfContext::TriGRecognizerContext(c) => c
  //   _ =>
  //     return Err(
  //       RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
  //     )
  // }

  self.debug_logger.info("ObjectCollectionBeginning: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(")"), _)
    ) => {
      // 空集合 ()
      let new_self = self
      new_self.cur_object.push(TermRef::NamedNodeRef(lwNIL))

      // emit_quad for nil? 原代码调用了 emit_quad(results)
      let quad = new_self.make_current_quad()

      let new_stack = new_self.stack
      new_stack.push(TriGState::PredicateObjectListEnd)

      let final_self = { ..new_self, stack: new_stack }
      Ok((final_self, TriGState::PredicateObjectListEnd, Some(quad)))
    }
    _ => {
      // 非空集合
      let root = BlankNode::default()
      let new_self = self

      // Push root as current object and emit quad (Subject, Predicate, Root)
      new_self.cur_object.push(TermRef::BlankNodeRef(root.as_ref()))
      let quad_root = new_self.make_current_quad()

      // Prepare for first element
      new_self.cur_subject.push(
        NamedOrBlankNodeRef::BlankNodeRef(root.as_ref()),
      )
      new_self.cur_predicate.push(
        NamedNodeRef::NamedNodeRef(lwFIRST.to_string()),
      )

      let new_stack = new_self.stack
      new_stack.push(TriGState::ObjectCollectionPossibleEnd)
      new_stack.push(TriGState::Object)

      let final_self = { ..new_self, stack: new_stack }
      // 返回根节点的 Quad,后续元素的 Quad 将在后续状态中生成
      Ok((final_self, TriGState::Object, Some(quad_root)))
    }
  }
}

// ===== 状态: TriGState::ObjectCollectionPossibleEnd =====
// 功能: 检查集合是否结束或继续处理下一个元素

///|
fn TriGRecognizer::handle_object_collection_possible_end_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "ObjectCollectionPossibleEnd: handling event: \{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  let old_subject = match self.cur_subject.pop() {
    Some(s) => s
    None =>
      return Err(
        RuleRecognizerError::SyntaxError(
          "Internal error: subject stack empty",
          self.last_range,
        ),
      )
  }

  // Clean up object stack if needed? Original code pops object.
  // Let's assume we need to pop the object that was just processed by the previous Object state.
  // However, in our flow, Object state returns the Quad. The object remains in cur_object until popped here?
  // Original code: let _ = self.cur_object.pop()

  let new_self = { ..self, cur_subject: self.cur_subject } // Pop last subject manually if pop() isn't available on immutable, or use mutable logic in builder
  // For simplicity, assuming we construct new_self with updated stacks

  if event
    is LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(")"), _)
    ) {
    // End of collection
    let _ = new_self.cur_predicate.pop()

    // Generate rest -> nil
    let rest_quad = RdfOut::Quad(
      Quad::Quad(
        old_subject.into_owned(),
        lwREST.into_owned(),
        lwNIL.as_term().into_owned(),
        new_self.cur_graph.into_owned(),
      ),
    )

    let new_stack = new_self.stack
    new_stack.push(TriGState::PredicateObjectListEnd)

    let final_self = { ..new_self, stack: new_stack }
    Ok((final_self, TriGState::PredicateObjectListEnd, Some(rest_quad)))
  } else {
    // Continue collection
    let new_bnode = BlankNode::default()

    // Generate rest -> new_bnode (Original code used lwNIL here which seems wrong, but we follow logic or fix it)
    // Fixing to use new_bnode for correct RDF list construction
    let rest_quad = RdfOut::Quad(
      Quad::Quad(
        old_subject.into_owned(),
        lwREST.into_owned(),
        new_bnode.as_ref().as_term().into_owned(),
        new_self.cur_graph.into_owned(),
      ),
    )

    // Push new subject for next element
    let updated_cur_subject = new_self.cur_subject
    updated_cur_subject.push(
      NamedOrBlankNodeRef::BlankNodeRef(new_bnode.as_ref()),
    )

    let new_stack = new_self.stack
    new_stack.push(TriGState::ObjectCollectionPossibleEnd)
    new_stack.push(TriGState::Object)

    let final_self = {
      ..new_self,
      cur_subject: updated_cur_subject,
      stack: new_stack,
    }
    Ok((final_self, TriGState::Object, Some(rest_quad)))
  }
}

// ===== 状态: TriGState::PredicateObjectListEnd =====
// 功能: 处理谓词对象列表结束符(逗号、分号、句号)

///|
fn TriGRecognizer::handle_predicate_object_list_end_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info("PredicateObjectListEnd: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(","), _)
    ) =>
      // Same predicate, next object
      Ok((self, TriGState::Object, None))
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(";"), _)
    ) =>
      // Same subject, next predicate
      // Original code pushes PredicateObjectListPossibleContinuation
      // We need to define this state or handle it. Assuming it leads back to Verb/Predicate parsing.
      Ok((self, TriGState::PredicateObjectListPossibleContinuation, None))
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("."), _)
    ) => {
      // End of statement
      let new_self = {
        ..self,
        stack: [TriGState::TriGDoc], // Reset stack to Doc
        cur_subject: [],
        cur_predicate: [],
        cur_object: [],
      }
      Ok((new_self, TriGState::TriGDoc, None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected ';' or '.' after predicate-object list",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::TriGDoc =====
// 功能: TriG文档的顶层状态,处理指令和三文组

///|
fn TriGRecognizer::handle_trig_doc_m(
  self : TriGRecognizer,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info("[Step 1] Entering TriGDoc with event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  let new_self = { ..self, cur_graph: GraphNameRef::DefaultGraph }

  match event {
    // 匹配 BASE 关键字
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "base") =>
      Ok((new_self, TriGState::BaseExpectIri, None))

    // 匹配 PREFIX 关键字
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "prefix") =>
      Ok((new_self, TriGState::PrefixExpectPrefix, None))

    // 匹配 VERSION 关键字
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "version") =>
      Ok((new_self, TriGState::VersionExpectVersion, None))

    // 处理 @prefix, @base, @version 语法糖
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LangTag(language="prefix", direction=None), _)
    ) => {
      let new_stack = new_self.stack
      new_stack.push(TriGState::ExpectDot)
      new_stack.push(TriGState::PrefixExpectPrefix)
      let final_self = { ..new_self, stack: new_stack }
      Ok((final_self, TriGState::PrefixExpectPrefix, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LangTag(language="base", direction=None), _)
    ) => {
      let new_stack = new_self.stack
      new_stack.push(TriGState::ExpectDot)
      new_stack.push(TriGState::BaseExpectIri)
      let final_self = { ..new_self, stack: new_stack }
      Ok((final_self, TriGState::BaseExpectIri, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LangTag(language="version", direction=None), _)
    ) => {
      let new_stack = new_self.stack
      new_stack.push(TriGState::ExpectDot)
      new_stack.push(TriGState::VersionExpectVersion)
      let final_self = { ..new_self, stack: new_stack }
      Ok((final_self, TriGState::VersionExpectVersion, None))
    }

    // 处理 GRAPH 关键字
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "graph") && ctx.with_graph_name => {
      let new_stack = new_self.stack
      new_stack.push(TriGState::WrappedGraph)
      new_stack.push(TriGState::GraphName)
      let final_self = { ..new_self, stack: new_stack }
      Ok((final_self, TriGState::GraphName, None))
    }

    // 处理匿名图开始 {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("{"), _)
    ) if ctx.with_graph_name => {
      let new_stack = new_self.stack
      new_stack.push(TriGState::WrappedGraph)
      let final_self = { ..new_self, stack: new_stack }
      Ok((final_self, TriGState::WrappedGraph, None))
    }

    // ✅ 处理 IRI 作为主语
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      self.debug_logger.info("TriGDoc: IRI as subject = \{iri}")
      let new_self_with_subject = new_self
      new_self_with_subject.cur_subject.push(
        NamedNodeRef::new_unchecked(iri).as_enum(),
      )
      // 进入 WrappedGraphOrPredicateObjectList,等待谓词
      let new_stack = new_self_with_subject.stack
      new_stack.push(
        TriGState::WrappedGraphOrPredicateObjectList(
          term=NamedNodeRef::new_unchecked(iri).as_enum(),
        ),
      )
      let final_self = { ..new_self_with_subject, stack: new_stack }
      Ok(
        (
          final_self,
          TriGState::WrappedGraphOrPredicateObjectList(
            term=NamedNodeRef::new_unchecked(iri).as_enum(),
          ),
          None,
        ),
      )
    }

    // 处理 BlankNode 作为主语
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::BlankNodeLabel(label), _)
    ) => {
      self.debug_logger.info("TriGDoc: BlankNode as subject = \{label}")
      let new_self_with_subject = new_self
      new_self_with_subject.cur_subject.push(
        BlankNodeRef::new_unchecked(label).as_enum(),
      )
      let new_stack = new_self_with_subject.stack
      new_stack.push(
        TriGState::WrappedGraphOrPredicateObjectList(
          term=BlankNodeRef::new_unchecked(label).as_enum(),
        ),
      )
      let final_self = { ..new_self_with_subject, stack: new_stack }
      Ok(
        (
          final_self,
          TriGState::WrappedGraphOrPredicateObjectList(
            term=BlankNodeRef::new_unchecked(label).as_enum(),
          ),
          None,
        ),
      )
    }

    // 处理 PrefixedName 作为主语
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          self.debug_logger.info("TriGDoc: PrefixedName as subject = \{t}")
          let new_self_with_subject = new_self
          new_self_with_subject.cur_subject.push(t.as_enum())
          let new_stack = new_self_with_subject.stack
          new_stack.push(
            TriGState::WrappedGraphOrPredicateObjectList(term=t.as_enum()),
          )
          let final_self = { ..new_self_with_subject, stack: new_stack }
          Ok(
            (
              final_self,
              TriGState::WrappedGraphOrPredicateObjectList(term=t.as_enum()),
              None,
            ),
          )
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }

    // 处理集合开始 ( 作为主语
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("("), _)
    ) => {
      let new_stack = new_self.stack
      new_stack.push(TriGState::PredicateObjectList)
      new_stack.push(TriGState::SubjectCollectionBeginning)
      let final_self = { ..new_self, stack: new_stack }
      Ok((final_self, TriGState::SubjectCollectionBeginning, None))
    }

    // 处理空白节点属性列表 [ 作为主语
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("["), _)
    ) => {
      let new_stack = new_self.stack
      new_stack.push(TriGState::WrappedGraphBlankNodePropertyListCurrent)
      let final_self = { ..new_self, stack: new_stack }
      Ok(
        (final_self, TriGState::WrappedGraphBlankNodePropertyListCurrent, None),
      )
    }

    // 默认情况
    _ => {
      self.debug_logger.info(
        "TriGDoc: unexpected token, pushing TriplesOrGraph",
      )
      let new_stack = new_self.stack
      new_stack.push(TriGState::TriplesOrGraph)
      let final_self = { ..new_self, stack: new_stack }
      Ok((final_self, TriGState::TriplesOrGraph, None))
    }
  }
}

// ===== 状态: TriGState::Triples =====
// 功能: 处理图内的三元组,识别主语

///|
fn TriGRecognizer::handle_triples_m(
  self : TriGRecognizer,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info("Entering Triples with event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("}"), _)
    ) => Ok((self, TriGState::Triples, None))
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("["), _)
    ) => {
      let new_subject = BlankNode::default()
      let new_cur_subject = self.cur_subject +
        [NamedOrBlankNodeRef::BlankNodeRef(new_subject.as_ref())]
      let new_self = { ..self, cur_subject: new_cur_subject }
      Ok((new_self, TriGState::PredicateObjectList, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      let new_cur_subject = self.cur_subject +
        [NamedNodeRef::new_unchecked(iri).as_enum()]
      let new_self = { ..self, cur_subject: new_cur_subject }
      Ok((new_self, TriGState::PredicateObjectList, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          let new_cur_subject = self.cur_subject + [t.as_enum()]
          let new_self = { ..self, cur_subject: new_cur_subject }
          Ok((new_self, TriGState::PredicateObjectList, None))
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::BlankNodeLabel(label), _)
    ) => {
      let new_cur_subject = self.cur_subject +
        [NamedOrBlankNodeRef::BlankNodeRef(BlankNodeRef::new_unchecked(label))]
      let new_self = { ..self, cur_subject: new_cur_subject }
      Ok((new_self, TriGState::PredicateObjectList, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("("), _)
    ) => {
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::PredicateObjectList)
      new_stack.push(TriGState::SubjectCollectionBeginning)
      let new_self = { ..self, stack: new_stack }
      Ok((new_self, TriGState::SubjectCollectionBeginning, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("<<"), _)
    ) => {
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::MaybePredicateObjectList)
      new_stack.push(TriGState::SubjectReifiedTripleEnd)
      new_stack.push(TriGState::EndOfReifiedTripleBeforeReifier)
      new_stack.push(TriGState::ReifiedTripleSubject(is_reified=true))
      new_stack.push(TriGState::Verb)
      new_stack.push(TriGState::ReifiedTripleObject(is_reified=true))
      let new_self = { ..self, stack: new_stack }
      Ok((new_self, TriGState::Verb, None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "TOKEN is not a valid RDF subject".to_string(),
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::Verb =====
// 功能: 处理谓词(包括 'a' 关键字和IRI)

///|
fn TriGRecognizer::handle_verb_m(
  self : TriGRecognizer,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info("Verb: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    // 'a' 表示 rdf:type
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword("a"), _)
    ) => {
      self.debug_logger.info("Verb: 'a' predicate")
      let new_cur_predicate = self.cur_predicate + [lwTYPE]
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::ObjectsList)
      let new_self = {
        ..self,
        cur_predicate: new_cur_predicate,
        stack: new_stack,
      }
      Ok((new_self, TriGState::ObjectsList, None))
    }

    // IRI 谓词
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      self.debug_logger.info("Verb: IRI predicate: \{iri}")
      let new_cur_predicate = self.cur_predicate +
        [NamedNodeRef::new_unchecked(iri)]
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::ObjectsList)
      let new_self = {
        ..self,
        cur_predicate: new_cur_predicate,
        stack: new_stack,
      }
      Ok((new_self, TriGState::ObjectsList, None))
    }

    // 前缀名谓词
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          self.debug_logger.info("Verb: PrefixedName predicate: \{t}")
          let new_cur_predicate = self.cur_predicate + [t]
          let new_stack = self.stack.copy()
          new_stack.push(TriGState::ObjectsList)
          let new_self = {
            ..self,
            cur_predicate: new_cur_predicate,
            stack: new_stack,
          }
          Ok((new_self, TriGState::ObjectsList, None))
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }

    // 其他情况 - 错误
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected a predicate (IRI or 'a'), found: \{event}".to_string(),
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::ExpectDot =====
// 功能: 期望遇到句号,用于指令结束

///|
fn TriGRecognizer::handle_expect_dot_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info("ExpectDot: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("."), _)
    ) => {
      // 重置到文档级别状态
      let new_self = self.reset_to_tri_gdoc() // 假设此方法返回新的 TriGRecognizer 实例
      Ok((new_self, TriGState::TriGDoc, None))
    }
    _ => {
      // 记录错误并重置
      let err = RuleRecognizerError::TripleMissingDot
      let new_self = self.add_error(err).reset_to_tri_gdoc()
      Ok((new_self, TriGState::TriGDoc, None))
    }
  }
}

// ===== 状态: TriGState::BaseExpectIri =====
// 功能: BASE指令后期望IRI

///|
fn TriGRecognizer::handle_base_expect_iri_m(
  self : TriGRecognizer,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info("BaseExpectIri: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Iri(iri_str), _)
    ) => {
      let iri_ref = Iri::new(iri_str)
      let new_ctx_options = if self.lenient {
        { base_iri: Some(IriRef::parse_unchecked(iri_ref)) }
      } else {
        match IriRef::parse(iri_ref) {
          Ok(parsed_iri) => { base_iri: Some(parsed_iri) }
          Err(e) => {
            let err = RuleRecognizerError::SyntaxError(
              "Invalid BASE IRI: \{e.to_string()}",
              self.last_range,
            )
            let new_self = self.add_error(err)
            // 即使出错也继续,但保持上下文不变或更新为默认?这里假设出错不更新 base_iri
            return Ok((new_self, TriGState::ExpectDot, None))
          }
        }
      }

      let new_ctx = { ..ctx, lexer_options: new_ctx_options }
      let new_context = RdfContext::TriGRecognizerContext(new_ctx)
      let new_self = self.set_context(new_context)

      Ok((new_self, TriGState::ExpectDot, None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "The BASE keyword should be followed by an IRI",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::PrefixExpectPrefix =====
// 功能: PREFIX指令后期望前缀名

///|
fn TriGRecognizer::handle_prefix_expect_prefix_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  // let ctx = match context {
  //   RdfContext::TriGRecognizerContext(c) => c
  //   _ =>
  //     return Err(
  //       RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
  //     )
  // }

  self.debug_logger.info("PrefixExpectPrefix: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PrefixedName(prefix~, localx~, ..), _)
    ) if localx.is_empty() =>
      Ok((self, TriGState::PrefixExpectIri(name=prefix), None))
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Iri(iri_str), _)
    ) if iri_str.has_suffix(":") => {
      let prefix = iri_str[0:iri_str.length() - 1]
      Ok((self, TriGState::PrefixExpectIri(name=prefix.to_owned()), None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if k.has_suffix(":") => {
      let prefix = k[0:k.length() - 1]
      Ok((self, TriGState::PrefixExpectIri(name=prefix.to_owned()), None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "The PREFIX keyword should be followed by a prefix like 'ex:'",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::PrefixExpectIri =====
// 功能: 前缀名后期望IRI值

///|
fn TriGRecognizer::handle_prefix_expect_iri_m(
  self : TriGRecognizer,
  name : String,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info("PrefixExpectIri: name=\{name}, event=\{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Iri(iri_str), _)
    ) => {
      let iri = Iri::Iri(iri_str)
      let new_prefixes = ctx.prefixes.copy()
      new_prefixes.set(name, iri)
      let new_ctx = { ..ctx, prefixes: new_prefixes }
      let new_context = RdfContext::TriGRecognizerContext(new_ctx)
      let new_self = self.set_context(new_context)

      Ok((new_self, TriGState::ExpectDot, None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "The PREFIX declaration should be followed by a prefix and its value as an IRI",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::VersionExpectVersion =====
// 功能: VERSION指令后期望版本号字符串

///|
fn TriGRecognizer::handle_version_expect_version_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info("VersionExpectVersion: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::String(_), _)
    ) => Ok((self, TriGState::ExpectDot, None))
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "The VERSION keyword should be followed by a single quoted string like \"1.2\"",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::WrappedGraphBlankNodePropertyListCurrent =====
// 功能: 处理图中空白节点属性列表的当前状态

///|
fn TriGRecognizer::handle_wrapped_graph_blank_node_property_list_current_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "WrappedGraphBlankNodePropertyListCurrent: handling event: \{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("]"), _)
    ) => {
      let term = BlankNode::default().as_ref().as_enum()
      Ok((self, TriGState::WrappedGraphOrPredicateObjectList(term~), None))
    }
    _ => {
      let bnode = BlankNode::default().as_ref().as_enum()
      let new_cur_subject = self.cur_subject + [bnode]
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::ExpectDot)
      new_stack.push(TriGState::SubjectBlankNodePropertyListEnd)
      new_stack.push(TriGState::PredicateObjectList)

      let new_self = { ..self, cur_subject: new_cur_subject, stack: new_stack }
      Ok((new_self, TriGState::PredicateObjectList, None))
    }
  }
}

// ===== 状态: TriGState::SubjectBlankNodePropertyListEnd =====
// 功能: 主语空白节点属性列表结束,期望']'

///|
fn TriGRecognizer::handle_subject_blank_node_property_list_end_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "SubjectBlankNodePropertyListEnd: handling event: \{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("]"), _)
    ) => Ok((self, TriGState::SubjectBlankNodePropertyListAfter, None))
    _ => {
      let err = RuleRecognizerError::BlankNodePropertyListMissingEndBracket
      let new_self = self.add_error(err)
      Ok((new_self, TriGState::SubjectBlankNodePropertyListAfter, None))
    }
  }
}

// ===== 状态: TriGState::SubjectBlankNodePropertyListAfter =====
// 功能: 主语空白节点属性列表结束后处理

///|
fn TriGRecognizer::handle_subject_blank_node_property_list_after_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "SubjectBlankNodePropertyListAfter: handling event: \{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("."), _)
    )
    | LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("}"), _)
    ) => Ok((self, TriGState::SubjectBlankNodePropertyListAfter, None))
    _ => {
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::PredicateObjectList)
      let new_self = { ..self, stack: new_stack }
      Ok((new_self, TriGState::PredicateObjectList, None))
    }
  }
}
// ===== 修正后的 handle_subject_collection_beginning_m =====

///|
fn TriGRecognizer::handle_subject_collection_beginning_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  match event {
    // ===== 情况1:空集合 () =====
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(")"), _)
    ) => {
      // ✅ 空集合:cur_subject.push(rdf:nil)
      let new_cur_subject = self.cur_subject + [lwNIL.as_enum()]
      let new_self = { ..self, cur_subject: new_cur_subject }

      // ✅ 返回 PredicateObjectList,处理后续的 '.' 或 ';'
      // 注意:SubjectCollectionBeginning 已经完成,应该弹出
      // 由于栈中可能有其他状态,直接返回 PredicateObjectList
      Ok((new_self, TriGState::PredicateObjectList, None))
    }

    // ===== 情况2:非空集合 (element ...) =====
    _ => {
      // ✅ 创建空白节点作为集合的根
      let root = NamedOrBlankNodeRef::BlankNodeRef(
        BlankNode::default().as_ref(),
      )
      let new_cur_subject = self.cur_subject + [root]
      let new_cur_predicate = self.cur_predicate + [lwFIRST]

      // ✅ 压入状态:处理集合结束 + 处理元素
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::SubjectCollectionPossibleEnd) // 处理 ')' 或下一个元素
      new_stack.push(TriGState::Object) // 处理当前元素

      let new_self = {
        ..self,
        cur_subject: new_cur_subject,
        cur_predicate: new_cur_predicate,
        stack: new_stack,
      }

      // ✅ 返回 Object 状态,处理当前元素
      // 注意:这里返回 Object,让引擎用同一个 token 继续处理
      Ok((new_self, TriGState::Object, None))
    }
  }
}

// ===== 状态: TriGState::SubjectCollectionPossibleEnd =====
// 功能: 检查主语集合是否结束或继续处理下一个元素

///|
fn TriGRecognizer::handle_subject_collection_possible_end_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "SubjectCollectionPossibleEnd: handling event: \{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  // 弹出当前 subject 和 object
  let old = match self.cur_subject.pop() {
    Some(s) => s
    None =>
      return Err(
        RuleRecognizerError::SyntaxError(
          "Internal error: subject stack is empty",
          self.last_range,
        ),
      )
  }
  let _ = self.cur_object.pop()

  match event {
    // ✅ 集合结束:收到 ')'
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(")"), _)
    ) => {
      // 弹出 predicate (rdf:first)
      let _ = self.cur_predicate.pop()

      // ✅ 输出 rdf:rest rdf:nil
      let quad = RdfOut::Quad(
        Quad::Quad(
          old.into_owned(),
          lwREST.into_owned(),
          lwNIL.into_owned().as_term(),
          self.cur_graph.into_owned(),
        ),
      )

      // ✅ 返回 PredicateObjectList 继续处理
      Ok((self, TriGState::PredicateObjectList, Some(quad)))
    }

    // ✅ 还有更多元素
    _ => {
      // 创建新的空白节点
      let new = BlankNode::default()

      // ✅ 输出 rdf:rest new
      let quad = RdfOut::Quad(
        Quad::Quad(
          old.into_owned(),
          lwREST.into_owned(),
          new.as_ref().as_term().into_owned(),
          self.cur_graph.into_owned(),
        ),
      )

      // 设置新的 subject 和 predicate
      let new_cur_subject = self.cur_subject +
        [NamedOrBlankNodeRef::BlankNodeRef(new.as_ref())]
      let new_cur_predicate = self.cur_predicate + [lwFIRST]
      let new_self = {
        ..self,
        cur_subject: new_cur_subject,
        cur_predicate: new_cur_predicate,
      }

      // 压入状态继续处理
      let new_stack = new_self.stack
      new_stack.push(TriGState::SubjectCollectionPossibleEnd)
      new_stack.push(TriGState::Object)
      let new_self = { ..new_self, stack: new_stack }

      // ✅ 返回 Object 处理下一个元素
      Ok((new_self, TriGState::Object, Some(quad)))
    }
  }
}

// ===== 状态: TriGState::TriplesBlankNodePropertyListCurrent =====
// 功能: 处理三元组中空白节点属性列表的当前状态

///|
fn TriGRecognizer::handle_triples_blank_node_property_list_current_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "TriplesBlankNodePropertyListCurrent: handling event: \{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("]"), _)
    ) => Ok((self, TriGState::PredicateObjectList, None))
    _ => {
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::SubjectBlankNodePropertyListEnd)
      new_stack.push(TriGState::PredicateObjectList)
      let new_self = { ..self, stack: new_stack }
      Ok((new_self, TriGState::PredicateObjectList, None))
    }
  }
}

// ===== 状态: TriGState::GraphName =====
// 功能: 处理图名的解析(IRI、前缀名、空白节点等)

///|
fn TriGRecognizer::handle_graph_name_m(
  self : TriGRecognizer,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info("GraphName: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    // ✅ IRI 作为图名
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      let new_cur_graph = GraphNameRef::NamedNodeRef(
        NamedNodeRef::new_unchecked(iri),
      )
      let new_self = { ..self, cur_graph: new_cur_graph }
      // ✅ 返回 GraphName,等待下一个 token(应该是 '{')
      // 下一个 token 会在 WrappedGraph 状态处理
      Ok((new_self, TriGState::GraphName, None))
    }

    // ✅ PrefixedName 作为图名
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          let new_cur_graph = GraphNameRef::NamedNodeRef(t)
          let new_self = { ..self, cur_graph: new_cur_graph }
          // ✅ 返回 GraphName,等待 '{'
          Ok((new_self, TriGState::GraphName, None))
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }

    // ✅ BlankNode 作为图名
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::BlankNodeLabel(label), _)
    ) => {
      let new_cur_graph = GraphNameRef::BlankNodeRef(
        BlankNodeRef::new_unchecked(label),
      )
      let new_self = { ..self, cur_graph: new_cur_graph }
      // ✅ 返回 GraphName,等待 '{'
      Ok((new_self, TriGState::GraphName, None))
    }

    // ✅ 匿名图名: [ ... ]
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("["), _)
    ) => {
      // 创建匿名空白节点作为图名
      let bnode = BlankNode::default().as_ref()
      let new_cur_graph = GraphNameRef::BlankNodeRef(bnode)
      let new_self = { ..self, cur_graph: new_cur_graph }

      // ✅ 匿名图名需要处理内部的属性列表
      // 压入 GraphNameAnonEnd 状态等待 ']'
      self.stack.push(TriGState::GraphNameAnonEnd)

      // ✅ 返回 GraphName,等待 ']' 完成匿名图名
      Ok((new_self, TriGState::GraphName, None))
    }

    // ❌ 无效的图名
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Invalid graph name: expected IRI, PrefixedName, BlankNode, or '['",
          self.last_range,
        ),
      )
  }
}
// ===== 状态: TriGState::GraphNameAnonEnd =====
// 功能: 匿名图名结束,期望']'

///|
fn TriGRecognizer::handle_graph_name_anon_end_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info("GraphNameAnonEnd: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    // ✅ 收到 ']',匿名图名结束
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("]"), _)
    ) => {
      // 创建匿名空白节点作为图名
      let bnode = BlankNode::default().as_ref()
      let new_cur_graph = GraphNameRef::BlankNodeRef(bnode)
      let new_self = { ..self, cur_graph: new_cur_graph }

      // ✅ 返回 WrappedGraph,等待 '{'
      // 注意:不要返回 GraphNameAnonEnd,因为匿名图名已经结束
      Ok((new_self, TriGState::WrappedGraph, None))
    }

    // ❌ 不是 ']',错误
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected ']' to close anonymous graph name",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::MaybePredicateObjectList =====
// 功能: 可选的谓词对象列表,处理特殊情况

///|
fn TriGRecognizer::handle_maybe_predicate_object_list_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info("MaybePredicateObjectList: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("."), _)
    ) => Ok((self, TriGState::MaybePredicateObjectList, None))
    _ => {
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::PredicateObjectList)
      let new_self = { ..self, stack: new_stack }
      Ok((new_self, TriGState::PredicateObjectList, None))
    }
  }
}

// ===== 状态: TriGState::AnnotationEnd =====
// 功能: 注释结束,期望'|}'

///|
fn TriGRecognizer::handle_annotation_end_m(
  self : TriGRecognizer,
  with_reifier : Bool,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "AnnotationEnd: with_reifier=\{with_reifier}, event=\{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  let new_cur_subject = self.cur_subject // pop
  let new_self = { ..self, cur_subject: new_cur_subject }

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("|}"), _)
    ) => Ok((new_self, TriGState::AnnotationEnd(with_reifier~), None))
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Annotations should end with '|}'",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::ObjectBlankNodePropertyListCurrent =====
// 功能: 对象空白节点属性列表的当前状态

///|
fn TriGRecognizer::handle_object_blank_node_property_list_current_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "ObjectBlankNodePropertyListCurrent: handling event: \{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("]"), _)
    ) => {
      let bnode = BlankNode::default().as_ref()
      let new_cur_object = self.cur_object + [TermRef::BlankNodeRef(bnode)]
      let new_self = { ..self, cur_object: new_cur_object }
      let quad = new_self.emit_quad_m()
      Ok((new_self, TriGState::ObjectBlankNodePropertyListCurrent, Some(quad)))
    }
    _ => {
      let bnode = BlankNode::default().as_ref()
      let new_cur_subject = self.cur_subject +
        [NamedOrBlankNodeRef::BlankNodeRef(bnode)]
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::ObjectBlankNodePropertyListEnd)
      new_stack.push(TriGState::PredicateObjectList)
      let new_self = { ..self, cur_subject: new_cur_subject, stack: new_stack }
      Ok((new_self, TriGState::PredicateObjectList, None))
    }
  }
}

// ===== 状态: TriGState::LiteralExpectDatatype =====
// 功能: 字面量后期望数据类型IRI

///|
fn TriGRecognizer::handle_literal_expect_datatype_m(
  self : TriGRecognizer,
  value : String,
  emit : Bool,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info(
    "LiteralExpectDatatype: value='\{value}', emit=\{emit}, event=\{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Iri(datatype_str), _)
    ) => {
      if !self.lenient && datatype_str == lwLANG_STRING.to_string() {
        return Err(
          RuleRecognizerError::SyntaxError(
            "The datatype of a literal without a language tag must not be rdf:langString",
            self.last_range,
          ),
        )
      }
      if !self.lenient && datatype_str == lwDIR_LANG_STRING.to_string() {
        return Err(
          RuleRecognizerError::SyntaxError(
            "The datatype of a literal without a base direction must not be rdf:dirLangString",
            self.last_range,
          ),
        )
      }

      let datatype = NamedNodeRef::new_unchecked(datatype_str)
      let data_value = datatype.into_datatype(value)
      let literal = LiteralRef::new_typed_literal(data_value, datatype)
      let new_cur_object = self.cur_object + [TermRef::LiteralRef(literal)]
      let new_self = { ..self, cur_object: new_cur_object }

      if emit {
        let quad = new_self.emit_quad_m()
        Ok(
          (
            new_self,
            TriGState::LiteralExpectDatatype(value~, emit~),
            Some(quad),
          ),
        )
      } else {
        Ok((new_self, TriGState::LiteralExpectDatatype(value~, emit~), None))
      }
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          if !self.lenient && t == lwLANG_STRING {
            return Err(
              RuleRecognizerError::SyntaxError(
                "The datatype of a literal without a language tag must not be rdf:langString",
                self.last_range,
              ),
            )
          }
          if !self.lenient && t == lwDIR_LANG_STRING {
            return Err(
              RuleRecognizerError::SyntaxError(
                "The datatype of a literal without a base direction must not be rdf:dirLangString",
                self.last_range,
              ),
            )
          }

          let data_value = t.into_datatype(value)
          let literal = LiteralRef::new_typed_literal(data_value, t)
          let new_cur_object = self.cur_object + [TermRef::LiteralRef(literal)]
          let new_self = { ..self, cur_object: new_cur_object }

          if emit {
            let quad = new_self.emit_quad_m()
            Ok(
              (
                new_self,
                TriGState::LiteralExpectDatatype(value~, emit~),
                Some(quad),
              ),
            )
          } else {
            Ok(
              (new_self, TriGState::LiteralExpectDatatype(value~, emit~), None),
            )
          }
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expecting a datatype IRI after ^^",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::SubjectReifiedTripleEnd =====
// 功能: 引用三元组主语结束,期望'>>'

///|
fn TriGRecognizer::handle_subject_reified_triple_end_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info("SubjectReifiedTripleEnd: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  // 使用 pop() 弹出 reifier
  let reifier = match self.cur_reifier.pop() {
    Some(r) => r
    None =>
      return Err(
        RuleRecognizerError::SyntaxError(
          "Internal error: reifier stack empty",
          self.last_range,
        ),
      )
  }

  // 将弹出的 reifier 加入 cur_subject
  let new_cur_subject = self.cur_subject + [reifier]

  // self.cur_reifier 已经被 pop 修改,直接使用 self 并更新 cur_subject
  let new_self = { ..self, cur_subject: new_cur_subject }

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(">>"), _)
    ) => Ok((new_self, TriGState::SubjectReifiedTripleEnd, None))
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expecting '>>' to close a reified triple",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::TripleTermEnd =====
// 功能: 三元组项结束,期望')>>'

///|
fn TriGRecognizer::handle_triple_term_end_m(
  self : TriGRecognizer,
  emit : Bool,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info("TripleTermEnd: emit=\{emit}, event=\{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  // 使用 pop() 替代 unsnoc()
  let subject = match self.cur_subject.pop() {
    Some(s) => s
    None =>
      return Err(
        RuleRecognizerError::SyntaxError(
          "Internal error: subject stack empty in TripleTermEnd",
          self.last_range,
        ),
      )
  }
  let predicate = match self.cur_predicate.pop() {
    Some(p) => p
    None =>
      return Err(
        RuleRecognizerError::SyntaxError(
          "Internal error: predicate stack empty in TripleTermEnd",
          self.last_range,
        ),
      )
  }
  let object = match self.cur_object.pop() {
    Some(o) => o
    None =>
      return Err(
        RuleRecognizerError::SyntaxError(
          "Internal error: object stack empty in TripleTermEnd",
          self.last_range,
        ),
      )
  }

  let triple = TripleRef::TripleRef(subject, predicate, object)

  // 将 triple 作为对象推入 cur_object
  self.cur_object.push(TermRef::TripleRef(triple))

  let output = if emit { Some(self.emit_quad_m()) } else { None }

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(")>>"), _)
    ) =>
      // self 已经包含更新后的 cur_object, cur_subject 等
      Ok((self, TriGState::TripleTermEnd(emit~), output))
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expecting ')>>' to close a triple term",
          self.last_range,
        ),
      )
  }
}

// ===== 状态: TriGState::EndOfReifiedTripleBeforeReifier =====
// 功能: 引用三元组结束后处理reifier

///|
fn TriGRecognizer::handle_end_of_reified_triple_before_reifier_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "EndOfReifiedTripleBeforeReifier: handling event: \{event}",
  )
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  // 使用 pop() 弹出 subject, predicate, object
  let subject = match self.cur_subject.pop() {
    Some(s) => s
    None =>
      return Err(
        RuleRecognizerError::SyntaxError(
          "Internal error: subject stack empty",
          self.last_range,
        ),
      )
  }
  let predicate = match self.cur_predicate.pop() {
    Some(p) => p
    None =>
      return Err(
        RuleRecognizerError::SyntaxError(
          "Internal error: predicate stack empty",
          self.last_range,
        ),
      )
  }
  let object = match self.cur_object.pop() {
    Some(o) => o
    None =>
      return Err(
        RuleRecognizerError::SyntaxError(
          "Internal error: object stack empty",
          self.last_range,
        ),
      )
  }

  let triple = TripleRef::TripleRef(subject, predicate, object)

  // 此时 self 中的 cur_subject, cur_predicate, cur_object 已经被 pop 修改
  // 直接使用 self 作为 intermediate_self
  let intermediate_self = self

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("~"), _)
    ) =>
      Ok(
        (
          intermediate_self,
          TriGState::Reifier(triple=triple.into_owned()),
          None,
        ),
      )
    _ => {
      let reifier = BlankNode::default()
      let quad = RdfOut::Quad(
        Quad::Quad(
          reifier.as_enum(),
          lwREIFIES.into_owned(),
          TermRef::TripleRef(triple).into_owned(),
          intermediate_self.cur_graph.into_owned(),
        ),
      )
      // 注意:这里需要修改 cur_reifier,由于 intermediate_self 是 self 的别名/拷贝,
      // 我们需要构建一个新的 self 来更新 cur_reifier
      let new_cur_reifier = intermediate_self.cur_reifier +
        [reifier.as_enum().as_ref()]
      let new_self = { ..intermediate_self, cur_reifier: new_cur_reifier }
      Ok((new_self, TriGState::EndOfReifiedTripleBeforeReifier, Some(quad)))
    }
  }
}

// ===== 状态: TriGState::Reifier =====
// 功能: 处理reifier(引用节点)

///|
fn TriGRecognizer::handle_reifier_m(
  self : TriGRecognizer,
  triple : Triple,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info("Reifier: triple=\{triple}, event=\{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      let reifier = NamedNodeRef::new_unchecked(iri)
      let quad = RdfOut::Quad(
        Quad::Quad(
          reifier.as_enum().into_owned(),
          lwREIFIES.into_owned(),
          triple.as_enum(),
          self.cur_graph.into_owned(),
        ),
      )
      let new_cur_reifier = self.cur_reifier + [reifier.as_enum()]
      let new_self = { ..self, cur_reifier: new_cur_reifier }
      Ok((new_self, TriGState::Reifier(triple~), Some(quad)))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(reifier) => {
          let quad = RdfOut::Quad(
            Quad::Quad(
              reifier.as_enum().into_owned(),
              lwREIFIES.into_owned(),
              triple.as_term(),
              self.cur_graph.into_owned(),
            ),
          )
          let new_cur_reifier = self.cur_reifier + [reifier.as_enum()]
          let new_self = { ..self, cur_reifier: new_cur_reifier }
          Ok((new_self, TriGState::Reifier(triple~), Some(quad)))
        }
        Err(e) => {
          // Fallback to blank node reifier on error? Original code does this.
          let reifier = BlankNode::default()

          let quad = RdfOut::Quad(
            Quad::Quad(
              reifier.as_enum(),
              lwREIFIES.into_owned(),
              triple.as_term(),
              self.cur_graph.into_owned(),
            ),
          )
          let new_cur_reifier = self.cur_reifier + [reifier.as_enum().as_ref()]
          let new_self = self.add_error(
            RuleRecognizerError::SyntaxError(e, self.last_range),
          )
          let final_self = { ..new_self, cur_reifier: new_cur_reifier }
          Ok((final_self, TriGState::Reifier(triple~), Some(quad)))
        }
      }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::BlankNodeLabel(bnode), _)
    ) => {
      let reifier = BlankNodeRef::new_unchecked(bnode)
      let quad = RdfOut::Quad(
        Quad::Quad(
          reifier.as_enum().into_owned(),
          lwREIFIES.into_owned(),
          triple.as_enum(),
          self.cur_graph.into_owned(),
        ),
      )
      let new_cur_reifier = self.cur_reifier + [reifier.as_enum()]
      let new_self = { ..self, cur_reifier: new_cur_reifier }
      Ok((new_self, TriGState::Reifier(triple~), Some(quad)))
    }
    _ => {
      // Fallback to blank node reifier
      let reifier = BlankNode::default()
      let quad = RdfOut::Quad(
        Quad::Quad(
          reifier.as_enum(),
          lwREIFIES.into_owned(),
          triple.as_enum(),
          self.cur_graph.into_owned(),
        ),
      )
      let new_cur_reifier = self.cur_reifier + [reifier.as_ref().as_enum()]
      let new_self = { ..self, cur_reifier: new_cur_reifier }
      Ok((new_self, TriGState::Reifier(triple~), Some(quad)))
    }
  }
}

// ===== ReifiedTripleSubject 处理 =====

///|
fn TriGRecognizer::handle_reified_triple_subject_m(
  self : TriGRecognizer,
  is_reified : Bool,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("["), _)
    ) => {
      let bnode = BlankNode::default().as_ref()
      let new_cur_subject = self.cur_subject +
        [NamedOrBlankNodeRef::BlankNodeRef(bnode)]
      let new_self = { ..self, cur_subject: new_cur_subject }
      Ok((new_self, TriGState::QuotedAnonEnd, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      let new_cur_subject = self.cur_subject +
        [NamedOrBlankNodeRef::NamedNodeRef(NamedNodeRef::new_unchecked(iri))]
      let new_self = { ..self, cur_subject: new_cur_subject }
      Ok((new_self, TriGState::ReifiedTripleSubject(is_reified~), None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          let new_cur_subject = self.cur_subject + [t.as_enum()]
          let new_self = { ..self, cur_subject: new_cur_subject }
          Ok((new_self, TriGState::ReifiedTripleSubject(is_reified~), None))
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::BlankNodeLabel(label), _)
    ) => {
      let new_cur_subject = self.cur_subject +
        [NamedNodeRef::new_unchecked(label).as_enum()]
      let new_self = { ..self, cur_subject: new_cur_subject }
      Ok((new_self, TriGState::ReifiedTripleSubject(is_reified~), None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("<<"), _)
    ) if is_reified => {
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::SubjectReifiedTripleEnd)
      new_stack.push(TriGState::EndOfReifiedTripleBeforeReifier)
      new_stack.push(TriGState::ReifiedTripleSubject(is_reified=true))
      new_stack.push(TriGState::Verb)
      new_stack.push(TriGState::ReifiedTripleObject(is_reified=true))
      let new_self = { ..self, stack: new_stack }
      Ok((new_self, TriGState::Verb, None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "TOKEN is not a valid RDF quoted triple subject",
          self.last_range,
        ),
      )
  }
}

// ===== ReifiedTripleObject 处理 =====

///|
fn TriGRecognizer::handle_reified_triple_object_m(
  self : TriGRecognizer,
  is_reified : Bool,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("["), _)
    ) => {
      let bnode = BlankNode::default().as_ref()
      let new_cur_object = self.cur_object + [TermRef::BlankNodeRef(bnode)]
      let new_self = { ..self, cur_object: new_cur_object }
      Ok((new_self, TriGState::QuotedAnonEnd, None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      // 注意:原代码这里 push 的是 BlankNodeRef? 应该是 NamedNodeRef 或 TermRef
      // 修正为 NamedNodeRef
      let new_cur_object = self.cur_object +
        [TermRef::NamedNodeRef(NamedNodeRef::new_unchecked(iri))]
      let new_self = { ..self, cur_object: new_cur_object }
      Ok((new_self, TriGState::ReifiedTripleObject(is_reified~), None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          let new_cur_object = self.cur_object + [t.as_term()]
          let new_self = { ..self, cur_object: new_cur_object }
          Ok((new_self, TriGState::ReifiedTripleObject(is_reified~), None))
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::BlankNodeLabel(label), _)
    ) => {
      let new_cur_object = self.cur_object +
        [BlankNodeRef::new_unchecked(label).as_term()]
      let new_self = { ..self, cur_object: new_cur_object }
      Ok((new_self, TriGState::ReifiedTripleObject(is_reified~), None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::String(value), _)
    ) => Ok((self, TriGState::LiteralPossibleSuffix(value~, emit=false), None))
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Integer(v), _)
    ) => {
      let v = try @string.parse_int(v) |> Ok catch {
        e => Err(e)
      }
      match v {
        Ok(value) => {
          let literal = LiteralRef::new_typed_literal(
            VarDataType::IntVar(value.to_string()),
            lwINTEGER,
          )
          let new_cur_object = self.cur_object + [literal.as_term()]
          let new_self = { ..self, cur_object: new_cur_object }
          Ok((new_self, TriGState::ReifiedTripleObject(is_reified~), None))
        }
        Err(e) =>
          Err(RuleRecognizerError::SyntaxError(e.to_string(), self.last_range))
      }
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Decimal(v), _)
    ) => {
      let v = try @string.parse_double(v) |> Ok catch {
        e => Err(e)
      }
      match v {
        Ok(value) => {
          let literal = LiteralRef::new_typed_literal(
            VarDataType::DecimalVar(value.to_string()),
            lwDECIMAL,
          )
          let new_cur_object = self.cur_object + [literal.as_term()]
          let new_self = { ..self, cur_object: new_cur_object }
          Ok((new_self, TriGState::ReifiedTripleObject(is_reified~), None))
        }
        Err(e) =>
          Err(RuleRecognizerError::SyntaxError(e.to_string(), self.last_range))
      }
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Double(v), _)
    ) => {
      let v = try @string.parse_double(v) |> Ok catch {
        e => Err(e)
      }
      match v {
        Ok(value) => {
          let literal = LiteralRef::new_typed_literal(
            VarDataType::DoubleVar(value.to_string()),
            lwDOUBLE,
          )
          let new_cur_object = self.cur_object + [literal.as_term()]
          let new_self = { ..self, cur_object: new_cur_object }
          Ok((new_self, TriGState::ReifiedTripleObject(is_reified~), None))
        }
        Err(e) =>
          Err(RuleRecognizerError::SyntaxError(e.to_string(), self.last_range))
      }
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword("true"), _)
    ) => {
      let literal = LiteralRef::new_typed_literal(
        VarDataType::TrueVar,
        lwBOOLEAN,
      )
      let new_cur_object = self.cur_object + [literal.as_term()]
      let new_self = { ..self, cur_object: new_cur_object }
      Ok((new_self, TriGState::ReifiedTripleObject(is_reified~), None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword("false"), _)
    ) => {
      let literal = LiteralRef::new_typed_literal(
        VarDataType::FalseVar,
        lwBOOLEAN,
      )
      let new_cur_object = self.cur_object + [literal.as_term()]
      let new_self = { ..self, cur_object: new_cur_object }
      Ok((new_self, TriGState::ReifiedTripleObject(is_reified~), None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("<<("), _)
    ) => {
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::ObjectReifiedTripleEnd(emit=false))
      new_stack.push(TriGState::ReifiedTripleObject(is_reified=false))
      new_stack.push(TriGState::Verb)
      new_stack.push(TriGState::ReifiedTripleSubject(is_reified=false))
      let new_self = { ..self, stack: new_stack }
      Ok((new_self, TriGState::ReifiedTripleSubject(is_reified=false), None))
    }
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("<<"), _)
    ) if is_reified => {
      let new_stack = self.stack.copy()
      new_stack.push(TriGState::ObjectReifiedTripleEnd(emit=false))
      new_stack.push(TriGState::EndOfReifiedTripleBeforeReifier)
      new_stack.push(TriGState::ReifiedTripleObject(is_reified=true))
      new_stack.push(TriGState::Verb)
      new_stack.push(TriGState::ReifiedTripleSubject(is_reified=true))
      let new_self = { ..self, stack: new_stack }
      Ok((new_self, TriGState::ReifiedTripleSubject(is_reified=true), None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "TOKEN is not a valid RDF quoted triple object",
          self.last_range,
        ),
      )
  }
}

// ===== QuotedAnonEnd 处理 =====

///|
fn TriGRecognizer::handle_quoted_anon_end_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("]"), _)
    ) => Ok((self, TriGState::QuotedAnonEnd, None))
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Anonymous blank node with a property list are not allowed in quoted triples",
          self.last_range,
        ),
      )
  }
}

// ===== ExpectAtKeyword 处理 =====

///|
fn TriGRecognizer::handle_expect_at_keyword_m(
  self : TriGRecognizer,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "base") =>
      Ok((self, TriGState::BaseExpectIri, None))
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "prefix") =>
      Ok((self, TriGState::PrefixExpectPrefix, None))
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword(k), _)
    ) if eq_ignore_ascii_case(k, "version") =>
      Ok((self, TriGState::VersionExpectVersion, None))
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("{"), _)
    ) if ctx.with_graph_name => Ok((self, TriGState::WrappedGraph, None))
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected 'base', 'prefix', or 'version' after '@'",
          self.last_range,
        ),
      )
  }
}

// ===== WrappedGraph 状态处理 '{' =====

///|
fn TriGRecognizer::handle_wrapped_graph_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  // WrappedGraph 由 { 进入,现在进入图内容
  // 期望收到三元组主语(IRI、blank node 等)或 {
  match event {
    // 收到 '{',开始图内容
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("{"), _)
    ) => {
      self.stack.push(TriGState::WrappedGraphPossibleEnd)
      self.stack.push(TriGState::Triples)
      Ok((self, TriGState::Triples, None))
    }
    // 收到 IRI 作为图内容的主语
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      self.cur_subject.push(NamedNodeRef::new_unchecked(iri).as_enum())
      self.stack.push(TriGState::WrappedGraphPossibleEnd)
      self.stack.push(TriGState::PredicateObjectList)
      Ok((self, TriGState::PredicateObjectList, None))
    }
    // 收到 BlankNode 作为图内容的主语
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::BlankNodeLabel(label), _)
    ) => {
      self.cur_subject.push(BlankNodeRef::new_unchecked(label).as_enum())
      self.stack.push(TriGState::WrappedGraphPossibleEnd)
      self.stack.push(TriGState::PredicateObjectList)
      Ok((self, TriGState::PredicateObjectList, None))
    }
    // 收到匿名图 [
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("["), _)
    ) => {
      self.stack.push(TriGState::WrappedGraphPossibleEnd)
      self.stack.push(TriGState::WrappedGraphBlankNodePropertyListCurrent)
      Ok((self, TriGState::WrappedGraphBlankNodePropertyListCurrent, None))
    }
    // 收到集合开始 (
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("("), _)
    ) => {
      self.stack.push(TriGState::WrappedGraphPossibleEnd)
      self.stack.push(TriGState::SubjectCollectionBeginning)
      Ok((self, TriGState::SubjectCollectionBeginning, None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected '{' or subject to start graph content",
          self.last_range,
        ),
      )
  }
}

// ===== handle_wrapped_graph_possible_end_m =====

///|
fn TriGRecognizer::handle_wrapped_graph_possible_end_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  match event {
    // ✅ 情况1:收到 `}` → 图结束
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("}"), _)
    ) => {
      self.debug_logger.info("WrappedGraphPossibleEnd: graph ended with '}'")

      // ✅ 弹出 WrappedGraphPossibleEnd

      // ✅ 返回 WrappedGraph,表示图已结束,可以回到上层
      Ok((self, TriGState::WrappedGraph, None))
    }

    // ✅ 情况2:收到 `.` → 还有更多三元组
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("."), _)
    ) => {
      self.debug_logger.info(
        "WrappedGraphPossibleEnd: dot, continuing graph content",
      )

      // ✅ 继续处理图内的三元组
      // 清空当前三元组的数据
      let new_self = {
        ..self,
        cur_subject: [],
        cur_predicate: [],
        cur_object: [],
        cur_reifier: [],
      }

      // ✅ 压入 Triples 状态,继续处理
      let new_stack = new_self.stack
      new_stack.push(TriGState::WrappedGraphPossibleEnd) // 保留结束状态
      new_stack.push(TriGState::Triples) // 继续处理三元组
      let new_self = { ..new_self, stack: new_stack }

      Ok((new_self, TriGState::Triples, None))
    }

    // ✅ 情况3:收到其他 token → 可能是错误,或者是新的三元组开始
    _ =>
      // 检查是否可能是新的三元组(主语)
      match event {
        LocatedTokenOrLineJump::LocatedN3Token(
          LocatedN3Token(N3Token::Iri(_), _)
        )
        | LocatedTokenOrLineJump::LocatedN3Token(
          LocatedN3Token(N3Token::BlankNodeLabel(_), _)
        )
        | LocatedTokenOrLineJump::LocatedN3Token(
          LocatedN3Token(N3Token::Punctuation("["), _)
        )
        | LocatedTokenOrLineJump::LocatedN3Token(
          LocatedN3Token(N3Token::Punctuation("("), _)
        ) => {
          // 可能是新的三元组开始
          self.debug_logger.info(
            "WrappedGraphPossibleEnd: new triple detected, continuing",
          )

          // 清空当前三元组数据
          let new_self = {
            ..self,
            cur_subject: [],
            cur_predicate: [],
            cur_object: [],
            cur_reifier: [],
          }

          // ✅ 压入 Triples 状态,让主语处理
          let new_stack = new_self.stack
          new_stack.push(TriGState::WrappedGraphPossibleEnd) // 保留结束状态
          new_stack.push(TriGState::Triples) // 处理新三元组
          let new_self = { ..new_self, stack: new_stack }

          // ✅ 返回 Triples 状态
          Ok((new_self, TriGState::Triples, None))
        }
        _ =>
          // ❌ 无效 token
          Err(
            RuleRecognizerError::SyntaxError(
              "Expected '}' or '.' or new triple in graph block",
              self.last_range,
            ),
          )
      }
  }
}

// ===== handle_object_reified_triple_end_m =====

///|
fn TriGRecognizer::handle_object_reified_triple_end_m(
  self : TriGRecognizer,
  emit : Bool,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info("ObjectReifiedTripleEnd: emit=\{emit}, event=\{event}")

  // ✅ 检查是否是结束标记 `>>`
  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation(">>"), _)
    ) => {
      // 1. 弹出引用三元组的三个部分
      // 注意:顺序是 subject, predicate, object
      // 它们在栈中的顺序:先压入 subject,再 predicate,最后 object

      let object = match self.cur_object.pop() {
        Some(o) => o
        None =>
          return Err(
            RuleRecognizerError::SyntaxError(
              "Internal error: object stack empty in reified triple",
              self.last_range,
            ),
          )
      }

      let predicate = match self.cur_predicate.pop() {
        Some(p) => p
        None =>
          // 如果 predicate 为空,可能是语法错误
          return Err(
            RuleRecognizerError::SyntaxError(
              "Internal error: predicate stack empty in reified triple",
              self.last_range,
            ),
          )
      }

      let subject = match self.cur_subject.pop() {
        Some(s) => s
        None =>
          return Err(
            RuleRecognizerError::SyntaxError(
              "Internal error: subject stack empty in reified triple",
              self.last_range,
            ),
          )
      }

      // 2. 构造 Triple 对象
      let triple = TripleRef::TripleRef(subject, predicate, object)

      // 3. 将 Triple 作为对象推入 cur_object
      let new_cur_object = self.cur_object + [TermRef::TripleRef(triple)]
      let new_self = { ..self, cur_object: new_cur_object }

      // 4. 如果 emit=true,输出三元组
      if emit {
        self.debug_logger.info("ObjectReifiedTripleEnd: emitting triple")

        // 注意:此时输出的三元组是外层的三元组
        // subject = cur_subject 栈顶(外层 subject)
        // predicate = cur_predicate 栈顶(外层 predicate)
        // object = triple (刚构造的引用三元组)
        let quad = new_self.emit_quad_m()

        // 5. 弹出 ObjectReifiedTripleEnd,进入 PredicateObjectListEnd
        // 注意:需要弹出当前状态
        let new_stack = new_self.stack
        let _ = new_stack.pop() // 弹出 ObjectReifiedTripleEnd
        let new_self = { ..new_self, stack: new_stack }

        Ok((new_self, TriGState::PredicateObjectListEnd, Some(quad)))
      } else {
        // ✅ 不输出(用于嵌套的引用三元组)
        self.debug_logger.info("ObjectReifiedTripleEnd: not emitting (nested)")

        // 弹出 ObjectReifiedTripleEnd
        let new_stack = new_self.stack
        let _ = new_stack.pop()
        let new_self = { ..new_self, stack: new_stack }

        Ok((new_self, TriGState::PredicateObjectListEnd, None))
      }
    }

    // ❌ 错误:期望 `>>`
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected '>>' to close reified triple",
          self.last_range,
        ),
      )
  }
}

// ===== handle_literal_possible_suffix_m =====

///|
fn TriGRecognizer::handle_literal_possible_suffix_m(
  self : TriGRecognizer,
  value : String,
  emit : Bool,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  self.debug_logger.info(
    "LiteralPossibleSuffix: value='\{value}', emit=\{emit}, event=\{event}",
  )

  match event {
    // ===== 情况1:语言标签 =====
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::LangTag(language~, direction~), _)
    ) => {
      self.debug_logger.info(
        "LiteralPossibleSuffix: language tag '@\{language}'",
      )

      // 创建语言标签字面量
      let literal = if direction is Some(dir) {
        // RDF 1.2 支持方向
        let lang_tag = try
          LanguageTag::from_str(language.to_lower()) |> Ok
        catch {
          e => Err(e)
        }
        let lang_tag = match lang_tag {
          Ok(lang_tag) => lang_tag
          Err(_e) => LanguageTag::default()
        }
        LiteralRef::new_directional_language_tagged_literal_unchecked(
          value, lang_tag, dir,
        )
      } else {
        // 普通语言标签
        let lang_tag = try
          LanguageTag::from_str(language.to_lower()) |> Ok
        catch {
          e => Err(e)
        }
        let lang_tag = match lang_tag {
          Ok(lang_tag) => lang_tag
          Err(_e) => LanguageTag::default()
        }
        LiteralRef::new_language_tagged_literal_unchecked(
          value,
          lang_tag.to_string(),
        )
      }

      // 推入 cur_object
      let new_cur_object = self.cur_object + [TermRef::LiteralRef(literal)]
      let new_self = { ..self, cur_object: new_cur_object }

      // 如果 emit=true,输出三元组
      if emit {
        self.debug_logger.info(
          "LiteralPossibleSuffix: emitting quad with language tag",
        )
        let quad = new_self.emit_quad_m()

        // 弹出 LiteralPossibleSuffix 状态
        let new_stack = new_self.stack
        let _ = new_stack.pop()
        let new_self = { ..new_self, stack: new_stack }

        Ok((new_self, TriGState::PredicateObjectListEnd, Some(quad)))
      } else {
        // 不输出(用于引用三元组内部)
        let new_stack = new_self.stack
        let _ = new_stack.pop()
        let new_self = { ..new_self, stack: new_stack }

        Ok((new_self, TriGState::PredicateObjectListEnd, None))
      }
    }

    // ===== 情况2:数据类型 =====
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("^^"), _)
    ) => {
      self.debug_logger.info("LiteralPossibleSuffix: datatype indicator '^^'")

      // ✅ 进入 LiteralExpectDatatype 状态等待数据类型
      // 注意:不消耗当前 token,让下一个状态处理
      Ok((self, TriGState::LiteralExpectDatatype(value~, emit~), None))
    }

    // ===== 情况3:无后缀(简单字面量) =====
    _ => {
      self.debug_logger.info("LiteralPossibleSuffix: no suffix, simple literal")

      // 创建简单字面量
      let literal = LiteralRef::new_simple_literal(value)
      let new_cur_object = self.cur_object + [TermRef::LiteralRef(literal)]
      let new_self = { ..self, cur_object: new_cur_object }

      // 如果 emit=true,输出三元组
      if emit {
        self.debug_logger.info(
          "LiteralPossibleSuffix: emitting quad (simple literal)",
        )
        let quad = new_self.emit_quad_m()

        // 弹出 LiteralPossibleSuffix 状态
        let new_stack = new_self.stack
        let _ = new_stack.pop()
        let new_self = { ..new_self, stack: new_stack }

        // ✅ 继续处理当前 token(可能是 '.' 或 ';' 或 ',')
        // 需要递归调用 recognize_next 处理同一个 token
        // 但这里我们返回 PredicateObjectListEnd,由引擎处理同一个 token
        Ok((new_self, TriGState::PredicateObjectListEnd, Some(quad)))
      } else {
        // 不输出
        let new_stack = new_self.stack
        let _ = new_stack.pop()
        let new_self = { ..new_self, stack: new_stack }

        Ok((new_self, TriGState::PredicateObjectListEnd, None))
      }
    }
  }
}

// ===== 简化版 =====

///|
fn TriGRecognizer::handle_object_blank_node_property_list_end_m(
  self : TriGRecognizer,
  event : Event,
  _context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  match event {
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("]"), _)
    ) => {
      // 弹出空白节点
      let subject = self.cur_subject.pop()
      // let subject= match subject  {
      //   Some(NamedOrBlankNodeRef::BlankNodeRef(b)) => b
      //   _ => return Err(RuleRecognizerError::SyntaxError("Expected blank node", self.last_range))
      //  }

      let blank_ref = match subject {
        Some(NamedOrBlankNodeRef::BlankNodeRef(b)) => b
        _ =>
          return Err(
            RuleRecognizerError::SyntaxError(
              "Expected blank node",
              self.last_range,
            ),
          )
      }

      // 推入 cur_object
      let new_cur_object = self.cur_object + [TermRef::BlankNodeRef(blank_ref)]
      let new_self = { ..self, cur_object: new_cur_object }

      // 输出
      let quad = new_self.emit_quad_m()

      // 弹出当前状态
      let new_stack = new_self.stack
      let _ = new_stack.pop()
      let new_self = { ..new_self, stack: new_stack }

      Ok((new_self, TriGState::PredicateObjectListEnd, Some(quad)))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected ']' to close blank node property list",
          self.last_range,
        ),
      )
  }
}

///|
/// 状态: PredicateObjectList - 处理谓词对象列表
fn TriGRecognizer::handle_predicate_object_list_m(
  self : TriGRecognizer,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  self.debug_logger.info("PredicateObjectList: handling event: \{event}")
  self.debug_logger.info("Token stack: \{@debug.to_string(self.stack)}")

  match event {
    // ✅ 处理 'a' 作为 rdf:type
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword("a"), _)
    ) => {
      let new_self = self
      new_self.cur_predicate.push(lwTYPE)
      // 保持在 PredicateObjectList,准备处理 Object
      Ok((new_self, TriGState::Object, None))
    }

    // ✅ 处理 IRI 作为 predicate
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      let new_self = self
      new_self.cur_predicate.push(NamedNodeRef::new_unchecked(iri))
      Ok((new_self, TriGState::Object, None))
    }

    // ✅ 处理 PrefixedName 作为 predicate
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          let new_self = self
          new_self.cur_predicate.push(t)
          Ok((new_self, TriGState::Object, None))
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }

    // ✅ 处理 '}' 图结束
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("}"), _)
    ) => {
      // 图结束,返回 TriGDoc
      let new_self = { ..self, stack: [TriGState::TriGDoc] }
      Ok((new_self, TriGState::TriGDoc, None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected predicate or '}' in predicate-object list",
          self.last_range,
        ),
      )
  }
}

///|
/// 状态: PredicateObjectListPossibleContinuation - 谓词列表分号后等待新谓词
fn TriGRecognizer::handle_predicate_object_list_possible_continuation_m(
  self : TriGRecognizer,
  event : Event,
  context : RdfContext,
) -> TransitionResult[TriGRecognizer, TriGState, RdfOut] {
  let ctx = match context {
    RdfContext::TriGRecognizerContext(c) => c
    _ =>
      return Err(
        RuleRecognizerError::SyntaxError("Invalid context", self.last_range),
      )
  }

  match event {
    // ✅ 处理 'a' 作为 rdf:type
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::PlainKeyword("a"), _)
    ) => {
      let new_self = self
      new_self.cur_predicate.push(lwTYPE)
      Ok((new_self, TriGState::Object, None))
    }

    // ✅ 处理 IRI 作为 predicate
    LocatedTokenOrLineJump::LocatedN3Token(LocatedN3Token(N3Token::Iri(iri), _)) => {
      let new_self = self
      new_self.cur_predicate.push(NamedNodeRef::new_unchecked(iri))
      Ok((new_self, TriGState::Object, None))
    }

    // ✅ 处理 PrefixedName 作为 predicate
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(
        N3Token::PrefixedName(prefix~, localx~, might_be_invalid_iri~),
        _
      )
    ) =>
      match
        resolve_local_name(prefix, localx, might_be_invalid_iri, ctx.prefixes) {
        Ok(t) => {
          let new_self = self
          new_self.cur_predicate.push(t)
          Ok((new_self, TriGState::Object, None))
        }
        Err(e) => Err(RuleRecognizerError::SyntaxError(e, self.last_range))
      }

    // ✅ 处理 } 图结束
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("}"), _)
    ) => {
      let new_self = { ..self, stack: [TriGState::TriGDoc] }
      Ok((new_self, TriGState::TriGDoc, None))
    }

    // ✅ 处理 . 结束语句
    LocatedTokenOrLineJump::LocatedN3Token(
      LocatedN3Token(N3Token::Punctuation("."), _)
    ) => {
      let new_self = {
        ..self,
        stack: [TriGState::TriGDoc],
        cur_subject: [],
        cur_predicate: [],
        cur_object: [],
      }
      Ok((new_self, TriGState::TriGDoc, None))
    }
    _ =>
      Err(
        RuleRecognizerError::SyntaxError(
          "Expected predicate, '.', or '}' after ';'",
          self.last_range,
        ),
      )
  }
}