program LexicalAnalyzer;

function CheckFirstWord(s: string; var p: integer): boolean;
var
  start: integer;
begin
  start := p;

  { (000)* }
  while (p + 2 <= Length(s)) and
        (s[p] = '0') and
        (s[p + 1] = '0') and
        (s[p + 2] = '0') do
    p := p + 3;

  { 001 }
  if (p + 2 > Length(s)) or
     (s[p] <> '0') or
     (s[p + 1] <> '0') or
     (s[p + 2] <> '1') then
  begin
    p := start;
    CheckFirstWord := false;
    Exit;
  end;

  p := p + 3;

  { (010)* }
  while (p + 2 <= Length(s)) and
        (s[p] = '0') and
        (s[p + 1] = '1') and
        (s[p + 2] = '0') do
    p := p + 3;

  CheckFirstWord := true;
end;


function CheckSecondWord(s: string; var p: integer): boolean;
begin
  { First two characters must be ab }

  if p + 1 > Length(s) then
  begin
    CheckSecondWord := false;
    Exit;
  end;

  if (s[p] <> 'a') or (s[p + 1] <> 'b') then
  begin
    CheckSecondWord := false;
    Exit;
  end;

  p := p + 2;

  { Other characters can be a, b, c or d }

  while (p <= Length(s)) and
        (s[p] in ['a', 'b', 'c', 'd']) do
    p := p + 1;

  CheckSecondWord := true;
end;


function AnalyzeLine(s: string; lineNumber: integer): boolean;
var
  p: integer;
  ok: boolean;
begin
  p := 1;
  AnalyzeLine := true;

  while p <= Length(s) do
  begin

    { Skip spaces }
    while (p <= Length(s)) and (s[p] = ' ') do
      p := p + 1;

    if p > Length(s) then
      Exit;

    { Comment }
    if s[p] = '''' then
    begin
      Exit;
    end;

    { First word }
    if s[p] = '0' then
    begin
      ok := CheckFirstWord(s, p);

      if not ok then
      begin
        writeln('Error in line ', lineNumber,
                ', position ', p,
                ': invalid first word.');
        AnalyzeLine := false;
        Exit;
      end;
    end

    { Second word }
    else if s[p] in ['a', 'b', 'c', 'd'] then
    begin
      ok := CheckSecondWord(s, p);

      if not ok then
      begin
        writeln('Error in line ', lineNumber,
                ', position ', p,
                ': invalid second word.');
        AnalyzeLine := false;
        Exit;
      end;
    end

    { Invalid character }
    else
    begin
      writeln('Error in line ', lineNumber,
              ', position ', p,
              ': invalid character.');
      AnalyzeLine := false;
      Exit;
    end;

  end;
end;


var
  n: integer;
  i: integer;
  line: string;
  allCorrect: boolean;

begin

  writeln('=============================================');
  writeln('LEXICAL ANALYZER');
  writeln('VARIANT 34');
  writeln('=============================================');
  writeln;

  writeln('WORD 1: (000)*001(010)*');
  writeln('WORD 2: ab(a | b | c | d)*');
  writeln('COMMENT: apostrophe to end of line');
  writeln;

  write('Enter number of lines: ');
  readln(n);

  writeln;
  writeln('Enter text:');

  allCorrect := true;

  for i := 1 to n do
  begin
    readln(line);

    if not AnalyzeLine(line, i) then
      allCorrect := false;
  end;

  writeln;

  if allCorrect then
    writeln('No errors found.');

  writeln;
  writeln('Press Enter to exit.');
  readln;

end.