Я расплатился с 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
за +
, так далее.
Почему эти «инструкции» выше не рассматриваются как токены?
Поскольку они представляют собой одинарные символы, они уже являются конечными символами. Не нужно делать из этого токен. Вы можете найти список доступных токенов парсера здесь: 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 (Ух ты, они сделали книгу общедоступной!)
Других решений пока нет …