Ada - 使用look_ahead跳过空白

时间:2018-03-22 16:42:19

标签: whitespace ada lookahead

我有一个程序,理论上应该使用look_ahead循环跳过空格。问题是,它不起作用,如果输入文件中有任何空格,则将其添加到记录数组中。我认为我的逻辑是正确的,但可以用另一双眼睛让我知道我错过了什么,以及为什么它不起作用。

PROCEDURE Read(Calc: OUT Calculation) IS
  EOL: Boolean;
  C: Character;
  I: Integer := 1;
BEGIN
  LOOP
     LOOP
        Look_Ahead(C, EOL);
        EXIT WHEN EOL or C /= ' ';
        Get(C);
     END LOOP;
     EXIT WHEN ADA.Text_IO.END_OF_FILE;    
     Look_Ahead(C, EOL);
     IF Is_Digit(C) THEN
        Calc.Element(I).Kind := Number;
        Get(Calc.Element(I).Int_Value);
     ELSE
        Calc.Element(I).Kind := Symbol;
        Get(Calc.Element(I).Char_Value);
     END IF;
     Calc.Len := Calc.Len+1;
     IF Calc.Element(I).Char_Value = '=' THEN
        EXIT;
     END IF;
     I := I+1; 
  END LOOP;
END Read;

编辑:如果答案需要任何其他程序,记录代码等,请告诉我,我会发布。

2 个答案:

答案 0 :(得分:2)

对于Ada.Text_IO.Look_AheadARM A.10.7(8)

  

如果在行尾,则将End_Of_Line设置为True,包括在页面末尾或文件末尾;在每种情况下,都没有指定Item的值。否则,End_Of_Line设置为False,Item设置为文件中的下一个字符(不消耗它)。

(我的重点),我认为“不消耗它”是关键。 Look_Ahead找到有趣字符后,您需要调用Get来检索该字符。

我一起攻击了这个小小的演示:我将文件末尾留给了异常处理,一旦看到行尾,我就调用了Skip_Line,因为只有Get不正确(对不起)更确切地说!)。

with Ada.Text_IO;
with Ada.IO_Exceptions;
procedure Justiciar is

   procedure Read is
      Eol: Boolean;
      C: Character;
   begin
      --  Instead of useful processing, echo the input to the output
      --  replacing spaces with periods.
      Outer:
      loop
         Inner:
         loop
            Ada.Text_IO.Look_Ahead (C, Eol);
            exit Outer when Eol;   -- C is undefined
            exit Inner when C /= ' ';
            Ada.Text_IO.Get (C);   -- consume the space
            Ada.Text_IO.Put ('.'); -- instead of the space for visibility
         end loop Inner;
         Ada.Text_IO.Get (C);      -- consume the character which isnt a space
         Ada.Text_IO.Put (C);      -- print it (or other processing!)
      end loop Outer;
      Ada.Text_IO.Skip_Line;       -- consume the newline
      Ada.Text_IO.New_Line;        -- clear for next call
   end Read;

begin
   loop
      Ada.Text_IO.Put ("reading: ");
      Read;
   end loop;
exception
   when Ada.IO_Exceptions.End_Error =>
      null;
end Justiciar;

答案 1 :(得分:1)

通常最好读取整行并解析它,而不是尝试逐个字符地解析。后者通常更复杂,更难理解,更容易出错。所以我建议像

这样的东西
function De_Space (Source : String) return String is
   Line : Unbounded_String := To_Unbounded_String (Source);
begin -- De_Space
   Remove : for I in reverse 1 .. Length (Line) loop
      if Element (Line, I) = ' ' then
         Delete (Source => Line, From => I, Through => I);
      end if;
   end loop Remove;

   return To_String (Line);
end De_Space;

Line : constant String := De_Space (Get_Line);

然后,您可以遍历Line'range并解析它。因为我不清楚是否

Get(C);
Get(Calc.Element(I).Int_Value);
Get(Calc.Element(I).Char_Value);

代表1,2或3个不同的程序,我无法真正帮助那个部分。