2012-07-22 61 views
1

我想基于以下接口一组解析器Ada中的模型:Ada接口铸造?

package Parsers is 

    type Parser is interface; 
    type DataArray is array(Integer range <>) of String(1..100); 

    function Parse(Object : access Parser; FilePath : String) return DataArray is abstract; 

end Parsers; 

第一分析器接口成员低于文本分析器显示:

with Parsers; 

package TextParsers is 
    type Parser is new Parsers.Parser with null record; 

    overriding function Parse(Object : access Parser; FilePath : String) return Parsers.DataArray; 
    end TextParsers;          

with Parsers; 
use Parsers; 

package body TextParsers is 

    overriding function Parse(Object : access Parser; FilePath : String) return Parsers.DataArray is 
     Data : Parsers.DataArray (0..144); 
    begin 
     -- just stubbed out 
     return Data; 
    end Parse; 
end TextParsers; 

最后,我想有一个工厂方法创建基于路径上的这些解析器提供,例如,检测,如果它是一个txt文件或者一个CSV等。这里是工厂代码:

with Parsers; 
use Parsers; 

package ParserFactories is 
    function GetParser(Path : String) return Parsers.Parser; 
end ParserFactories; 


with Parsers, TextParsers; 

package body ParserFactories is 
    function GetParser(Path : String) return Parsers.Parser is 
     Text : TextParsers.Parser; 
     Parse : Parsers.Parser'Class := Text; 
    begin 
     return Parse; 
    end GetParser; 
end ParserFactories; 

我不断收到“动态标记的表达式不允许”编译器错误,我无法弄清楚如何创建这些实现解析器接口并将其从此函数中返回的对象。有没有办法在Ada中做到这一点?

回答

2

您正试图返回Parsers.Parser类型。这是不允许的(而不是你打算做的)。改为改为Parsers.Parser'Class

+1

+1,但应该可以扩展。在Ada中,如果你指定一个类型,你将总是得到那种类型。如果你想让这个类型成为“这个类型或从它派生的任何东西”,你需要使用''class'。 – 2012-07-23 17:19:21

1

答案是,您不返回接口的类型,但是该对象的类型是...或者您可以返回接口的类来指示您将它分配给该抽象类型,类型变量。

Procedure Testing is 

package Interface_Test is 
    Type IBob is interface; 
    Function Make Return IBob is abstract; 
    Function Image(Object : In IBob) Return String is abstract; 

    Generic 
     Type Data is (<>); 
     Default_Data : In Data; 
    Package Container is 
     Type Data_Container is NEW IBob with private; 
    private 
     Type Data_Container is new IBob with record 
     Info : Data:= Default_Data; 
     end record; 

     Overriding Function Make Return Data_Container; 
     Overriding Function Image(Object : In Data_Container) Return String; 
    end Container; 
end Interface_Test; 

package Body Interface_Test is 
    Package Body Container is 

     Function Make Return Data_Container is 
     begin 
     Return Result : Data_Container; 
     end Make; 

     Function Image(Object : Data_Container) Return String is 
     begin 
     return Data'Image(Object.Info); 
     end image; 

    end Container; 
end Interface_Test; 


package J is new Interface_Test.Container(Integer, 1); 
use type J.Data_Container; 
Test : J.Data_Container:= J.Make; 

Use Ada.Text_IO; 

Begin 
    put_line(Test.Image); 
End;