2

这是我的问题here的后续行动。

我在程序中遇到了一个点,我觉得我无法继续使用当前的结构,所以我做了很多重写。Statement类型不再是抽象的,每个子类型都创建Statement自己Statement的变量实例。我还从 Statements 包中删除了抽象execute函数,因为编译器不喜欢这样(execute无论如何,每个子类型仍然有自己的方法)。该execute函数已更改为过程,因为必须修改传入的 Statement 类型。我将statementFactory(以前的 createStatement)移动到Statement包中。

这是我得到的错误:

statements-compoundstatements.adb:15:29: expected type "CompoundStatement" defined at statements-compoundstatements.ads:11
statements-compoundstatements.adb:15:29: found type "Statement'Class" defined at statements.ads:6

我是 Ada 的初学者,但我的直觉是,因为execute程序在CompoundStatements(它是 Statements 的“子类”)中,所以它永远无法看到executeStatements 的另一个“子类”的方法。我能想到的唯一解决方案是将所有execute调用过程的过程转储executeStatement包中,但这似乎是不可取的。但这仍然不能解释为什么stmt.all被用作类型Statement'Class而不是在statementFactory.

这是新代码:

package Statements is

   type Statement is tagged private;

   type Statement_Access is access all Statement'Class;
   ParserException : Exception;

   procedure createStatement(tokens : Vector; S : out Statement);
   procedure statementFactory(S: in out Statement; stmt: out Statement_Access);

--.....A bunch of other procedures and functions.....

private
   type Statement is tagged
      record
         tokens : Vector;
         executedtokens : Vector;
      end record;

end Statements;

   procedure createStatement(tokens : Vector; S : out Statement) is
   begin
      S.tokens := tokens;
   end createStatement;

   procedure statementFactory(S: in out Statement; stmt: out Statement_Access) is
      currenttoken : Unbounded_String;
      C            : CompoundStatement;
      A            : AssignmentStatement;
      P            : PrintStatement;

   begin
      currenttoken := getCurrentToken(S);
      if currenttoken = "begin" then
         createStatement(S.tokens, C);
         stmt := new CompoundStatement;
         stmt.all := Statement'Class(C);
      elsif isVariable(To_String(currenttoken)) then
         createStatement(S.tokens, A);
         stmt := new AssignmentStatement;
         stmt.all := Statement'Class(A);
      elsif currenttoken = "print" then
         createStatement(S.tokens, P);
         stmt := new PrintStatement;
         stmt.all := Statement'Class(P);
   end statementFactory;

package body Statements.CompoundStatements is

   procedure execute(skip: in Boolean; C: in out CompoundStatement; reset: out Integer) is
      stmt: Statement_Access;
      tokensexecuted: Integer;
      currenttoken : Unbounded_String;
   begin
      match(C, "begin");
      currenttoken := getCurrentToken(C);
      while(currenttoken /= "end") loop
         statementFactory(C, stmt);
         execute(skip, stmt.all, tokensexecuted); //ERROR OCCURS HERE
4

1 回答 1

5

你说“我还从 Statements 包中删除了抽象执行函数,因为编译器不喜欢那样”;但是您确实需要它,因为否则编译器如何知道当您调用execute (skip, stmt.all, tokensexecuted)any时,它stmt.all会提供一个execute供它分派的对象?

扩展类型不仅继承了其父类型的属性(因此每个CompoundStatementetc 已经具有tokensand executedtokens),它还继承了父类型的原始操作;如果父操作是abstract,则子操作必须提供自己的实现,否则,子操作可以提供自己的(覆盖)实现。

请参阅Ada 95 RationaleWikibooks以获得关于此的良好讨论。

于 2012-04-07T08:46:46.150 回答