Я снова заплатил 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 (Вау, они сделали книгу открытой!)