Если вы серьезно относитесь к этому, вы должны учитывать каждую строку, все граничные условия, ошибки и т. Д. Недостаточно просто соответствовать определенной форме, не зная ничего о других формах.
При использовании регулярных выражений, более чистый способ - зарезервировать фиксированное количество буферов, которые можно проанализировать.Это довольно сложно для элементарной проверки синтаксиса первого уровня.
Это начало:
/
^
(?!\s*$)
\s*
(?|
([a-zA-Z]+)
\s*
((?<=\s)
-?\d+|) (?!,\s*$) (?:,\s*|\s*$)
(-?\d+|) (?!,\s*$) (?:,\s*|\s*$)
(-?\d+|) \s*$
()
|
()()()()(.+)
)
$
/x;
Тестовый пример Perl с использованием строк с разделителями новой строки:
use strict;
use warnings;
my $rx = qr/
^
(?!\s*$)
\s*
(?|
([a-zA-Z]+)
\s*
((?<=\s)
-?\d+|) (?!,\s*$) (?:,\s*|\s*$)
(-?\d+|) (?!,\s*$) (?:,\s*|\s*$)
(-?\d+|) \s*$
()
|
()()()()(.+)
)
$/x;
my $cnt = 0; # line counter
while ( my $line = <DATA> )
{
++$cnt;
if ( $line =~ /$rx/ )
{
if (length $5) {
print "\nSyntax error ? (line $cnt) '$5'\n";
}
else {
print "\nInstruction: '$1'\n";
print " op1 = '$2'\n";
print " op2 = '$3'\n";
print " op3 = '$4'\n";
}
}
}
__DATA__
MOVI 8 10
ADDI 8 8 10
NOP
BNEZI -1
InstA 0
InstB 1,
InstC 2,3, 4
InstD 5,6, 7, 8
MOVI 7, 8
ADDI 9, 10, 11
ADDI 12, 13 14
Вывод:
Syntax error ? (line 2) 'MOVI 8 10'
Syntax error ? (line 3) 'ADDI 8 8 10'
Instruction: 'NOP'
op1 = ''
op2 = ''
op3 = ''
Instruction: 'BNEZI'
op1 = '-1'
op2 = ''
op3 = ''
Instruction: 'InstA'
op1 = '0'
op2 = ''
op3 = ''
Syntax error ? (line 8) 'InstB 1,'
Instruction: 'InstC'
op1 = '2'
op2 = '3'
op3 = '4'
Syntax error ? (line 10) 'InstD 5,6, 7, 8'
Instruction: 'MOVI'
op1 = '7'
op2 = '8'
op3 = ''
Instruction: 'ADDI'
op1 = '9'
op2 = '10'
op3 = '11'
Syntax error ? (line 14) 'ADDI 12, 13 14'
Альтернативно, все данные в строке (то же регулярное выражение).
while ( $str =~ /$rx/mg ) { }