#!/usr/local/bin/perl -w
use CGI; #модуль CGI, подключается для чтения входных параметров из заголовка
use CGI::Carp qw(fatalsToBrowser); #подключаетя для вывода ошибок в браузер
$q=new CGI;
$M=$q->param('M'); #M=длина идентификатора
$N=$q->param('N'); #N=количество чисел в массиве
$TP=$q->param('TP'); #TP=текст программы
#Вывод заголовков страницы html
print "Content-type: text/html\n\n";
print qq[
Курсовая работа Габидиновой Айгуль
];
#Вывод входных параметров
print qq[
Входные параметры:
\n
Максимальная длина идентификатора: $M\n
Количество чисел в массиве: $N\n
Текст программы:$TP
\n];
# ПРОВЕРКА СИНТАКСИСА ЯЗЫКОВОЙ ПРОГРАММЫ.
$b=1; #Присваиваем булевской переменной значение true, которое остается таковым, пока не будет найдена ошибка
$_=$TP; #Стандартной переменной присваиваем текст проверяемой программы (так как с ней удобнее работать: короче записи)
print "\nПротокол ошибок:
";
# Проверка общих условий задачи 6
~s/\r\n//g; #убираем все переносы строк, так как они не несут синтаксической нагрузки
unless(/\s/){print "\nУ программы нет конца! (необходим пробел).
";$b=0};
if(/\s./){print "\nПосле пробела имеется символ! (По условию пробел трактуется как конец).
";$b=0};
if(/;([^A-Za-z\s])/g){print "\nПосле \'\;\' должна быть либо буква, либо пробел (а не \'$1\').
";$b=0};
/^(.*?)\s/;$_=$1; #Присваиваем стандартной переменной текст, заключённый между началом строки и первым пробелом
if(/([^A-Za-z0-9\s\d\+\-\*\/\;\:\=\|\_\,\(\)]+)/){print "\nВ тексте используются недопустимые символы(\"$1\").
";$b=0};
if(/:(?!\=)/g){print "\nПосле двоеточия может быть только знак равно.
";$b=0};
@op=split(';'); #элементами массива становятся операторы (деление по символу ';')
$o=1; #счётчик
foreach(@op){
@sk=split('\('); #Разбиваем оператор по открывающим скобкам и идем в массиве по получившимся строкам
if($sk[0]=~/\)/){print "Перед закрывающей скобкой нет открывающей (В $o операторе)
";$b=0};
for($i=1;$i<=$#sk;$i++){
if($sk[$i]!~/\)/){print "Открывающей скобке не хватает закрывающей! (В $o операторе)
";$b=0}
$sk[$i]=~/^(.*)\)/;$zpt=$1; #В $zpt записываем то, что находится между скобками
@zpt=($zpt=~/(\,)/g); # В массив заносим все запятые, $#zpt-индекс последнего элемента массива
if($#zpt!=($N-2)){print "Количество чисел в массиве должно быть $N! (В $o операторе их ".($#zpt+2).")
";$b=0};
if($zpt=~/([^0-9\+\-\,]+)/){print "\nВнутри круглых скобок могут быть только цифры, запятая, знаки '+' и '-' (В $o операторе имеется \"$1\").
";$b=0};
if($zpt=~/[\(\,]([^\+\-]+)/){print "\nЧисло должно начинаться с '+' или '-', а начинается с \'$1\' (В $o операторе).
";$b=0};
if($zpt=~/[\+\-]([^0-9]+)/){print "\nПосле знака '+' или '-' в числе должна стоять цифра (стоит \'$1\' в $o операторе).
";$b=0};
while($zpt=~/([\+\-][0-9]+)/g){if(length($1)!=6){print "Количество цифр в числе \"$1\" $o-го оператора равняется ".(length($1)-1).". Должно быть ровно 5.
";$b=0}};
};
@id=(m/([A-Za-z][A-Za-z0-9]+)/g); #Заносим в массив @id идентификаторы (выражение, 1 символ которого буква, последующие буквы и цифры)
for($d=0;$d<=$#id;$d++){ #Идем по идентификаторам
if(length($id[$d])>$M){print "Длина идентификатора ($id[$d]) превышает максимальную ($M) (В $o операторе).
";$b=0}}
if(m/\=(.+)$/){$pch=$1}else{print "В $o операторе определяемому идентификатору ничего не присваивается.
";$b=0};
$pch=~s/\(.+?\)/sk/g;@pid=split(/[\+\-\*\/]/,$pch); #Делим правую часть оператора по арифметическим действиям в массив
foreach $pid (@pid){
unless($pid=~m/^([A-Za-z][A-Za-z0-9]+)$/){print "Арифметические действия могут выполняться только с идентификаторами и массивами (В $o операторе используется \"$pid\").
";$b=0}
if($pid ne 'sk'){$bool=0;
foreach $lid (@lid){if($lid eq $pid){$bool=1}};
if($bool==0){print "Оператор $pid не был определён перед использованием ($o оператор).
";$b=0}};
};
if(m/^([A-Za-z][A-Za-z0-9]+)\:/){$lid=$1}else{print "Ошибка в записи определяемого идентификатора в $o операторе.
";$b=0}; #Идентификатор из левой части выражения
@lid=(@lid,$lid); #Присваиваем массиву идентификаторы, стоящие в левой части
$o++};
# Вывод конца страницы
if($b==1){print "\nВ синтаксисе данной языковой программы ошибок не имеется."}else{
print "\n
В синтаксисе данной языковой программы имеются ошибки! (Смотрите выше)"};
print 'По всем вопросам обращайтесь по адресу
aigool@mail.ru
';