token_get_all и математические операторы

1

Я снова заплатил token_get_all() и наткнулся на что-то "специальное":

Учитывая следующую строку кода PHP:

<?php $var = 3 * 2 + 5;

когда я использую token_get_all() я получаю массив токенов:

array(15) {
  [0]=>
  array(3) {
    [0]=>
    int(376)
    [1]=>
    string(6) "<?php "
    [2]=>
    int(1)
  }
  [1]=>
  array(3) {
    [0]=>
    int(312)
    [1]=>
    string(4) "$var"
    [2]=>
    int(1)
  }
  [2]=>
  array(3) {
    [0]=>
    int(379)
    [1]=>
    string(1) " "
    [2]=>
    int(1)
  }
  [3]=>
  string(1) "="
  [4]=>
  array(3) {
    [0]=>
    int(379)
    [1]=>
    string(1) " "
    [2]=>
    int(1)
  }
  [5]=>
  array(3) {
    [0]=>
    int(308)
    [1]=>
    string(1) "3"
    [2]=>
    int(1)
  }
  [6]=>
  array(3) {
    [0]=>
    int(379)
    [1]=>
    string(1) " "
    [2]=>
    int(1)
  }
  [7]=>
  string(1) "*"
  [8]=>
  array(3) {
    [0]=>
    int(379)
    [1]=>
    string(1) " "
    [2]=>
    int(1)
  }
  [9]=>
  array(3) {
    [0]=>
    int(308)
    [1]=>
    string(1) "2"
    [2]=>
    int(1)
  }
  [10]=>
  array(3) {
    [0]=>
    int(379)
    [1]=>
    string(1) " "
    [2]=>
    int(1)
  }
  [11]=>
  string(1) "+"
  [12]=>
  array(3) {
    [0]=>
    int(379)
    [1]=>
    string(1) " "
    [2]=>
    int(1)
  }
  [13]=>
  array(3) {
    [0]=>
    int(308)
    [1]=>
    string(1) "5"
    [2]=>
    int(1)
  }
  [14]=>
  string(1) ";"
}

Обратите внимание, что математические операторы (=, *, +) и точка с запятой (;) не являются токенами, а просто строками. Я ожидал получить что-то вроде T_MATH_ADDITION для + и т.д.

Почему эти "инструкции" выше не обрабатываются как токены?

Теги:
token
lexer
tokenize

1 ответ

1
Лучший ответ

Поскольку они являются одиночными символами, они уже являются терминальными символами. Не нужно делать токен из него. Список доступных токенов синтаксического анализа можно найти здесь: http://php.net/manual/en/tokens.php

Посмотрите на (псевдо) грамматику:

# Using a token
product := T_NUMBER T_MULT_OPERATOR T_NUMBER

# Using the plain char
product := T_NUMBER '*' T_NUMBER

Что выглядит лучше? ;)

Я предлагаю выкопать в Flex и Bison и написать небольшой парсер самостоятельно. Тогда все станет понятнее. Начните здесь: http://web.iitd.ac.in/~sumeet/flex__bison.pdf (Вау, они сделали книгу открытой!)

  • 0
    Отлично. Спасибо за ваше объяснение. Я определенно загляну в книгу :-).
  • 0
    Веселитесь с этим! :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню