Как определить данные, которые не соответствуют шаблону - PullRequest
0 голосов
/ 01 февраля 2019

Итак, я использую класс matcher и использую его для идентификации токенов, которые я определил в перечислении.

  public static enum TokenType {
    // Definitions of accepted tokens
     IF("if"), WHILE("while"), PRINT("print"), TYPE("int|string|boolean"), BOOLOP("==|!="), BOOLVAL("false|true"), INTOP("[+]"), CHAR("[a-z]"), DIGIT("[0-9]"), WHITESPACE("[ \t\f\r\n]+"), LPAREN("[(]"), RPAREN("[)]");
    public final String pattern;

    private TokenType(String pattern) {
      this.pattern = pattern;
    }
  }

  public static class Token {
    public TokenType type;
    public String data;

Моя проблема в том, что мне также нужно идентифицировать все, что не определено в моем шаблоне, и напечатать ошибку, когда это происходит.

Так выглядит моя логика сопоставления

    // Begin matching tokens
    Matcher matcher = tokenPatterns.matcher(input);
      while (matcher.find()) {
        if (matcher.group(TokenType.DIGIT.name()) != null) {
          tokens.add(new Token(TokenType.DIGIT, matcher.group(TokenType.DIGIT.name())));
          continue;
      } else if (matcher.group(TokenType.IF.name()) != null) {
          tokens.add(new Token(TokenType.IF, matcher.group(TokenType.IF.name())));
          continue;
      } else if (matcher.group(TokenType.WHILE.name()) != null) {
          tokens.add(new Token(TokenType.WHILE, matcher.group(TokenType.WHILE.name())));
          continue;
      } else if (matcher.group(TokenType.TYPE.name()) != null) {
          tokens.add(new Token(TokenType.TYPE, matcher.group(TokenType.TYPE.name())));
          continue;
      } else if (matcher.group(TokenType.PRINT.name()) != null) {
          tokens.add(new Token(TokenType.PRINT, matcher.group(TokenType.PRINT.name())));
          continue;
      } else if (matcher.group(TokenType.BOOLOP.name()) != null) {
          tokens.add(new Token(TokenType.BOOLOP, matcher.group(TokenType.BOOLOP.name())));
          continue;
      } else if (matcher.group(TokenType.BOOLVAL.name()) != null) {
          tokens.add(new Token(TokenType.BOOLVAL, matcher.group(TokenType.BOOLVAL.name())));
          continue;
      } else if (matcher.group(TokenType.INTOP.name()) != null) {
          tokens.add(new Token(TokenType.INTOP, matcher.group(TokenType.INTOP.name())));
          continue;
      } else if (matcher.group(TokenType.CHAR.name()) != null) {
        tokens.add(new Token(TokenType.CHAR, matcher.group(TokenType.CHAR.name())));
        continue;
      } else if (matcher.group(TokenType.LPAREN.name()) != null) {
          tokens.add(new Token(TokenType.LPAREN, matcher.group(TokenType.LPAREN.name())));
          continue;
      } else if (matcher.group(TokenType.RPAREN.name()) != null) {
          tokens.add(new Token(TokenType.RPAREN, matcher.group(TokenType.RPAREN.name())));
          continue;  
      } else if (matcher.group(TokenType.WHITESPACE.name()) != null) {
          continue; 
      }
    }

    return tokens;
  }

Возможным решением было бы добавить к моему шаблону регистр, который учитывает все, что еще не было определено, что будет выглядеть примерно так: WHITESPACE ("[\ t \ f \ r \ n]+ "), LPAREN (" [(] "), ОШИБКА (" @ | #, $,%, ^, & ..... ") , но я не уверен в каком-либо реалистичном способе реализациичто.

Спасибо за любую помощь. Вот ссылка на полный код на случай, если я что-то пропустил - https://pastebin.com/jLtnJwgj

1 Ответ

0 голосов
/ 01 февраля 2019

Вы пробуете что-то подобное?

