编译原理:词法分析PHP代码实现

作者: Zeker62
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=drive-width,initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="login.css">
    <style>
        body {
            background: url('backiee-210221.jpg');
            background-repeat: no-repeat;
            background-size: 100% auto;
        }

        code {
            width: 30%;
            height: auto;
            margin: 0 auto;
            margin-top: 15%;
            text-align: center;
            background: 00000060;
            padding: 20px 50px;
        }

        code h1 {
            color: fff;
        }

        code .form .item input {
            margin-top: 25px;
        }

        code .form i {
            font-size: 18px;
            color: rgb(180, 155, 155);
        }

        code .form .item input {
            width: 180px;
            font-size: 20px;
            border: 0;
            border-bottom: 2px solidfff;
            padding: 5px 10px;
            background: ffffff00;
            color: fff;
        }

        .b {
            width: 300px;
            height: 200px;
            font-size: 20px;
            font-weight: 200;
            background: hsla(0, 0%, 100%, 0);
            color: aliceblue;
        }
    </style>
    <title>卷起来</title>
</head>
<body>
    <div id="code">
        <form method="post" action="WordAnalysis.php">
            <h1>词法分析测试界面</h1>
            <div class="form">
                <div class="item">
                    <i class="fa fa-user-circle-o" aria-hidden="true"></i>
                    <textarea class=b name="code" value=""></textarea>
                </div>
            </div>
            <input type="reset" value="重置">
            <input type="submit" value="提交" name=submit>
        </form>
    </div>
</body>
</html>

后端

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=drive-width,initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="login.css">
    <style>
        body {
            background: url('backiee-210221.jpg');
            background-repeat: no-repeat;
            background-size: 100% auto;
        }

        code {
            width: 30%;
            height: 80%;
            margin: 0 auto;
            margin-top: auto;
            text-align: center;
            background: 00000060;
            padding: 20px 50px;
        }

        code h2 {
            color:antiquewhite;
        }
        code h3{
            color:aliceblue;
        }
        code{
            color:aqua;
        }

        code .form .item input {
            margin-top: 25px;
        }

        code .form i {
            font-size: 18px;
            color: rgb(180, 155, 155);
        }

        code .form .item input {
            width: 180px;
            font-size: 20px;
            border: 0;
            border-bottom: 2px solidfff;
            padding: 5px 10px;
            background: ffffff00;
            color: fff;
        }

        .b {
            width: 300px;
            height: 200px;
            font-size: 20px;
            font-weight: 200;
            background: hsla(0, 0%, 100%, 0);
            color: aliceblue;
        }
        codes{
            text-align: left;
            color: yellow;
        }
    </style>
    <title>卷起来</title>
</head>
<body>
    <div id="code">
<?php
echo "<meta charset='utf-8'>";
//////////////////////////////////////////////////
///////////////////////////
// 读取网页上输入的代码,将文件保存在code.txt当中
$code = $_POST['code'];
$file = fopen('code.txt', 'w') or die('Unable to open file: ' . $file);
fwrite($file, $code);
fclose($file);
// 将code.txt 当中的字符全部逐个存入数组,并过滤空格
$path = 'code.txt';
$handle = fopen($path, 'r');
$char_array = array();
$char_array_display = array();
$i = 0;
while (FALSE !== ($chars = fgetc($handle))) {
    // 将字符存入数组
    $char_array[$i] = $chars;
    $i++;
}
$i = 0;
while (FALSE !== ($chars = fgets($handle))) {
    // 将字符存入数组
    $char_array_display[$i] = $chars;
    $i++;
}
fclose($handle);
//过滤空格

echo "<br>";

