One of the issue with the Eiffel syntax is that there are several ones. Indeed a while back the note keyword did not exist, it was `indexing’. As a result we configured the Eiffel parser to handle all of them.
So when parsing, you have to choose which syntax you are going to target. You do that by configuring the parser object as in:
parser.set_syntax_version ({EIFFEL_SCANNER}.provisional_syntax)
Note that EIFFEL_SCANNER defines the following possible syntax:
ecma_syntax: NATURAL_8 = 0x00
-- Syntax strictly follows the ECMA specification
obsolete_syntax: NATURAL_8 = 0x01
-- Allows pre-ECMA keywords and ignore new ECMA keywords such as `note', `attribute', `attached' and `detachable'
transitional_syntax: NATURAL_8 = 0x2
-- Allows both pre and ECMA keywords
provisional_syntax: NATURAL_8 = 0x3
-- ECMA syntax + possible future extensions
This should solve your issue.
Manu
--
For more messaging options, visit this group at http://forum.eiffel.com.
Information on the Eiffelstudio project: http://dev.eiffel.com.
Entering state 550
Reading a token
Next token is 285
Reducing via rule #35
Executing parser user-code from file 'eiffel.y' at line 511
Removing the indexing clause just pushes the same violation down to the parent_list in the inheritance section.
It might be that you are doing it in void-safe mode. We currently only use the Eiffel parser in non-void-safe mode as the rest of the EiffelStudio code. Can you try in non-void-safe mode and see if it works better?
Thanks,
Manu
You must be using void-safe EiffelBase otherwise you would not get the check violation:
Get precondition violation on "has_default" in EIFFEL_LIST.make_filled.
So I should have been more precise, you need to use the non-void-safe versions of libraries as well.
You must be using void-safe EiffelBase otherwise you would not get the check violation:
So I should have been more precise, you need to use the non-void-safe versions of libraries as well.
Manu
Hi,
Once the file is parsed, you can query if the parsing was successful or not, and if it is then you have access to `root_node’ which contains the top level node of the AST.
To regenerate the text from it, then you have to create the parser instance with the AST_ROUNDTRIP_FACTORY which keeps all the whitespaces, and then use the following visitor to output the text back: AST_ROUNDTRIP_PRINTER_VISITOR.
Regards,
Manu
From: Jimmy Johnson [mailto:jjj...@g.uky.edu]
Sent: Tuesday, February 17, 2015 23:03
To: eiffelst...@googlegroups.com
Cc: jjj...@g.uky.edu; ma...@eiffel.com
Subject: Re: [EiffelStudio Dev] Problem adapting eiffel parser
Yes, thank you. Now I can parse a single file. Not sure what I have when done, though. Is there an AST? If so how do I visit the nodes? How complete is the AST? Are create statements, assignment statements, locals, and invariant nodes in the tree?
Once the file is parsed, you can query if the parsing was successful or not, and if it is then you have access to `root_node’ which contains the top level node of the AST.
To regenerate the text from it, then you have to create the parser instance with the AST_ROUNDTRIP_FACTORY which keeps all the whitespaces, and then use the following visitor to output the text back: AST_ROUNDTRIP_PRINTER_VISITOR.
You need to setup the context for `v’ as in:
v.setup (p.root_node, p.match_list, True, True)
and then perform the visite:
v.process_ast_node (visitor.parsed_class)
As for inserting the new code, I think it is best to add it as I mentioned earlier if you want the compiler to generate the code. Modifying the AST is more complicated than adding a new instruction in the generated code.
Manu
From: Jimmy Johnson [mailto:jjj...@g.uky.edu]
Sent: Wednesday, February 18, 2015 20:31
To: eiffelst...@googlegroups.com
Cc: jjj...@g.uky.edu; ma...@eiffel.com
Subject: Re: [EiffelStudio Dev] Problem adapting eiffel parser
Once the file is parsed, you can query if the parsing was successful or not, and if it is then you have access to `root_node’ which contains the top level node of the AST.
As for inserting the new code, I think it is best to add it as I mentioned earlier if you want the compiler to generate the code. Modifying the AST is more complicated than adding a new instruction in the generated code.
Although a scheme like you propose is doable it will be quite complicated since you will need to fiddle with the input buffer of the parser and this can be quite complicated.
Another suggestion is to create a different type of AST node when you encounter an assignment. This requires less modification, just the Eiffel.y file.
But my suggestion is to only change {AST_FEATURE_CHECKER_GENERATOR}.process_assign_as to have the compiler generate exactly what you want.
Regards,
Manu
From: Jimmy Johnson [mailto:jjj...@g.uky.edu]
Sent: Wednesday, February 18, 2015 22:51
To: eiffelst...@googlegroups.com
Cc: jjj...@g.uky.edu; ma...@eiffel.com
Subject: Re: [EiffelStudio Dev] Problem adapting eiffel parser
Thanks I will try that.
Although a scheme like you propose is doable it will be quite complicated since you will need to fiddle with the input buffer of the parser and this can be quite complicated.
Another suggestion is to create a different type of AST node when you encounter an assignment. This requires less modification, just the Eiffel.y file.
But my suggestion is to only change {AST_FEATURE_CHECKER_GENERATOR}.process_assign_as to have the compiler generate exactly what you want.
I’m just going to assume you are performing an unqualified call to a routine of the current class. In this case you get the FEATURE_I from the current class representation CLASS_C and querying feature_named to get the FEATURE_I instance.
If the call is qualified, it is more complicated since you need an object and I do not know from where it is coming from.
Manu
From: Jimmy Johnson [mailto:jjj...@g.uky.edu]
Sent: Thursday, February 19, 2015 23:55
To: eiffelst...@googlegroups.com
Cc: jjj...@g.uky.edu; ma...@eiffel.com
Subject: Re: [EiffelStudio Dev] Problem adapting eiffel parser
I’m just going to assume you are performing an unqualified call to a routine of the current class. In this case you get the FEATURE_I from the current class representation CLASS_C and querying feature_named to get the FEATURE_I instance.
If the call is qualified, it is more complicated since you need an object and I do not know from where it is coming from.
I hope this shows it:
1)
x := y.foobar (z)
becomes
x := y.foobar (z)
if property_holds (Current) and is_attribute (x) then
do_procedure_1 (Current, x)
end
2)
a qualified feature call:
a.f
becomes
a.f
do_procedure_2 (a)
3)
new_keyword a_reference
becomes
do_procedure_3 (a_reference)
if `a_reference’ is non-Void and a non-basic type; otherwise report syntax, type, or validity error.
I assume I can change ANY so that it has a once `Procedure_manager’ from which `property_holds’ and the `do_procedure_x’ features can be accessed, as in:
a.f
Procedure_manager.do_procedure_2 (a)
Ideally, I only want this code added if some class in the system contains “new_keyword”; if not then compile as it does now. Also, the calls to `do_procedure_2’ and `do_procedure_3’ can be (would be best if) delayed until the end of the enclosing feature.
thanks,
jjj
I’m just going to assume you are performing an unqualified call to a routine of the current class. In this case you get the FEATURE_I from the current class representation CLASS_C and querying feature_named to get the FEATURE_I instance.
In another message you said to add a feature call by creating an instance of FEATURE_B in `process_assign_as'. How do I do this? Where do I get the arguments for FEATURE_B.make? How do I create a FEATURE_I, for example, when all I know is the class and feature name of the procedure I want to call?
> 1)
> x := y.foobar (z)
> becomes
> x := y.foobar (z)
> if property_holds (Current) and is_attribute (x) then
> do_procedure_1 (Current, x)
> a qualified feature call:
> a.f
> becomes
> a.f
> new_keyword a_reference
> becomes
> do_procedure_3 (a_reference)
> a.f
new_keyword a_reference
appears inside some other instruction, e.g.
if something then
new_keyword a_reference
end
> 1)
> x := y.foobar (z)
> becomes
> x := y.foobar (z)
> if property_holds (Current) and is_attribute (x) then
> do_procedure_1 (Current, x)
> endIf "property_holds (Current) and is_attribute (x)" is computed at compile time, you just need to add a call to do_procedure_1. It would be like you write:
where "do_procedure_1_feature_i" is the corresponding FEATURE_I for "do_procedure_1" that you can get from CLASS_C using either "feature_of_name_id", "feature_named" or, better, "feature_of_rout_id". The latter is better because it works for inherited/renamed/selected features as well, but then you need to find the feature in its origin by name, lookup for its routine id and then used this id to find an inherited
> Ideally, I only want this code added if some class in the system contains “new_keyword”; if not then compile as it does now.This is possible only when the whole system is recompiled from scratch. If you want your project to be compiled incrementally, there is no other way as to generate the additional code all the time. An alternative would be to use a project option, but this seems to be an overkill at this stage.
--