krak/lex

功能词法分析库

v1.0.0 2020-05-30 20:16 UTC

This package is auto-updated.

Last update: 2024-08-29 04:31:04 UTC


README

Lex 是一个用于 PHP 的词法分析库。目前只提供简单的正则表达式词法分析器;但考虑到你不应该在 PHP 中进行复杂的词法分析,这应该足够了 :).

安装

composer require krak/lex

使用

<?php

require_once __DIR__ . '/vendor/autoload.php';

use function Krak\Lex\lexer,
    Krak\Lex\skipLexer;

const TOK_INT = 'int';
const TOK_PLUS = 'plus';
const TOK_MINUS = 'minus';
const TOK_WS = 'whitespace';

// creates a lexer that will use these RE's to match input
// the A (anchor flag) is required
$lex = lexer([
    '/\d+/A' => TOK_INT,
    '/\+/A' => TOK_PLUS,
    '/\-/A' => TOK_MINUS,
    '/\s+/A' => TOK_WS
]);

// decorator for skipping tokens, in this case, just throw away the whitespace tokens
$lex = skipLexer($lex, [TOK_WS]);

// lex the input and return an iterator of tokens
$toks = $lex('1 + 2 - 3');

foreach ($toks as $matched_tok) {
    printf(
        "Matched token '%s' with input '%s' at offset %d\n",
        $matched_tok->token,
        $matched_tok->match,
        $matched_tok->offset
    );
}

以下程序会输出

Matched token 'int' with input '1' at offset 0
Matched token 'plus' with input '+' at offset 2
Matched token 'int' with input '2' at offset 4
Matched token 'minus' with input '-' at offset 6
Matched token 'int' with input '3' at offset 8

TokenStream

TokenStream 是一个简单接口,一次消费一个标记。这对于 递归下降解析器 非常有用

<?php

use function Krak\Lex\lexer,
    Krak\Lex\tokenStreamLexer;

$lex = lexer(['/a/A' => 'a', '/b/A' => 'b']);
$lex = tokenStreamLexer($lex);
$stream = $lex('aba');

assert($stream->peek() == 'a');
assert($stream->getToken() == 'a');
assert($stream->getToken() == 'b');
assert($stream->getToken() == 'a');
assert($stream->isEmpty());

API

词法分析器

每个词法分析器都将接受一个字符串输入,然后返回一个 MatchedToken 可迭代的对象。

lexer($token_map, $throw = true)

主词法分析器,根据 $token_map 分析字符串。$throw 决定了词法分析器在遇到无法识别的输入时是否抛出异常。

skipLexer($lex, $tokens)

词法分析器装饰器,将跳过在 $tokens 传入的集合中的任何匹配标记。

tokenStreamLexer($lex)

词法分析器装饰器,将 $lex 的输出转换为 TokenStream

mockLexer($tokens)

返回 $tokens 本身。

class MatchedToken

$match

返回匹配的文本。

$token

返回匹配的标记名称。

$offset

返回匹配开始的字符串偏移量。

interface TokenStream extends \IteratorAggregate

getToken()

返回当前标记并使内部指针上移一位。

peek()

返回当前标记但不移动内部指针。

isEmpty()

如果标记流为空则返回 true,否则返回 false。