//使用正则表达式过滤
$char_array = preg_grep('/\S+/', $char_array);
//数据展示函数
$char_array = array_merge($char_array);
//var_dump($char_array);
function display_array($array)
{
    for ($i = 0; $i < count($array); $i++) {
        echo $array[$i];
    }
}
//display_array($char_array);
//foriinrange(n):inta;forjinrange(m):
//var_dump($char_array);
////////////////////////////////////////////////////////////////////
//////////////////////////////////////
// 判断一目运算符函数,传入字符即可判断
// 运算符: 如:+、-、*、/、:=、=、>、<、>=、<=
// 界符:   如:','、'.' 、';' 、'(' 、')'、'',':'
function YunSuanFu_Single($char)
{
    if ($char == '+' || $char == '-' || $char == '*' || $char == '/'  ||
     $char == '%' || $char == '=' || $char == '>' || $char == '<' ||
      $char == '!' || $char == '&' || $char == '|') {

        echo "<运算符,$char><br>";

        return 1;
    }
    if ($char == ',' || $char == '.' || $char == ';' || $char == ':') {

        echo "<界符,$char><br>";

        return 1;
    }
    return 0;
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////
// 判断二元定界符函数,需要传入当前数组以及数组指针的位置
// 函数的返回值就是最后输出主函数需要跳跃的值
function YunSuanFu_Double($char_array, $i)
{
    // 判断()
    if ($char_array[$i] == '(') {
        for ($j = $i; $j < count($char_array); $j++) {
            //循环后面的数组
            if ($char_array[$j] == ')') {

                echo "<界符,()><br> ";

                return 1;
            }
        }
    }
    // 判断
    if ($char_array[$i] == '{') {
        for ($j = $i; $j < count($char_array); $j++) {
            //循环后面的数组
            if ($char_array[$j] == '}') {

                echo "<界符,><br> ";

                return 1;
            }
        }
    }
    // 判断[]
    if ($char_array[$i] == '[') {
        for ($j = $i; $j < count($char_array); $j++) {
            //循环后面的数组
            if ($char_array[$j] == ']') {

                echo "<界符,[]><br> ";

                return 1;
            }
        }
    }
    // 判断赋值符号
    if ($char_array[$i] == ':' && $i + 1 < count($char_array)) {
        if ($char_array[$i + 1] == '=') {

            echo "<运算符,:=><br>";

            return 2;
        }
    }
    // 判断双等号
    if ($char_array[$i] == '=' && $i + 1 < count($char_array)) {
        if ($char_array[$i + 1] == '=') {

            echo "<运算符,==><br>";

            return 2;
        }
    }
    // 判断不等号
    if ($char_array[$i] == '!' && $i + 1 < count($char_array)) {
        if ($char_array[$i + 1] == '=') {

            echo "<运算符,!=><br>";

            return 2;
        }
    }
    //判断 >=
    if ($char_array[$i] == '<' && $i + 1 < count($char_array)) {
        if ($char_array[$i + 1] == '=') {

            echo "<运算符,<=><br>";

            return 2;
        }
    }
    // 判断<=
    if ($char_array[$i] == '>' && $i + 1 < count($char_array)) {
        if ($char_array[$i + 1] == '=') {

            echo "<运算符,>=><br>";

            return 2;
        }
    }
    // 判断符号&&
    if ($char_array[$i] == '&' && $i + 1 < count($char_array)) {
        if ($char_array[$i + 1] == '&') {

            echo "<运算符,&&><br>";

            return 2;
        }
    }
    //判断符号||
    if ($char_array[$i] == '|' && $i + 1 < count($char_array)) {
        if ($char_array[$i + 1] == '|') {

            echo "<运算符,||><br>";

            return 2;
        }
    }
    return 0;
}
//////////////////////////////////////////////////////////////
////////////////////////////////////////////
// 判断关键字
// 判断关键字需要使用到有穷自动机
// 从最长的关键字开始匹配,直到匹配成功到最短的关键字
// 关键字存档文件:keyword.txt
// 可以知道最长的关键字也就只有八个
function Guanjianzi($char_array, $i)
{
    //将关键字存储到数组当中去
    $code_path = 'keyword.txt';
    $GuanJianZi_Array  = file($code_path, FILE_IGNORE_NEW_LINES);
    // 截取需要的字符串
    $len = count($char_array) - $i+1; //这里有可能出错。。
    if ($len >= 8) {
        $len = 8;
        //最长的关键字也就只有八个长度
    }
    $num = $len; // 赋值给计数变量
    while ($num > 0) {
        $sliced_array = array_slice($char_array, $i, $num);
        //包括i在内的num个数组
        $key_str = implode($sliced_array);
        for ($j = 0; $j < count($GuanJianZi_Array); $j++) {
            if ($key_str == $GuanJianZi_Array[$j]) {

                echo "<关键字," . $key_str . "><br>";

                return $num; //需要返回长度值,然后再主函数里面进行跳跃
            }
        }
        $num--;
    }
    return 0;
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////
// 判断数字
function isNumber($char_array, $i)
{
    if (is_numeric($char_array[$i])) {
        $len = count($char_array) - $i;
        $num = $len;
        while ($num > 0) {
            //直接把后面的数组来切割进行判断
            $sliced_array = array_slice($char_array, $i, $num);
            $num_str = implode($sliced_array);
            if (is_numeric($num_str)) {

                echo "<数字," . $num_str . "><br>";

                return $num;
            }
            $num--;
        }
    } else
        return 0;
}
//////////////////////////////////////////////////////////////////
////////////////////////////////////////
function GuanJianZi_All()
{
    //从文件种读取关键字到数组中去
    $code_path = 'keyword.txt';
    $GuanJianZi_Array  = file($code_path, FILE_IGNORE_NEW_LINES);
    //var_dump($GuanJianZi_Array);
    // 以空格分界的关键字读入数组
    $char_path = 'code.txt';
    $code_string = file_get_contents($char_path);
    //$char_key=fopen($char_path,'r');
    $char_key_array = preg_split('/[\s,]+/', $code_string);
    //var_dump($char_key_array);
    //开始比较
    $key_array = array();
    for ($i = 0; $i < count($char_key_array); $i++) {
        for ($j = 0; $j < count($GuanJianZi_Array); $j++) {
            if ($char_key_array[$i] == $GuanJianZi_Array[$j]) {
                array_push($key_array, $char_key_array[$i]);
            }
        }
    }
    return $key_array;
}
$key_array = GuanJianZi_All();
//var_dump($key_array);
function JieFu(){
    $char_path = 'boder.txt';
    $code_string = file_get_contents($char_path);
    //$char_key=fopen($char_path,'r');
    $boder_array = preg_split('/[\s,]+/', $code_string);
    return $boder_array;
}
$boder_array=JieFu();
//var_dump($boder_array);
// 判断标识符
function isName($char_array, $i, $key_array,$boder_array)
{
    // 首先判断不以数字或者下划线打头
    if ($char_array[$i] == "_" || preg_match('/[a-zA-Z]/',$char_array[$i])) {
        for ($j = $i; $j < count($char_array); $j++) {
            // 从i号开始,往上递增
            if(in_array($char_array[$j],$boder_array) 
            && strlen($char_array[$j]) > 0) {
                $sliced_array_one = array_slice($char_array, $i, $j-$i);
                $key_str = implode($sliced_array_one);

                echo "<标识符,".$key_str."><br>";

                return $j-$i;

            }
            $num = 2;
            //从第2个字符开始寻找是否是关键字
            while ($num < count($char_array) - $j) {
                $sliced_array = array_slice($char_array, $j, $num);
                $key_str = implode($sliced_array);
                // 如果是关键字的话
                if (in_array($key_str, $key_array) && strlen($key_str) > 0) {
                    $sliced_array = array_slice($char_array, $i, $num-1);
                    $key_str = implode($sliced_array);

                    echo "<标识符," . $key_str . "><br>";

                    return $num-1;
                }

                $num++;
            }

        }
    }
    return 0;
}
////////////////////////////////////////////////////////
//////////////////////////////////////////////////
// 主函数
echo "<h2>词法分析程序</h2>";
echo "<h3>源代码</h3>";
$code_path = 'code.txt';
echo "<div id=codes>";
$Code_Array  = file($code_path);
for($i=0; $i<count($Code_Array); $i++){

    echo $Code_Array[$i]."<br>";

}

echo "</div><br>";

echo "<h3>词法分析</h3>";
$m = 0;
while ($m <= count($char_array)) {

    $count == 0;
    $diff = count($char_array) - $m;
    $sum = 0;
    //echo count($char_array);
    // 先判断是不是双目运算符,再判断是不是单目运算符
    $sum = YunSuanFu_Double($char_array, $m);

    //echo "<br>$sum"."  "."$m<br>";

    $m += $sum;
    $sum = YunSuanFu_Single($char_array[$m]);
    $m += $sum;

    //判断是不是关键字
    $sum = GuanJianZi($char_array, $m);
    $m += $sum;
    // 判断是不是标识符
    $sum = isName($char_array, $m,$key_array,$boder_array);
    $m += $sum;

    $sum = isNumber($char_array, $m);
    $m += $sum;

    //echo "<br>$sum"."  "."$m<br>";

    //判断数组长度和m的差值,即到某个字符时,所有的函数都不匹配的时候
    if ($diff == count($char_array) - $m) {
        $m += 1; //指针就向后移动一位
    }
}
?>
    </div>
    </body>
    </html>

原文创作:Zeker62

原文链接:https://www.cnblogs.com/Zeker62/p/15380566.html

更多推荐

更多
  • Azure上Linux管理-十、使用 Azure Kubernetes 服务 技术要求,开始使用 AKS,与 Helm 一起工作,使用草稿,管理 Kubernetes,问题,进一步,使用 WSL 和 VS Code,安装依赖,kubectl 安装,使用 Azure CLI 创建集群,AKS 首次部署,创建服务,多
    Apache CN

  • Azure上Linux管理-十一、故障排除和监控您的工作负载 module(load="imuxsock"),技术要求,访问您的系统,Azure 日志分析,性能监控,问题,进一步,不允许远程访问,正在端口上工作,使用 nftables,引导诊断,Linux 登录,配置日志分析服务,安装 Azure
    Apache CN

  • Azure上Linux管理-十二、附录 第一章:探索微软 Azure 云,第二章:Azure 云入门,第三章:Linux 基础管理,第 4 章:管理 Azure,第五章:高级 Linux 管理,第七章:部署虚拟机,第八章:探索连续配置自动化,第 9 章:Azure 中的容器虚
    Apache CN

  • Azure上Linux管理-九、Azure 中的容器虚拟化 cloudconfig,集装箱技术导论,系统生成,Docker,Azure 容器实例,Buildah, Podman, and Skopeo,容器和储存,问题,进一步,容器历史,chroot 环境,OpenVZ,LXC,创建一个带启动的
    Apache CN

  • Azure上Linux管理-七、部署你的虚拟机 ResourceGroup 不存在,创建它:,vnet 不存在,创建 vnet,cloudconfig,Vagrant.config 结束,部署场景,Azure 中的自动部署选项,初始配置,流浪,封隔器,自定义虚拟机和 vhd,问题,进
    Apache CN

  • Azure上Linux管理-八、探索持续配置自动化 了解配置管理,使用 Ansible,使用地球形态,使用 PowerShell DSC,Azure 策略客户端配置,其他解决方案,问题,进一步,技术要求,Ansible 的安装,SSH 配置,裸最小配置,库存文件,Ansible 剧本和模
    Apache CN

  • Azure上Linux管理-五、高级 Linux 管理 技术要求,软件管理,网络,存储,systemd,问题,进一步,RPM 软件管理器,YUM 软件管理,基于 DNF 的软件管理,DPKG 软件管理器,运用 apt 进行软件管理,ZYpp 软件管理,识别网络接口,IP 地址识别,显示路由表
    Apache CN

  • Azure上Linux管理-六、管理 Linux 安全与身份 SELINUX=可以接受以下三个值之一:,permissiveSELinux 打印警告而不是强制执行。,disabled 没有加载 SELinux 策略。,SELINUXTYPE=可以接受以下三个值之一:,targeted 目标进程
    Apache CN

  • Azure上Linux管理-四、管理 Azure 使用 Azure CLI 和 PowerShell 管理 Azure 资源,技术要求,管理存储资源,管理网络资源,管理计算资源,虚拟机资源,问题,进一步,存储帐户,托管磁盘,Azure 文件,Azure Blob,虚拟网络,子网,网络安
    Apache CN

  • Azure上Linux管理-三、Linux 基础管理 Linux Shell,获取帮助,使用文本文件,在文件系统中找到你的方式,流程管理,自由访问控制,问题,执行命令,命令行编辑,与历史一起工作,自动完成,球状,重定向,处理变量,Bash 配置文件,使用手册页,使用信息文档,其他文档,文本
    Apache CN

  • 近期文章

    更多
    文章目录

      推荐作者

      更多