shell写的编译器

头文件

debug_wait

function allFile() {
awk '{print NR,$0}' $fileName
}

function main() {
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo "|+++++++++++++++++输入提醒+++++++++++++++|"
echo "|+++++++++1、调试操作:debug ++++++++++|"
echo "|+++++++++(其他命令)、运行操作 ++++++++++|"
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
echo -e " >--->请键入命令(序号和命令均可):\c"
read ORDER
#有问题:怎么两个条件并列

if [ "$ORDER" = "debug" ] || [ "$ORDER" = "1" ]
then
promptDialog
else
run
fi
}
function Lookhelp() {
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo "|+++++++++++++++调试步骤命令+++++++++++++|"
echo "|+++++++ 1、设置断点:set ++++++++|"
echo "|+++++++ 2、单步调试:oneStep ++++++++|"
echo "|+++++++ 3、跳转至下一断点:next ++++++++|"
echo "|+++++++ 4、查看变量:check ++++++++|"
echo "|+++++++ (其他命令)、结束调试 ++++++++|"
echo "++++++++++++++++++++++++++++++++++++++++++"
}
function promptDialog() {

#初始化
is_OneStep=0

if [ "$firstInter" = "0" ]
then
firstInter=1
echo " 所调试程序显示如下,请根据行号设置断点:"
echo "------------------------------------------"
allFile
echo "------------------------------------------"
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo "|+++++++++++++++++友情提示+++++++++++++++|"
echo "|++++++++如需帮助请键入:help ++++++++|"
echo "++++++++++++++++++++++++++++++++++++++++++"
fi
echo " "
echo -e " >--->请输入操作命令(序号和命令均可):\c"
read COMMAND
echo " "
#帮助操作
if [ "$COMMAND" = "help" ]
then
Lookhelp
echo " "
echo -e " >--->请输入操作命令(序号和命令均可):\c"
read COMMAND
echo " "
fi
#设置断点操作
if [ "$COMMAND" = "set" ] || [ "$COMMAND" = "1" ]
then
set_point
#单步调试操作
elif [ "$COMMAND" = "oneStep" ] || [ "$COMMAND" = "2" ]
then
oneStep
#跳转至下一断点操作
elif [ "$COMMAND" = "next" ] || [ "$COMMAND" = "3" ]
then
nextPoint
#查看变量操作
elif [ "$COMMAND" = "check" ] || [ "$COMMAND" = "4" ]
then
check
#结束调试操作
else
run
fi
}

function check() {
k=0
while [ $k -eq 0 ]
do
echo -e " >--->请输入变量(输入exit退出):\c"
read orderName
if [ "$orderName" = "exit" ]
then
return
else
echo " 变量显示:$orderName : ${!orderName}"
fi
done
}

#跳转至下一断点操作
function nextPoint() {
N=$point_count
}

#单步调试 事实上是不需要任何操作的
function oneStep() {
is_OneStep=1
}

#调试该行
function debug_wait() {
src=$1
line=$2
#返回0或1,$?表示返回的值,必须紧接下一行引用
is_break $1 $2
if [ $? -eq 1 ] || [ $is_OneStep -eq 1 ]
then
echo " "
echo -e " 第 $line 行内容为:\c"
display_src $src $line
echo " ----------------------------------------"
promptDialog $line
fi
}

#显示行
function display_src() {
awk -v line=$2 '
{
if( FNR == line ){
print $0;
}
else{
next;
}
}
' $1
}

#判断是否设置了断点
function is_break() {
c=0
while [ $c -lt ${point_count} ]
do
if [ "$1" = "${point_src[$c]}" ] && [ "$2" = "${point_line[$c]}" ]
then
return 1
fi
c=`expr $c + 1`
done
return 0
}

#运行
function run() {
point_count=0
}

#设置断点
function set_point() {
echo "++++++++++++++++++++++++++++++++++++++++++"
echo "|++++++++++++设置断点方法介绍++++++++++++|"
echo "|+++ 1、输入程序的行号,表示断点位置。+++|"
echo "|+++ 2、输入 0 表示设置断点结束。 +++|"
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
N=1

echo -e " >--->请输入第 $N 个断点位置:\c"
read NUM
while [ $NUM -gt 0 ]
do
point_src[${point_count:-0}]=$fileName
point_line[${point_count:-0}]=$NUM
point_count=`expr ${point_count:-0} + 1`
N=`expr $N + 1`
echo -e " >--->请输入第 $N 个断点位置:\c"
read NUM
done
if [ "$N" -ne "0" ]
then
M=`expr $N - 1`
echo " (您一共设定了个 $M 断点)"
else
echo " (您未设置断点)"
fi

promptDialog
}

point_count=0
firstInter=0
is_OneStep=0
main

其他文件

#!/bin/bash

var=`date +%Y%m%d%H%M%S`.sh

