protected RegexTokenParser rule(Rule r, RBNF rbnf) {
    String ruleId = r.getId().getMatchedText();
    if (ruleId == null) return null;
    if (ruleId.length() < 1) return null;
    if (ruleId.startsWith("_")) return null;

    TreeNode e = r.getExpression();
    String s = expression(e, rbnf);
    if (s != null) {
      s = "^(?us)(" + s + ").*";
      return new RegexTokenParser(r.getId().getMatchedText(), s, 1);
    }
    return null;
  }
  protected String id(Identifier id, RBNF rbnf) {
    String sid = id.getMatchedText();
    if (sid != null) {
      Rule r = rbnf.getRuleById(sid);
      if (r != null) {
        TreeNode ex = r.getExpression();
        if (ex != null) {
          String s = expression(ex, rbnf);
          return s;
        }
      }

      if (sid.equals("any")) return ".";
      if (sid.equals("letter")) return "\\p{Alpha}";
      if (sid.equals("digit")) return "\\p{Digit}";
      if (sid.equals("endl")) return "\\r?\\n";
      if (sid.equals("ws")) return "\\s";
    }
    return null;
  }