/**
   * Reads a string and puts it in a list of integers
   *
   * @param result the list of integers that contains the read string
   * @param name the name of the current node
   * @throws javax.xml.stream.XMLStreamException
   */
  private void readString(List<Integer> result, String name) throws XMLStreamException {
    if (reader.getEventType() == XMLStreamConstants.CHARACTERS) {
      int start = reader.getTextStart();
      int length = reader.getTextLength();
      String value = new String(reader.getTextCharacters(), start, length);
      for (int i = 0; i < value.length(); i++) {
        result.add((int) value.charAt(i));
      }
      // System.err.println("value = " + value);
    } else if (reader.getEventType() == XMLStreamConstants.START_ELEMENT) {
      if (name.equals(COMPILER_BLANK_ELEM)) {
        requireEmptyError(name);
        result.add((int) (' '));
      } else if (name.equals(COMPILER_JOIN_ELEM)) {
        requireEmptyError(name);
        result.add((int) '+');
      } else if (name.equals(COMPILER_POSTGENERATOR_ELEM)) {
        requireEmptyError(name);
        result.add((int) '~');
      } else if (name.equals(COMPILER_GROUP_ELEM)) {
        int type = reader.getEventType();
        if (type != XMLStreamConstants.END_ELEMENT) {
          result.add((int) '#');
        }
      } else if (name.equals(COMPILER_S_ELEM)) {
        requireEmptyError(name);
        String symbol = "<" + attrib(COMPILER_N_ATTR) + ">";
        if (!alphabet.isSymbolDefined(symbol)) {
          throw new RuntimeException(
              "Error ("
                  + reader.getLocation().getLineNumber()
                  + ","
                  + reader.getLocation().getColumnNumber()
                  + "): Undefined symbol '"
                  + symbol
                  + "'.");
        }
        result.add(alphabet.cast(symbol));
      } else {
        throw new RuntimeException(
            "Error ("
                + reader.getLocation().getLineNumber()
                + "): Invalid specification of element '<"
                + name
                + ">' in this context.");
      }
    } else if (reader.getEventType() == XMLStreamConstants.END_ELEMENT) {
      if (name.equals(COMPILER_BLANK_ELEM)) {
      } else if (name.equals(COMPILER_JOIN_ELEM)) {
      } else if (name.equals(COMPILER_POSTGENERATOR_ELEM)) {
      } else if (name.equals(COMPILER_GROUP_ELEM)) {
      } else {
        throw new RuntimeException(
            "Error ("
                + reader.getLocation().getLineNumber()
                + ","
                + reader.getLocation().getColumnNumber()
                + "): unexpected event type '"
                + XMLPrint.getEventTypeString(reader.getEventType())
                + "'.");
      }
    } else {
      throw new RuntimeException(
          "Error ("
              + reader.getLocation().getLineNumber()
              + ","
              + reader.getLocation().getColumnNumber()
              + "): unexpected event type '"
              + XMLPrint.getEventTypeString(reader.getEventType())
              + "'.");
    }

    // System.err.println("result = " + result);
  }
  /**
   * Construct symbol pairs by align leftSide side of both parts and insert them into a transducer
   *
   * @param pi leftSide part of the transduction
   * @param pd right part of the transduction
   * @param state the state from wich insert the new transduction
   * @param t the transducer
   * @return the last state of the inserted transduction
   */
  int matchTransduction(ArrayList<Integer> pi, ArrayList<Integer> pd, int state, TransducerComp t) {
    int izqda, dcha, limizqda, limdcha;
    if (direction.equals(COMPILER_RESTRICTION_LR_VAL)) {
      izqda = 0;
      dcha = 0;
      limizqda = pi.size();
      limdcha = pd.size();

      if (pi.size() == 0 && pd.size() == 0) {
        if (DEBUG) System.err.println("e = " + t.toString());
        state = t.insertNewSingleTransduction(alphabet_cast00, state);
      } else {
        HashSet<Integer> acx_map_ptr = null;
        int rsymbol = 0;

        while (true) {
          int etiqueta;
          if (izqda == limizqda && dcha == limdcha) {
            break;
          } else if (izqda == limizqda) {
            etiqueta = alphabet.cast(0, pd.get(dcha));
            dcha++;
          } else if (dcha == limdcha) {
            Integer pi_izqda = pi.get(izqda);
            etiqueta = alphabet.cast(pi_izqda, 0);
            acx_map_ptr = acx_map.get(pi_izqda); // perhaps null
            rsymbol = 0;
            izqda++;
          } else {
            Integer pi_izqda = pi.get(izqda);
            Integer pd_dcha = pd.get(dcha);
            etiqueta = alphabet.cast(pi_izqda, pd_dcha);
            acx_map_ptr = acx_map.get(pi_izqda); // perhaps null
            rsymbol = pd_dcha;
            izqda++;
            dcha++;
          }

          int nuevo_estado = t.insertSingleTransduction(etiqueta, state);
          if (acx_map_ptr != null) {
            for (Integer integer : acx_map_ptr) {
              t.linkStates(state, nuevo_estado, alphabet.cast(integer, rsymbol));
            }
          }
          state = nuevo_estado;
        }
      }
      return state;

    } else {
      izqda = 0;
      dcha = 0;
      limizqda = pd.size();
      limdcha = pi.size();

      if (pi.size() == 0 && pd.size() == 0) {
        state = t.insertNewSingleTransduction(alphabet_cast00, state);
      } else {
        HashSet<Integer> acx_map_ptr = null;
        int rsymbol = 0;

        while (true) {
          int etiqueta;
          if (izqda == limizqda && dcha == limdcha) {
            break;
          } else if (izqda == limizqda) {
            etiqueta = alphabet.cast(0, pi.get(dcha));
            dcha++;
          } else if (dcha == limdcha) {
            Integer pd_izqda = pd.get(izqda);
            etiqueta = alphabet.cast(pd_izqda, 0);
            acx_map_ptr = acx_map.get(pd_izqda); // perhaps null
            rsymbol = 0;
            izqda++;
          } else {
            Integer pd_izqda = pd.get(izqda);
            Integer pi_dcha = pi.get(dcha);
            etiqueta = alphabet.cast(pd_izqda, pi_dcha);
            acx_map_ptr = acx_map.get(pd_izqda); // perhaps null
            rsymbol = pi_dcha;
            izqda++;
            dcha++;
          }

          int nuevo_estado = t.insertSingleTransduction(etiqueta, state);
          if (acx_map_ptr != null) {
            for (Integer integer : acx_map_ptr) {
              t.linkStates(state, nuevo_estado, alphabet.cast(integer, rsymbol));
            }
          }
          state = nuevo_estado;
        }
      }
      return state;
    }
  }
 /** Parse the <sdef> elements */
 private void procSDef() {
   if (reader.getEventType() != XMLStreamConstants.END_ELEMENT) {
     alphabet.includeSymbol("<" + attrib(COMPILER_N_ATTR) + ">");
   }
 }
 /** The constructor */
 public Compile() {
   alphabet = new CompileAlphabet();
   alphabet_cast00 = alphabet.cast(0, 0);
   // LtLocale.tryToSetLocale();
 }