#判断'(',')'是否匹配
function CheckYuan(){
#获得要编译的文件的行数
row=$(awk '
END { print FNR }
' $1)
#i用于标记遍历编译文件行数
i=1
#用于记录全局的存储剩余{d的个数
symbleCount=0
#用于统计前i行的剩余{的个数
count=0
#遍历编译文件的每一行
while [ $i -le $row ] && [ $symbleCount -ge 0 ]
do
count=$( awk -v _count=$symbleCount -v _i=$i '
BEGIN {FS =""; OFS =" " }
{
if ( FNR == _i ) {
for (j=1;j<=NF;j++){
if ($j~/^[ \t]*\([ \t]*$/){
_count = _count +1;
}
else if ($j~/^[ \t]*\)[ \t]*$/){
if (_count >0){
_count = _count -1;
}
else
if (_count<=0){
_count=-1*_i;
}
}
}
}
}
END {print _count }
' $1 )
#如果{的个数大于等于0
if [ $count -ge 0 ]
then
#如果全局变量统计的{值小于当前{的值,将当前行的{的值保存到数组line中
while [ ${symbleCount} -lt ${count} ]
do
line[$symbleCount]=$i
symbleCount=`expr $symbleCount + 1`

done
#如果当前系统保存的统计{的值的全局变量大于当前的{的统计值,则将当前的统计值置未当前值
if [ ${symbleCount} -gt ${count} ]
then
symbleCount=$count
fi
#如果当前统计值未-1,则将row的值付给i
elif [ $count -lt 0 ]
then
i=$row
symbleCount=-1
var=`expr $count * {-1}`
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " 》语法错误:第$var行的')'没有匹配的'('《 "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
return `false`
fi
#遍历下一行
i=`expr $i + 1`
done

if [ $symbleCount -gt 0 ]
then
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " 》语法错误:第$line行的'('缺少配对的')'《"
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
return `false`
fi
if [ $symbleCount -eq 0 ]
then
return `true`
fi

}

#查看‘{’,‘}’是否匹配
function CheckCode(){
#获得要编译的文件的行数
row=$(awk '
END { print FNR }
' $1)
#i用于标记遍历编译文件行数
i=1
#用于记录全局的存储剩余{d的个数
symbleCount=0
#用于统计前i行的剩余{的个数
count=0
#遍历编译文件的每一行
while [ $i -le $row ] && [ $symbleCount -ge 0 ]
do
count=$( awk -v _count=$symbleCount -v _i=$i '
BEGIN {FS =""; OFS =" " }
{
if ( FNR == _i ) {
for (j=1;j<=NF;j++){
if ($j~/^[ \t]*{[ \t]*$/){
_count = _count +1;
}
else if ($j~/^[ \t]*}[ \t]*$/){
if (_count >0){
_count = _count -1;
}
else
if (_count<=0){
_count=-1*_i;
}
}
}
}
}
END {print _count }
' $1 )
#如果{的个数大于等于0
if [ $count -ge 0 ]
then
#如果全局变量统计的{值小于当前{的值,将当前行的{的值保存到数组line中
while [ ${symbleCount} -lt ${count} ]
do
line[$symbleCount]=$i
symbleCount=`expr $symbleCount + 1`

done
#如果当前系统保存的统计{的值的全局变量大于当前的{的统计值,则将当前的统计值置未当前值
if [ ${symbleCount} -gt ${count} ]
then
symbleCount=$count
fi
#如果当前统计值未-1,则将row的值付给i
elif [ $count -lt 0 ]
then
i=$row
symbleCount=-1
var=`expr $count * {-1}`
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " 》语法错误:第$var行的'}'没有匹配的'{'《 "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
return `false`
fi
#遍历下一行
i=`expr $i + 1`
done

if [ $symbleCount -gt 0 ]
then
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " 》语法错误:第$line行的'{'缺少配对的'}'《"
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
return `false`
fi
if [ $symbleCount -eq 0 ]
then
return `true`
fi

}


function drop_var() {
awk -v var=$1 '
NR==FNR{
print
}END { print "rm",var }
' h_xz.sh > h_rt.sh
}

#在源程序每行后加入debug_wait
function makets_debugs() {
awk -v name=$1 '
NR==FNR&&(NR==1){
a[NR]=$0
}NR>FNR{
print;
for (i in a){
if (!/^[ \t]*#/ && NF && $0!="}" && !/^[ \t]*if/ && !/^[ \t]*elif/ && !/[ \t]*while/) print a[i],name,FNR
}
}
' h_file $1 > h_xz.sh
}

#在源程序中加入调试function
function makets_funs() {
awk '
NR==FNR&&(FNR>=3 && FNR<=199){
a[FNR]=$0
}NR>FNR{
if (FNR==2)
for (i=3;i<=199;i++) print a[i];
print

}
' h_file h_rt.sh > h_xzz.sh
}

#为调试文件中的变量fileName赋源文件的名称
function give_name() {
awk -v name=$1 '
NR==FNR{
if (FNR==2)
print "fileName=" name;
print
}
' h_xzz.sh > $var
}

#判断用户输入的文件是否存在
function is_exist() {
read name
while [ ! -e $name ] || [ -z $name ]
do
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo "|+++++++++++ 输入exit结束任务 +++++++++++|"
echo "|+++ 文件名不存在或者为空,请重新输入 +++|"
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
read name
if [ $name == "exit" ]
then
#echo "输入了exit"
return `false`
fi
done
return `true`
}

#主函数
function main() {
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo "|+++++++++ 请输入源文件的名称 +++++++++++|"
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
if is_exist
then
if CheckYuan $name
then
if CheckCode $name
then
makets_debugs $name
drop_var $var
makets_funs
give_name $name
rm h_xz.sh
rm h_rt.sh
rm h_xzz.sh
chmod u+x $var
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo "|+++++++++++++++ 开始调试 +++++++++++++++|"
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
./$var
fi
fi
else
echo " "
echo "++++++++++++++++++++++++++++++++++++++++++"
echo "|+++++++++++++++ 结束任务 +++++++++++++++|"
echo "++++++++++++++++++++++++++++++++++++++++++"
echo " "
fi
}

main




原文地址:https://www.cnblogs.com/wuxi/p/2285935.html