Thank you for answering! No else questions in this post. Just my thoughts/remarks in case you want to read them.
Anyway, it is a fundamental property of Visual Prolog ...
Yes, I see. Changing a fundamental property can turn a lot of things upside down. I can imagine that it could easily produce an unreasonable large amount of work.
Finally notice, that given the current way things are now, both objA and objC are allowed to define domains (with functors) and constants with same names ...
Oh, I had not noticed that before. It means that for constants I can cure the problem 'manually' by simply declaring the constants from the super-interfaces again with same names in the sub-interface:
Code: Select all
c : unsigned = 1.
end interface objA
interface objB supports objA
c : unsigned = objA::c.
end interface objB
However for domains it does not work out that way.
When someone reads the code and sees objC::const1 it is quite nice that const1 is actually placed in objC
True. But uniformly referencing to const1
which can be declared in objC
or any of its super-interfaces would be even nicer.
Furthermore, code like this would be fully legal, but somewhat confusing ...
Yes. However a sensible example is larger. I can report about the situation in my 'real' code on which I am working currently. But the story is not equally short:
I have a bunch of lexers which are similar to the one in the pfc, but which are customized to languages I want to parse.
The 1st lexer interface is just named lexer
(in a different namespace than the one from the pfc). The interface declares constants for three terminals. These are bof_terminal
, and error_terminal
("bof" stands for Begin Of File). The interface is only an abstract root of my lexers, it has no class implementing it.
My 2nd lexer (interface and class) is alphaLexer
and it supports lexer
. It translates keywords to terminals and additionally declares terminal constants id_terminal
. Where id_terminal
matches the usual upper- and lower-case IDs and op_terminal
matches for example "+", "**", and ":=".
The 3rd lexer is alphaNumLexer
. It additionally declares terminal constants number_terminal
. The fist one matches unsigned integer numerals with arbitrary many digits, the last-mentioned matches unsigned decimal numerals also with arbitrary many digits.
The 4th lexer is strNumLexer
. It additionally declares terminal constants char_terminal
, and further terminals for string literals without ESC-sequence replacement and for unterminated strings.
The 5th lexer is fillerLexer
. It additionally declares terminal constant filler_terminal
. This terminal matches parts of the source text which are surounded by certain terminals which are input to the constructor of the fillerLexer
class. For example filler_terminal
can match a leading part of the text which is surounded by bof_terminal
and a terminal which matches the keyword "begin".
The lexer interfaces/classes mentioned so far are part of my 'code library' (to accompany the pfc, I put it in namespace mfc).
In my application I have another lexer which contains the terminal constants for the application-specific keywords. It supports one of the above lexers and inherits its class. Let's take the worst case, it supports fillerLexer
The situation now is, that when I am writing the grammar rules, I need to refer to all the terminal constants and thus I am putting open qualifications for the application-specific lexer and all its super-lexer-interfaces into my code. I have but the feeling, that these are way too many open qualifications.
The alternative to place all terminal constants together in one file does not seem to be really appealing: In the above construction I never need to update an existant file to introduce new terminals (nor for lexers in the library, neither for lexers in an application). Instead I am just adding subtype interfaces, which is lot more elegant.