AI智能
改变未来

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

<!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 solid#fff;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 solid#fff;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"><?phpecho "<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--;}} elsereturn 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>
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 编译原理:词法分析PHP代码实现