2016-05-17 4 views
0

Я хотел бы сделать очень простой лексический анализатор, но я немного застрял. Допустим, у меня есть только две арифметические операции (сложение и умножение) и два целых числа. Добавление или умножение производится с двумя операндами (порядок не имеет значения, так как это добавление или умножение). Например, как вход "ADD 4 8", ожидается 4 + 8. Ниже приводится то, что я сделал до сих пор. Я могу извлечь операнды, но любопытно, что не оператор "+" или "*". Как я уже сказал, я действительно не знаю, как идти вперед, и выполнить простой add или mul.Thanks для вашей помощи.Базовый лексический анализатор для добавления и умножения в Java

private static enum Type { 
    ADD, MUL, OPERAND 
} 

private static class Token<TokenType, TokenValue> { 
    private final TokenType type; 
    private final TokenValue value; 

    public Token(TokenType t, TokenValue value) { 
     this.type = t; 
     this.value = value; 
    } 

    public String toString() { 
     return "Token value: " + this.value + "\n" + "Token type: " + this.type; 
    } 
} 

private static String getOperand(String operand, int index) { 

    int i = index; 
    while (i < operand.length()) { 
     if (Character.isDigit(operand.charAt(i))) { 
      i++; 
     } else { 
      return operand.substring(index, i); 
     } 
    } 
    return operand.substring(index, i); 
} 

private static ArrayList<Token<Type, String>> lex(String expression) { 

    ArrayList<Token<Type, String>> tokens = new ArrayList<>(); 

    for (int i = 0; i < expression.length(); i++) { 
     char currChar = expression.charAt(i); 

     switch (currChar) { 
     case '+': 
      tokens.add(new Token<>(Type.ADD, String.valueOf(currChar))); 
      i++; 
      break; 

     case '*': 
      tokens.add(new Token<>(Type.MUL, String.valueOf(currChar))); 
      i++; 
      break; 

     default: 
      if (Character.isWhitespace(currChar)) { 
       i++; 
      } else { 
       String operand = getOperand(expression, i); 
       i += operand.length(); 
       tokens.add(new Token<>(Type.OPERAND, operand)); 
      } 
      break; 
     } 
    } 
    return tokens; 
} 

public static void main(String[] args) { 

    Scanner scan = new Scanner(System.in); 
    System.out.println("Please enter an expression: "); 
    String input = scan.nextLine(); 

    ArrayList<Token<Type, String>> tokens = lex(input); 
    for (Token token : tokens) { 
     System.out.println(token); 
    } 
} 

Пример ввод: "5+1" выхода:

Token value: 5 
Token type: OPERAND 
Token value: 1 
Token type: OPERAND 
+0

Что вы вводите? Каков ваш ожидаемый результат? Каков наблюдаемый результат? В общем, если вы планируете анализировать более сложные выражения, вы можете запрограммировать свой алгоритм рекурсивным образом. – Turing85

+0

Я отредактировал вход и выход. По крайней мере, я ожидал, что знак «+» будет распознан как токен ADD, но это не так. Следующий шаг - выполнить добавление, но я еще не справился. – loukios

+0

Это не проблема только лексического анализа. Вам нужен синтаксический анализатор, а также лексический анализатор. Посмотрите на «рекурсивный синтаксический анализатор спуска» или алгоритм Дейкстра Шунтинга. – EJP

ответ

0

В методе lex(), вы приращение позиции символа дополнительное время для каждых маркеров. Вы добавляете токен после добавления токена, но есть и приращение цикла for.

Например, если ваш вход «5 + 1», в качестве OPERAND добавляется «5», позиция обновляется соответствующим образом, тогда цикл for пропускает «+», а следующий символ «1», который добавляется как другой операнд.

+0

Спасибо! Я не обратил на это внимания. Теперь я замечаю, что последний токен «1» в примере не учитывается, можете ли вы понять, почему? – loukios

+0

@loukios No. Я взял код в вашем вопросе в настоящее время, изменил 'for (int i = 0; i <выражение.length(); i ++) {' to 'for (int i = 0; i erickson

 Смежные вопросы

  • Нет связанных вопросов^_^