我正在用 PHP 构建一个基本的词法分析器,就像一个练习一样。现在我正在使它成为 lex PHP 源代码并通过 HTML 标记输出突出显示的源代码,但我使用的是真正的令牌名称和东西,而不仅仅是一些广泛的正则表达式匹配。
我设置它的方式是逐个字符地读取 PHP 源代码。它检查当前字符以确定当前标记可能是什么,然后读入与适当模式匹配的下一个x字符。
例如,如果当前字符是“,我将读入所有字符,直到遇到另一个前面没有转义 \ 的“。这是一种不好的做法吗?我见过并理解的唯一另一种方法是制作一个编译大量正则表达式并同时匹配所有标记的类,但这对我来说似乎并不灵活。
想法?
$str = '';
$php = str_replace( "\r\n", "\n", $php );
$php = str_split( $php );
$len = count( $php );
$keyword = '';
for ( $i = 0; $i < $len; $i++ ) {
$char = $php[$i];
// Detect PHP strings and backtick execution operators
if ( strpos( self::STRING_CHARACTERS, $char ) !== FALSE ) {
$string = $char;
$opening_quote = $char;
$escaped = FALSE;
while ( isset( $php[++$i] ) && ( $escaped || $php[$i] != $opening_quote ) ) {
$string .= $php[$i];
if ( $php[$i] == '\\' ) {
$escaped = !$escaped;
}
}
$string .= $php[$i];
if ( $opening_quote == "'" ) {
$str .= '<span class="php-string php-single-quoted-string">' . htmlspecialchars( $string ) . '</span>';
} else if ( $opening_quote == '"' ) {
$str .= '<span class="php-string php-double-quoted-string">' . htmlspecialchars( $string ) . '</span>';
} else if ( $opening_quote == '`' ) {
$str .= '<span class="php-execution-operator php-backtick">' . htmlspecialchars( $string ) . '</span>';
}
continue;
}
$str .= $char;
}