public class Lexer {

public static enum TokenType {
    // Definitions of accepted tokens
    IF("if"),
    WHILE("while"),
    PRINT("print"),
    TYPE("int|string|boolean"),
    BOOLOP("==|!="),
    BOOLVAL("false|true"),
    INTOP("[+]"),
    CHAR("[a-z]"),
    DIGIT("[0-9]"),
    WHITESPACE("[ \t\f\r\n]+"),
    LPAREN("[(]"),
    RPAREN("[)]"),
    OTHER(".");
    public final String pattern;

    private TokenType(final String pattern) {
        this.pattern = pattern;
    }
}

public static class Token {
    public TokenType type;
    public String data;

    public Token(final TokenType type, final String data) {
        this.type = type;
        this.data = data;
    }
}

public static ArrayList<Token> lex(final String input) {
    // The tokens to return
    final ArrayList<Token> tokens = new ArrayList<Token>();

    // allows us to work with a mutable string
    final StringBuffer tokenPatternsBuffer = new StringBuffer();

    for (final TokenType tokenType : TokenType.values()) {
        tokenPatternsBuffer.append(String.format("|(?<%s>%s)",
                tokenType.name(), tokenType.pattern));
    }
    final Pattern tokenPatterns = Pattern.compile(
            new String(tokenPatternsBuffer.substring(1)));

    // Begin matching tokens
    String other = "";
    final Matcher matcher = tokenPatterns.matcher(input);
    while (matcher.find()) {
        if (matcher.group(TokenType.DIGIT.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.DIGIT,
                    matcher.group(TokenType.DIGIT.name())));
            continue;
        } else if (matcher.group(TokenType.IF.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.IF,
                    matcher.group(TokenType.IF.name())));
            continue;
        } else if (matcher.group(TokenType.WHILE.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.WHILE,
                    matcher.group(TokenType.WHILE.name())));
            continue;
        } else if (matcher.group(TokenType.TYPE.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.TYPE,
                    matcher.group(TokenType.TYPE.name())));
            continue;
        } else if (matcher.group(TokenType.PRINT.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.PRINT,
                    matcher.group(TokenType.PRINT.name())));
            continue;
        } else if (matcher.group(TokenType.BOOLOP.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.BOOLOP,
                    matcher.group(TokenType.BOOLOP.name())));
            continue;
        } else if (matcher.group(TokenType.BOOLVAL.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.BOOLVAL,
                    matcher.group(TokenType.BOOLVAL.name())));
            continue;
        } else if (matcher.group(TokenType.INTOP.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.INTOP,
                    matcher.group(TokenType.INTOP.name())));
            continue;
        } else if (matcher.group(TokenType.CHAR.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.CHAR,
                    matcher.group(TokenType.CHAR.name())));
            continue;
        } else if (matcher.group(TokenType.LPAREN.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.LPAREN,
                    matcher.group(TokenType.LPAREN.name())));
            continue;
        } else if (matcher.group(TokenType.RPAREN.name()) != null) {
            other = unknow(tokens, other);
            tokens.add(new Token(TokenType.RPAREN,
                    matcher.group(TokenType.RPAREN.name())));
            continue;
        } else if (matcher.group(TokenType.WHITESPACE.name()) != null) {
            continue;
        } else if (matcher.group(TokenType.OTHER.name()) != null) {
            other += matcher.group(TokenType.OTHER.name());
            continue;
        }
    }
    other = unknow(tokens, other);
    return tokens;
}

private static String unknow(final ArrayList<Token> tokens, final String _unknow) {
    if (!_unknow.isEmpty()) {
        tokens.add(new Token(TokenType.OTHER,_unknow));
    }
    return "";
}

public static void main(final String[] args) {
    final String input = "if\nprint\nta!?!?!taelse?§.?toto";
    // Create tokens and print them
    final ArrayList<Token> tokens = lex(input);
    for (final Token token : tokens)
        System.out.println("DEBUG Lexer - " + token.type + " [ "
                + token.data + " ] " + "found at " + "linenumber");
}

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...