code: def lexicon_to_fst_nosil(
      lexicon: Lexicon,
      token2id: Dict[str, int],
      word2id: Dict[str, int],
      need_self_loops: bool = False,
  ):
      start_state = 0
      next_state = 1
      arcs = []
  
      assert token2id["<eps>"] == 0
      assert word2id["<eps>"] == 0
  
      eps = 0
  
      for word, tokens in lexicon:
          assert len(tokens) > 0, f"{word} has no pronunciations"
          cur_state = start_state
  
          word = word2id[word]
          tokens = [token2id[i] for i in tokens]
  
          for i in range(len(tokens) - 1):
              w = word if i == 0 else eps
              arcs.append([cur_state, next_state, tokens[i], w, 0])
  
              cur_state = next_state
              next_state += 1
  
          i = len(tokens) - 1
          w = word if i == 0 else eps
          arcs.append([cur_state, start_state, tokens[i], w, 0])
  
      if need_self_loops:
          disambig_token = token2id["#0"]
          disambig_word = word2id["#0"]
          arcs = add_self_loops(
              arcs,
              disambig_token=disambig_token,
              disambig_word=disambig_word,
          )
  
      final_state = next_state
      arcs.append([start_state, final_state, -1, -1, 0])
      arcs.append([final_state])
  
      arcs = sorted(arcs, key=lambda arcs: arcs[0])
      arcs = [[str(i) for i in arc] for arc in arcs]
      arcs = [" ".join(arc) for arc in arcs]
      arcs = "\n".join(arcs)
  
      fsa = k2.Fsa.from_str(arcs, acceptor=False)
      return fsa
  
file_path: espnet/egs2/aishell4/enh1/pyscripts/k2/prepare_lang.py
imports: import argparse
  import math
  from collections import defaultdict
  from pathlib import Path
  from typing import Any, Dict, List, Tuple
  import k2
  import torch
  from icefall.lexicon import read_lexicon, write_lexicon
  from espnet2.utils.types import str2bool
label_desc: Use image node_id 8 for calling a global function with example usage: lexicon_to_fst_nosil(lexicon, token2id, word2id, need__loops) and returns: fsa