<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://dev.eiffel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Maser</id>
		<title>EiffelStudio: an EiffelSoftware project - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://dev.eiffel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Maser"/>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/Special:Contributions/Maser"/>
		<updated>2026-04-27T22:56:03Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.24.1</generator>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User:Maser&amp;diff=14321</id>
		<title>User:Maser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User:Maser&amp;diff=14321"/>
				<updated>2011-12-11T13:53:44Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* Martin Luder */ removing my contact information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Martin Luder=&lt;br /&gt;
&lt;br /&gt;
==Work==&lt;br /&gt;
[[Syntax checking]] project&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3995</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3995"/>
				<updated>2006-07-11T08:49:11Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* TODO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
=== Refactoring ===&lt;br /&gt;
* change indirect inheritance of EIFFEL_PARSER_SKELETON via EIFFEL_PARSER_ERROR_REPORTER in EIFFEL_PARSER.&lt;br /&gt;
&lt;br /&gt;
=== report a lot more errors ===&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y / eiffel.l====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* create EIFFEL_SCANNER, EIFFEL_PARSER and EIFFEL_TOKENS from these files using the makefile in $EIFFEL_SRC/Eiffel/parser/parser/&lt;br /&gt;
====EIFFEL_TOKENS====&lt;br /&gt;
* defines the tokens&lt;br /&gt;
====EIFFEL_SCANNER====&lt;br /&gt;
* reads list of tokens from file/string&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
====EIFFEL_PARSER_ERROR_REPORTER====&lt;br /&gt;
* provides error reporting features (report_*)&lt;br /&gt;
====EIFFEL_AST====&lt;br /&gt;
* base class of AST nodes&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== BON diagrams ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Parser ===&lt;br /&gt;
&lt;br /&gt;
[[Image:SynChé BON PARSER.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SYNTAX_MESSAGE descendants ===&lt;br /&gt;
&lt;br /&gt;
[[Image:SynChé BON SYNTAX MESSAGE.png]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3895</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3895"/>
				<updated>2006-06-30T10:27:06Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: added BON diagrams&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y &amp;amp; eiffel.l: merging current file with Paul's (done) ===&lt;br /&gt;
==== didn't work out too good! ====&lt;br /&gt;
* Ueli: 0 - 844: Parent_List (done)&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics (done)&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call (done)&lt;br /&gt;
* Martin: 2131 - end, eiffel.l (done)&lt;br /&gt;
&lt;br /&gt;
=== error handling classes (done) ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== get recoverable parser working in ES (done) ===&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y / eiffel.l====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* create EIFFEL_SCANNER, EIFFEL_PARSER and EIFFEL_TOKENS from these files using the makefile in $EIFFEL_SRC/Eiffel/parser/parser/&lt;br /&gt;
====EIFFEL_TOKENS====&lt;br /&gt;
* defines the tokens&lt;br /&gt;
====EIFFEL_SCANNER====&lt;br /&gt;
* reads list of tokens from file/string&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
====EIFFEL_PARSER_ERROR_REPORTER====&lt;br /&gt;
* provides error reporting features (report_*)&lt;br /&gt;
====EIFFEL_AST====&lt;br /&gt;
* base class of AST nodes&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== BON diagrams ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Parser ===&lt;br /&gt;
&lt;br /&gt;
[[Image:SynChé BON PARSER.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SYNTAX_MESSAGE descendants ===&lt;br /&gt;
&lt;br /&gt;
[[Image:SynChé BON SYNTAX MESSAGE.png]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=File:SynCh%C3%A9_BON_SYNTAX_MESSAGE.png&amp;diff=3894</id>
		<title>File:SynChé BON SYNTAX MESSAGE.png</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=File:SynCh%C3%A9_BON_SYNTAX_MESSAGE.png&amp;diff=3894"/>
				<updated>2006-06-30T10:22:33Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: BON diagram of the syntax message classes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;BON diagram of the syntax message classes&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=File:SynCh%C3%A9_BON_PARSER.png&amp;diff=3893</id>
		<title>File:SynChé BON PARSER.png</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=File:SynCh%C3%A9_BON_PARSER.png&amp;diff=3893"/>
				<updated>2006-06-30T10:21:33Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: BON diagram of the parser library with the changes of the SynChé group&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;BON diagram of the parser library with the changes of the SynChé group&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3860</id>
		<title>Internationalization/plural forms</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Internationalization/plural_forms&amp;diff=3860"/>
				<updated>2006-06-28T13:34:39Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* Rules */ added arabic&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Internationalization]]&lt;br /&gt;
&lt;br /&gt;
The information about the plural form selection has to be stored in the header entry of the PO file (the one with the empty msgid string). The plural form information looks like this: &lt;br /&gt;
::Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1;&lt;br /&gt;
&lt;br /&gt;
The ''nplurals'' value must be a decimal number which specifies how many different plural forms exist for this language. The string following plural is an expression which is using the C language syntax. Exceptions are that no negative numbers are allowed, numbers must be decimal, and the only variable allowed is ''n''. This expression will be evaluated whenever one of the [[internationalization/translation_function|translation function]] for a &amp;quot;plural form&amp;quot; is called. The numeric value passed to these functions is then substituted for all uses of the variable n in the expression. The resulting value then must be greater or equal to zero and smaller than the value given as the value of ''nplurals''.&lt;br /&gt;
&lt;br /&gt;
==Rules==&lt;br /&gt;
The (at this point) known rules are:&lt;br /&gt;
===Only one form===&lt;br /&gt;
&lt;br /&gt;
Some languages only require one single form. There is no distinction between the singular and plural form. An appropriate header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=1; plural=0;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:**Hungarian &lt;br /&gt;
:*Asian family &lt;br /&gt;
:**Japanese, Korean &lt;br /&gt;
:*Turkic/Altaic family &lt;br /&gt;
:**Turkish &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for one only===&lt;br /&gt;
&lt;br /&gt;
This is the form used in most existing programs since it is what English is using. A header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n != 1;&lt;br /&gt;
:::(Note: this uses the feature of C expressions that boolean expressions have to value zero or one.) &lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Germanic family &lt;br /&gt;
:**Danish, Dutch, English, German, Norwegian, Swedish &lt;br /&gt;
:*Finno-Ugric family &lt;br /&gt;
:**Estonian, Finnish &lt;br /&gt;
:*Latin/Greek family &lt;br /&gt;
:**Greek &lt;br /&gt;
:*Semitic family &lt;br /&gt;
:**Hebrew &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:**Italian, Portuguese, Spanish &lt;br /&gt;
:*Artificial &lt;br /&gt;
:**Esperanto &lt;br /&gt;
&lt;br /&gt;
===Two forms, singular used for zero and one===&lt;br /&gt;
&lt;br /&gt;
Exceptional case in the language family. The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=2; plural=n&amp;gt;1;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Romanic family &lt;br /&gt;
:**French, Brazilian Portuguese &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for zero===&lt;br /&gt;
&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : n != 0 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:**Latvian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for one and two===&lt;br /&gt;
The header entry would be: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Celtic &lt;br /&gt;
:**Gaeilge (Irish) &lt;br /&gt;
:*Semitic family&lt;br /&gt;
:**Arabic&lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for numbers ending in 1[2-9]===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::::::n%10&amp;gt;=2 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Baltic family &lt;br /&gt;
:**Lithuanian&lt;br /&gt;
&lt;br /&gt;
===Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:**Croatian, Czech, Russian, Slovak, Ukrainian &lt;br /&gt;
&lt;br /&gt;
===Three forms, special case for one and some numbers ending in 2, 3, or 4===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=3; \&lt;br /&gt;
::plural=n==1 ? 0 : \&lt;br /&gt;
::::n%10&amp;gt;=2 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:**Polish &lt;br /&gt;
&lt;br /&gt;
===Four forms, special case for one and all numbers ending in 02, 03, or 04===&lt;br /&gt;
&lt;br /&gt;
The header entry would look like this: &lt;br /&gt;
 &lt;br /&gt;
:Plural-Forms: nplurals=4; \&lt;br /&gt;
::plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;&lt;br /&gt;
&lt;br /&gt;
:Languages with this property include: &lt;br /&gt;
:*Slavic family &lt;br /&gt;
:**Slovenian&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3800</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3800"/>
				<updated>2006-06-26T14:42:02Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* eiffel.y &amp;amp; eiffel.l: merging current file with Paul's */ done&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y &amp;amp; eiffel.l: merging current file with Paul's (done) ===&lt;br /&gt;
==== didn't work out too good! ====&lt;br /&gt;
* Ueli: 0 - 844: Parent_List (done)&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics (done)&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call (done)&lt;br /&gt;
* Martin: 2131 - end, eiffel.l (done)&lt;br /&gt;
&lt;br /&gt;
=== error handling classes (done) ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== get recoverable parser working in ES (done) ===&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y / eiffel.l====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* create EIFFEL_SCANNER, EIFFEL_PARSER and EIFFEL_TOKENS from these files using the makefile in $EIFFEL_SRC/Eiffel/parser/parser/&lt;br /&gt;
====EIFFEL_TOKENS====&lt;br /&gt;
* defines the tokens&lt;br /&gt;
====EIFFEL_SCANNER====&lt;br /&gt;
* reads list of tokens from file/string&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
====EIFFEL_PARSER_ERROR_REPORTER====&lt;br /&gt;
* provides error reporting features (report_*)&lt;br /&gt;
====EIFFEL_AST====&lt;br /&gt;
* base class of AST nodes&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3779</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3779"/>
				<updated>2006-06-25T17:11:25Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* TODO */ updated&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y &amp;amp; eiffel.l: merging current file with Paul's===&lt;br /&gt;
==== didn't work out too good! ====&lt;br /&gt;
* Ueli: 0 - 844: Parent_List (done)&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics (done)&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call (done)&lt;br /&gt;
* Martin: 2131 - end, eiffel.l (done)&lt;br /&gt;
&lt;br /&gt;
=== error handling classes (done) ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== get recoverable parser working in ES (done) ===&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y / eiffel.l====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* create EIFFEL_SCANNER, EIFFEL_PARSER and EIFFEL_TOKENS from these files using the makefile in $EIFFEL_SRC/Eiffel/parser/parser/&lt;br /&gt;
====EIFFEL_TOKENS====&lt;br /&gt;
* defines the tokens&lt;br /&gt;
====EIFFEL_SCANNER====&lt;br /&gt;
* reads list of tokens from file/string&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
====EIFFEL_PARSER_ERROR_REPORTER====&lt;br /&gt;
* provides error reporting features (report_*)&lt;br /&gt;
====EIFFEL_AST====&lt;br /&gt;
* base class of AST nodes&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3668</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3668"/>
				<updated>2006-06-21T12:28:23Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: moved TODO to the top&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y &amp;amp; eiffel.l: merging current file with Paul's===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List (done)&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics (done)&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call (done)&lt;br /&gt;
* Martin: 2131 - end, eiffel.l (done)&lt;br /&gt;
&lt;br /&gt;
=== error handling classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== correct bugs in parser (that we introduced) ===&lt;br /&gt;
&lt;br /&gt;
=== get recoverable parser working in ES ===&lt;br /&gt;
&lt;br /&gt;
=== extend/improve error reporting ===&lt;br /&gt;
There will probably be not enough time to do this.&lt;br /&gt;
* there's no error reporting with TUPLEs yet&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y / eiffel.l====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* create EIFFEL_SCANNER, EIFFEL_PARSER and EIFFEL_TOKENS from these files using the makefile in $EIFFEL_SRC/Eiffel/parser/parser/&lt;br /&gt;
====EIFFEL_TOKENS====&lt;br /&gt;
* defines the tokens&lt;br /&gt;
====EIFFEL_SCANNER====&lt;br /&gt;
* reads list of tokens from file/string&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
====EIFFEL_PARSER_ERROR_REPORTER====&lt;br /&gt;
* provides error reporting features (report_*)&lt;br /&gt;
====EIFFEL_AST====&lt;br /&gt;
* base class of AST nodes&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3667</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3667"/>
				<updated>2006-06-21T12:27:06Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* Important Classes/Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y / eiffel.l====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* create EIFFEL_SCANNER, EIFFEL_PARSER and EIFFEL_TOKENS from these files using the makefile in $EIFFEL_SRC/Eiffel/parser/parser/&lt;br /&gt;
====EIFFEL_TOKENS====&lt;br /&gt;
* defines the tokens&lt;br /&gt;
====EIFFEL_SCANNER====&lt;br /&gt;
* reads list of tokens from file/string&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
====EIFFEL_PARSER_ERROR_REPORTER====&lt;br /&gt;
* provides error reporting features (report_*)&lt;br /&gt;
====EIFFEL_AST====&lt;br /&gt;
* base class of AST nodes&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y &amp;amp; eiffel.l: merging current file with Paul's===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List (done)&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics (done)&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call (done)&lt;br /&gt;
* Martin: 2131 - end, eiffel.l (done)&lt;br /&gt;
&lt;br /&gt;
=== error handling classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== correct bugs in parser (that we introduced) ===&lt;br /&gt;
&lt;br /&gt;
=== get recoverable parser working in ES ===&lt;br /&gt;
&lt;br /&gt;
=== extend/improve error reporting ===&lt;br /&gt;
There will probably be not enough time to do this.&lt;br /&gt;
* there's no error reporting with TUPLEs yet&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3666</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3666"/>
				<updated>2006-06-21T12:21:56Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* Implementation */ removed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y &amp;amp; eiffel.l: merging current file with Paul's===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List (done)&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics (done)&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call (done)&lt;br /&gt;
* Martin: 2131 - end, eiffel.l (done)&lt;br /&gt;
&lt;br /&gt;
=== error handling classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== correct bugs in parser (that we introduced) ===&lt;br /&gt;
&lt;br /&gt;
=== get recoverable parser working in ES ===&lt;br /&gt;
&lt;br /&gt;
=== extend/improve error reporting ===&lt;br /&gt;
There will probably be not enough time to do this.&lt;br /&gt;
* there's no error reporting with TUPLEs yet&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3665</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3665"/>
				<updated>2006-06-21T12:19:00Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* TODO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y &amp;amp; eiffel.l: merging current file with Paul's===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List (done)&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics (done)&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call (done)&lt;br /&gt;
* Martin: 2131 - end, eiffel.l (done)&lt;br /&gt;
&lt;br /&gt;
=== error handling classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== correct bugs in parser (that we introduced) ===&lt;br /&gt;
&lt;br /&gt;
=== get recoverable parser working in ES ===&lt;br /&gt;
&lt;br /&gt;
=== extend/improve error reporting ===&lt;br /&gt;
There will probably be not enough time to do this.&lt;br /&gt;
* there's no error reporting with TUPLEs yet&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking&amp;diff=3650</id>
		<title>Syntax checking</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking&amp;diff=3650"/>
				<updated>2006-06-20T16:32:41Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* M6: June 27th */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
=Overview=&lt;br /&gt;
The aim of this project is to provide adequate, but non intrusive feedback to user about syntax errors. This is done by checking syntax as you type and underlining syntax errors by the well knwon wavy red line. Furthermore, error descriptions and possible solutions should be provided.&lt;br /&gt;
&lt;br /&gt;
The Project is named '''SynChé''', which is a combination of syntax and checking.&lt;br /&gt;
The ''é'' at the end is important, as a cool name needs either a recursive acronym or a special character from a non English language.&lt;br /&gt;
&lt;br /&gt;
=Software Requirement Specification (SRS)=&lt;br /&gt;
You can find our SRS [[Syntax_checking/SRS|here]]&lt;br /&gt;
&lt;br /&gt;
=Groups=&lt;br /&gt;
&lt;br /&gt;
* [[Syntax_checking/Visualisation|Visualisation]]&lt;br /&gt;
* [[Syntax_checking/Parser|Parser]]&lt;br /&gt;
&lt;br /&gt;
=Milestones=&lt;br /&gt;
&lt;br /&gt;
==M1: April 25th==&lt;br /&gt;
* Get home-grown EiffelStudio up and running.&lt;br /&gt;
&lt;br /&gt;
==M2: May 2nd==&lt;br /&gt;
* '''Put your name in this Wiki!'''&lt;br /&gt;
* Analyse source code to certain degree, so discussion about interfaces between parser and visual is possible&lt;br /&gt;
&lt;br /&gt;
==M3: May 9th==&lt;br /&gt;
* SRS written&lt;br /&gt;
* Overview of relevant classes (BON diagram or more)&lt;br /&gt;
* Further Project Milestones specified, based on SRS and knowledge about code&lt;br /&gt;
&lt;br /&gt;
== May 12th == &lt;br /&gt;
'''Results of the Meeting:''' [[Syntax_checking/Visualisation| Visualisation]]&lt;br /&gt;
&lt;br /&gt;
== May 17th == &lt;br /&gt;
'''Results of Parser Group:''' [[Syntax_checking/Parser| Parser]]&lt;br /&gt;
&lt;br /&gt;
==M4: May 23rd==&lt;br /&gt;
*'''Parser Group''': Find out what results you get from the parser&lt;br /&gt;
*'''Visualisation Group''': Write a feature that draw the red underline&lt;br /&gt;
&lt;br /&gt;
==M6: June 27th==&lt;br /&gt;
*'''Parser Group''': Multi Error Parser (don't stop parsing after first error encountered)&lt;br /&gt;
*'''Visualisation Group''': Draw the mouseover boxes; find how to use stones (especially x,y coordinates -&amp;gt; stones/tokens); collect all parser errors into information window on bottom&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
Everyone intrested in this project is welcome to join our mailinglist [http://origo.ethz.ch/cgi-bin/mailman/listinfo/es-ui es-ui@origo.ethz.ch]. &lt;br /&gt;
At this point, the team is divided into two groups at this point, one responsible for the parser, the other one for visual feedback (like underlininig).&lt;br /&gt;
&lt;br /&gt;
== Visual Feedback ==&lt;br /&gt;
* [[User:jabernet| Janick Bernet]] (project leader)&lt;br /&gt;
* [[User:fdevries| Fabien de Vries]]&lt;br /&gt;
* [[User:indermum| Matthias Indermühle]]&lt;br /&gt;
* [[User:clerco| Olivier Clerc]]&lt;br /&gt;
&lt;br /&gt;
== Parser ==&lt;br /&gt;
* [[User:maser| Martin Luder]]&lt;br /&gt;
* [[User:Chrigu| Christoph Huber]]&lt;br /&gt;
* [[User:goalgettah| Ueli Etter]]&lt;br /&gt;
* [[User:Squeezie| Michael Schär]]&lt;br /&gt;
* [[User:MarkoR| Marko Ristin]]&lt;br /&gt;
&lt;br /&gt;
== Assistant ==&lt;br /&gt;
* [[User:classens| Stephan Classen]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking&amp;diff=3475</id>
		<title>Syntax checking</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking&amp;diff=3475"/>
				<updated>2006-06-15T13:07:44Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* M4: May 23rd */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
=Overview=&lt;br /&gt;
The aim of this project is to provide adequate, but non intrusive feedback to user about syntax errors. This is done by checking syntax as you type and underlining syntax errors by the well knwon wavy red line. Furthermore, error descriptions and possible solutions should be provided.&lt;br /&gt;
&lt;br /&gt;
The Project is named '''SynChé''', which is a combination of syntax and checking.&lt;br /&gt;
The ''é'' at the end is important, as a cool name needs either a recursive acronym or a special character from a non English language.&lt;br /&gt;
&lt;br /&gt;
=Software Requirement Specification (SRS)=&lt;br /&gt;
You can find our SRS [[Syntax_checking/SRS|here]]&lt;br /&gt;
&lt;br /&gt;
=Groups=&lt;br /&gt;
&lt;br /&gt;
* [[Syntax_checking/Visualisation|Visualisation]]&lt;br /&gt;
* [[Syntax_checking/Parser|Parser]]&lt;br /&gt;
&lt;br /&gt;
=Milestones=&lt;br /&gt;
&lt;br /&gt;
==M1: April 25th==&lt;br /&gt;
* Get home-grown EiffelStudio up and running.&lt;br /&gt;
&lt;br /&gt;
==M2: May 2nd==&lt;br /&gt;
* '''Put your name in this Wiki!'''&lt;br /&gt;
* Analyse source code to certain degree, so discussion about interfaces between parser and visual is possible&lt;br /&gt;
&lt;br /&gt;
==M3: May 9th==&lt;br /&gt;
* SRS written&lt;br /&gt;
* Overview of relevant classes (BON diagram or more)&lt;br /&gt;
* Further Project Milestones specified, based on SRS and knowledge about code&lt;br /&gt;
&lt;br /&gt;
== May 12th == &lt;br /&gt;
'''Results of the Meeting:''' [[Syntax_checking/Visualisation| Visualisation]]&lt;br /&gt;
&lt;br /&gt;
== May 17th == &lt;br /&gt;
'''Results of Parser Group:''' [[Syntax_checking/Parser| Parser]]&lt;br /&gt;
&lt;br /&gt;
==M4: May 23rd==&lt;br /&gt;
*'''Parser Group''': Find out what results you get from the parser&lt;br /&gt;
*'''Visualisation Group''': Write a feature that draw the red underline&lt;br /&gt;
&lt;br /&gt;
==M6: June 15th==&lt;br /&gt;
*'''Parser Group''': Multi Error Parser (don't stop parsing after first error encountered)&lt;br /&gt;
*'''Visualisation Group''': Draw the mouseover boxes; find how to use stones (especially x,y coordinates -&amp;gt; stones/tokens); collect all parser errors into information window on bottom&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
Everyone intrested in this project is welcome to join our mailinglist [http://origo.ethz.ch/cgi-bin/mailman/listinfo/es-ui es-ui@origo.ethz.ch]. &lt;br /&gt;
At this point, the team is divided into two groups at this point, one responsible for the parser, the other one for visual feedback (like underlininig).&lt;br /&gt;
&lt;br /&gt;
== Visual Feedback ==&lt;br /&gt;
* [[User:jabernet| Janick Bernet]] (project leader)&lt;br /&gt;
* [[User:fdevries| Fabien de Vries]]&lt;br /&gt;
* [[User:indermum| Matthias Indermühle]]&lt;br /&gt;
* [[User:clerco| Olivier Clerc]]&lt;br /&gt;
&lt;br /&gt;
== Parser ==&lt;br /&gt;
* [[User:maser| Martin Luder]]&lt;br /&gt;
* [[User:Chrigu| Christoph Huber]]&lt;br /&gt;
* [[User:goalgettah| Ueli Etter]]&lt;br /&gt;
* [[User:Squeezie| Michael Schär]]&lt;br /&gt;
* [[User:MarkoR| Marko Ristin]]&lt;br /&gt;
&lt;br /&gt;
== Assistant ==&lt;br /&gt;
* [[User:classens| Stephan Classen]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3329</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3329"/>
				<updated>2006-06-12T16:19:51Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* classes with errors to check if parser works */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distribution==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end (done)&lt;br /&gt;
&lt;br /&gt;
=== eiffel.l ===&lt;br /&gt;
* Martin: added TE_BAD_ID (done)&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3328</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3328"/>
				<updated>2006-06-12T16:19:31Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* Tools */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distribution==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end (done)&lt;br /&gt;
&lt;br /&gt;
=== eiffel.l ===&lt;br /&gt;
* Martin: added TE_BAD_ID (done)&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [[http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post]] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [http://meld.sourceforge.net/ meld]&lt;br /&gt;
* [http://furius.ca/xxdiff/ xxdiff]&lt;br /&gt;
* [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3327</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3327"/>
				<updated>2006-06-12T16:19:16Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* creating a project that uses the parser */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
* [http://n.ethz.ch/student/luderm/es/root_class.e example of an application that uses the parser]&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distribution==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end (done)&lt;br /&gt;
&lt;br /&gt;
=== eiffel.l ===&lt;br /&gt;
* Martin: added TE_BAD_ID (done)&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [[http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post]] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [[http://meld.sourceforge.net/ meld]]&lt;br /&gt;
* [[http://furius.ca/xxdiff/ xxdiff]]&lt;br /&gt;
* [[http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=3326</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=3326"/>
				<updated>2006-06-12T16:14:57Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* acex for parser application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ERROR classes in Paul's code aren't compatible with the ones in the current version (mainly the versions of SYNTAX_ERROR and SYNTAX_MESSAGE are quite different). &lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:54, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That's correct. The existing error classes did not support everything they needed to support, so I reworte them. If you actually look at the parser error/warning classes in the parser cluster (not EiffelStudio's error classes) you'll see that the warning class is not even implemented!&lt;br /&gt;
&lt;br /&gt;
As I said, the parser is a stand-alone library. The parser cluster was only moved under Src/Eiffel for ease to users to check out and compile Eiffel. In that respect you should just create an application that uses the parser library, as I did. I then sent a generated error string, from the error classes, to the the command-line shell.&lt;br /&gt;
&lt;br /&gt;
[[User:Paulb|Paulb]] 22:14, 20 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm not sure if I understand what you mean. Basically, I should be able to take just the parser cluster and write a program that parses Eiffel files? But that's not possible, because EIFFEL_PARSER_SKELETON inherits from SHARED_ERROR_HANDLER, which is in the compiler cluster. Also, the error/warning classes in the parser cluster aren't used in ES, only the ones in the compiler cluster. I'd really like to create an application that uses the parser library, but I don't understand how it's going to work without the compiler cluster.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 01:38, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you take the configuration file parser.ecf in $EIFFEL_SRC/Eiffel/parser then it should include all you need.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 19:30, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Oh, you're right, everything's there, I just didn't see it. I could create a new project based on that file and it seems like there's really a lot to do in the ERROR classes.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:36, 22 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I didn't look into it too much, but the ERROR classes can do some stuff with TEXT_FORMATTERs (several elements of the GUI inherit from TEXT_FORMATTER) which could be useful to display information about the ERROR.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 02:22, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== suggestion for implementation ==&lt;br /&gt;
&lt;br /&gt;
I've added a suggestion how to implement our changes. How bad is it? Comments? Improvements?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:35, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
It's not bad, it sounds good ;)&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 12:39, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== acex for parser application ==&lt;br /&gt;
&lt;br /&gt;
I've uploaded a [http://n.ethz.ch/student/luderm/parser.acex parser.acex] (Edit: removed, there's information on this topic in [[Syntax checking/Parser]]). You can also use parser.ecf file in Eiffel/parser/ in the current trunk as Manu pointed out.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 17:01, 23 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== error classes ==&lt;br /&gt;
&lt;br /&gt;
I've studied Paul's error classes. They all inherit of syntax_error. And they can be called by the eiffel_parser_error_reporter. But where you decide, which class you should choose to represent the error?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 13:18, 5 June 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It's decided in eiffel.y, as far as I know. There's a 'report_*' feature for each error class and in the eiffel.y the appropriate one is called with the right string from the EIFFEL_PARSER_ERRORS class.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 13:54, 5 June 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3325</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3325"/>
				<updated>2006-06-12T16:12:32Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: added walkthrough for using the parser library&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== creating a project that uses the parser ==&lt;br /&gt;
The new build (June 11 2006) finally has the new system configuration GUI. It's quite easy to create a project that uses the parser:&lt;br /&gt;
# set ISE_LIBRARY to your checkout (ie. the directory that contains the 'library' subdirectory)&lt;br /&gt;
# start EiffelStudio and create a new project&lt;br /&gt;
# open Project &amp;gt; Project settings...&lt;br /&gt;
# go to Target &amp;gt; Group (on the left)&lt;br /&gt;
# click on the library icon (the one with books on it) and add the gobo library&lt;br /&gt;
# click on the icon again, type 'parser' in the Name field and set the location to $ISE_LIBRARY/Eiffel/parser/parser.ecf&lt;br /&gt;
&lt;br /&gt;
Now you can use the parser.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distribution==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end (done)&lt;br /&gt;
&lt;br /&gt;
=== eiffel.l ===&lt;br /&gt;
* Martin: added TE_BAD_ID (done)&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [[http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post]] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [[http://meld.sourceforge.net/ meld]]&lt;br /&gt;
* [[http://furius.ca/xxdiff/ xxdiff]]&lt;br /&gt;
* [[http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3322</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3322"/>
				<updated>2006-06-12T14:13:24Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* classes with errors to check if parser works */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distribution==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end (done)&lt;br /&gt;
&lt;br /&gt;
=== eiffel.l ===&lt;br /&gt;
* Martin: added TE_BAD_ID (done)&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* See [[http://origo.ethz.ch/pipermail/es-devel/2006-June/000372.html this post]] on the es-devel mailing list. It's probably better to wait, as we don't really have too much time left.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [[http://meld.sourceforge.net/ meld]]&lt;br /&gt;
* [[http://furius.ca/xxdiff/ xxdiff]]&lt;br /&gt;
* [[http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3321</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3321"/>
				<updated>2006-06-12T13:27:22Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: added information on eiffel.y and some examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distribution==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end (done)&lt;br /&gt;
&lt;br /&gt;
=== eiffel.l ===&lt;br /&gt;
* Martin: added TE_BAD_ID (done)&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* nobody yet&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [[http://meld.sourceforge.net/ meld]]&lt;br /&gt;
* [[http://furius.ca/xxdiff/ xxdiff]]&lt;br /&gt;
* [[http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]]&lt;br /&gt;
&lt;br /&gt;
== Grammar definition file (eiffel.y) ==&lt;br /&gt;
&lt;br /&gt;
some general information:&lt;br /&gt;
* capitalized names like TE_STR_LT are tokens. Search for them in eiffel.l (lower case L):&lt;br /&gt;
  \&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot;		{				&lt;br /&gt;
  				ast_factory.set_buffer (token_buffer2, Current)&lt;br /&gt;
  				last_token := TE_STR_LT&lt;br /&gt;
 			}&lt;br /&gt;
So TE_STR_LT corresponds to '&amp;lt;' (\&amp;quot;&amp;quot;&amp;lt;&amp;quot;\&amp;quot; is a regular expression)&lt;br /&gt;
* all other names are non-terminals, so you can find them in eiffel.y. If you don't know what a non-terminal means, you can always look it up in eiffel.y or ask the person responsible for that part of the file.&lt;br /&gt;
&lt;br /&gt;
=== changes ===&lt;br /&gt;
There are several types of changes we can do to the eiffel.y file while merging Paul's eiffel.y and the current eiffel.y:&lt;br /&gt;
&lt;br /&gt;
==== renaming ====&lt;br /&gt;
This doesn't really change the functionality and shouldn't really be a problem.&lt;br /&gt;
&lt;br /&gt;
Example: Paul renamed infix_operator to infix_string (for whatever reasons).&lt;br /&gt;
&lt;br /&gt;
==== new non-terminals ====&lt;br /&gt;
new Non-terminals are introduced because they simplify an existing rule or simplify error handling.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	TE_EMPTY_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
changed to:&lt;br /&gt;
  Default_manifest_string: &lt;br /&gt;
  		Non_empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	|	Empty_string&lt;br /&gt;
  			{ $$ := $1 }&lt;br /&gt;
  	;&lt;br /&gt;
  &lt;br /&gt;
  Empty_string: &lt;br /&gt;
 		TE_EMPTY_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_string_as (&amp;quot;&amp;quot;, line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
  	|	TE_EMPTY_VERBATIM_STRING&lt;br /&gt;
  			{ $$ := ast_factory.new_verbatim_string_as (&amp;quot;&amp;quot;, verbatim_marker.substring (2, verbatim_marker.count), not has_old_verbatim_strings and then verbatim_marker.item (1) = ']', line, column, string_position, position + text_count - string_position, token_buffer2) }&lt;br /&gt;
 	;&lt;br /&gt;
&lt;br /&gt;
==== new rules for error handling ====&lt;br /&gt;
Rules added to non-terminals to do error handling&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's Obsolete non-terminal:&lt;br /&gt;
&lt;br /&gt;
  Obsolete: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_OBSOLETE Manifest_string&lt;br /&gt;
  			{&lt;br /&gt;
  				$$ := ast_factory.new_keyword_string_pair ($1, $2)&lt;br /&gt;
  			}&lt;br /&gt;
  	|	TE_OBSOLETE error { report_expected_after_error (parser_errors.obsolete_keyword, $1, parser_errors.obsolete_string, False) }&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
==== changed error handling ====&lt;br /&gt;
Already existing error handling in eiffel.y is usually longer than Paul's error handling. That's mainly because he put that code into features.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
current version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				if has_syntax_warning then&lt;br /&gt;
  					Error_handler.insert_warning (&lt;br /&gt;
  						create {SYNTAX_WARNING}.make (line, column, filename,&lt;br /&gt;
  						&amp;quot;Use `inherit ANY' or do not specify an empty inherit clause&amp;quot;))&lt;br /&gt;
  				end&lt;br /&gt;
  				--- $$ := Void&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;br /&gt;
&lt;br /&gt;
Paul's version:&lt;br /&gt;
&lt;br /&gt;
  Inheritance: -- Empty&lt;br /&gt;
  			-- { $$ := Void }&lt;br /&gt;
  	|	TE_INHERIT ASemi&lt;br /&gt;
  			{&lt;br /&gt;
  				report_warning (parser_errors.empty_inherit_clause_warning, Void)&lt;br /&gt;
  				$$ := ast_factory.new_eiffel_list_parent_as (0)&lt;br /&gt;
  				if $$ /= Void then&lt;br /&gt;
  					$$.set_inherit_keyword ($1)&lt;br /&gt;
  				end&lt;br /&gt;
  			}&lt;br /&gt;
  	[...]&lt;br /&gt;
  	;&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3287</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3287"/>
				<updated>2006-06-09T12:43:04Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* eiffel.y */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distribution==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end (done)&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* nobody yet&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [[http://meld.sourceforge.net/ meld]]&lt;br /&gt;
* [[http://furius.ca/xxdiff/ xxdiff]]&lt;br /&gt;
* [[http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3286</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3286"/>
				<updated>2006-06-09T12:33:36Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* Work distribution */ typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distribution==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* nobody yet&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [[http://meld.sourceforge.net/ meld]]&lt;br /&gt;
* [[http://furius.ca/xxdiff/ xxdiff]]&lt;br /&gt;
* [[http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3196</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3196"/>
				<updated>2006-06-06T11:10:40Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* Tools */  added geyacc&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distributiony==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* nobody yet&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [[http://meld.sourceforge.net/ meld]]&lt;br /&gt;
* [[http://furius.ca/xxdiff/ xxdiff]]&lt;br /&gt;
* [[http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3195</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3195"/>
				<updated>2006-06-06T11:09:56Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: added links to tools&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distributiony==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* nobody yet&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
* [[http://meld.sourceforge.net/ meld]]&lt;br /&gt;
* [[http://furius.ca/xxdiff/ xxdiff]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3193</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3193"/>
				<updated>2006-06-05T21:43:40Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* EIFFEL_PARSER */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
** AST_NULL_FACTORY doesn't build an AST (AST_FACTORY does, the AST is in EIFFEL_PARSER.root_node after parsing)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING).&lt;br /&gt;
&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distributiony==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* nobody yet&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=3179</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=3179"/>
				<updated>2006-06-05T11:54:24Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* error classes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ERROR classes in Paul's code aren't compatible with the ones in the current version (mainly the versions of SYNTAX_ERROR and SYNTAX_MESSAGE are quite different). &lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:54, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That's correct. The existing error classes did not support everything they needed to support, so I reworte them. If you actually look at the parser error/warning classes in the parser cluster (not EiffelStudio's error classes) you'll see that the warning class is not even implemented!&lt;br /&gt;
&lt;br /&gt;
As I said, the parser is a stand-alone library. The parser cluster was only moved under Src/Eiffel for ease to users to check out and compile Eiffel. In that respect you should just create an application that uses the parser library, as I did. I then sent a generated error string, from the error classes, to the the command-line shell.&lt;br /&gt;
&lt;br /&gt;
[[User:Paulb|Paulb]] 22:14, 20 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm not sure if I understand what you mean. Basically, I should be able to take just the parser cluster and write a program that parses Eiffel files? But that's not possible, because EIFFEL_PARSER_SKELETON inherits from SHARED_ERROR_HANDLER, which is in the compiler cluster. Also, the error/warning classes in the parser cluster aren't used in ES, only the ones in the compiler cluster. I'd really like to create an application that uses the parser library, but I don't understand how it's going to work without the compiler cluster.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 01:38, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you take the configuration file parser.ecf in $EIFFEL_SRC/Eiffel/parser then it should include all you need.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 19:30, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Oh, you're right, everything's there, I just didn't see it. I could create a new project based on that file and it seems like there's really a lot to do in the ERROR classes.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:36, 22 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I didn't look into it too much, but the ERROR classes can do some stuff with TEXT_FORMATTERs (several elements of the GUI inherit from TEXT_FORMATTER) which could be useful to display information about the ERROR.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 02:22, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== suggestion for implementation ==&lt;br /&gt;
&lt;br /&gt;
I've added a suggestion how to implement our changes. How bad is it? Comments? Improvements?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:35, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
It's not bad, it sounds good ;)&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 12:39, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== acex for parser application ==&lt;br /&gt;
&lt;br /&gt;
I've uploaded a [http://n.ethz.ch/student/luderm/parser.acex parser.acex] (why can't I upload it to the wiki?). You can also use parser.ecf file in Eiffel/parser/ in the current trunk as Manu pointed out.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 17:01, 23 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== error classes ==&lt;br /&gt;
&lt;br /&gt;
I've studied Paul's error classes. They all inherit of syntax_error. And they can be called by the eiffel_parser_error_reporter. But where you decide, which class you should choose to represent the error?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 13:18, 5 June 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It's decided in eiffel.y, as far as I know. There's a 'report_*' feature for each error class and in the eiffel.y the appropriate one is called with the right string from the EIFFEL_PARSER_ERRORS class.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 13:54, 5 June 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3131</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3131"/>
				<updated>2006-06-01T11:47:32Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING): Both save the results in match_list: LEAF_AS_LIST.&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Work distributiony==&lt;br /&gt;
&lt;br /&gt;
=== eiffel.y ===&lt;br /&gt;
* Ueli: 0 - 844: Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end&lt;br /&gt;
&lt;br /&gt;
=== error classes ===&lt;br /&gt;
*Chrigu&lt;br /&gt;
&lt;br /&gt;
=== classes with errors to check if parser works ===&lt;br /&gt;
* nobody yet&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3121</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=3121"/>
				<updated>2006-06-01T10:48:50Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: work distribution&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING): Both save the results in match_list: LEAF_AS_LIST.&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;br /&gt;
&lt;br /&gt;
== Work distribution in eiffel.y==&lt;br /&gt;
&lt;br /&gt;
* Ueli: 0 - 844: before Parent_List&lt;br /&gt;
* Marko: 845 - 1494 Formal Generics&lt;br /&gt;
* Michi: 1495 - 2130 Instruction Call&lt;br /&gt;
* Martin: 2131 - end&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=3006</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=3006"/>
				<updated>2006-05-23T15:01:30Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: acex for parser application&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ERROR classes in Paul's code aren't compatible with the ones in the current version (mainly the versions of SYNTAX_ERROR and SYNTAX_MESSAGE are quite different). &lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:54, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That's correct. The existing error classes did not support everything they needed to support, so I reworte them. If you actually look at the parser error/warning classes in the parser cluster (not EiffelStudio's error classes) you'll see that the warning class is not even implemented!&lt;br /&gt;
&lt;br /&gt;
As I said, the parser is a stand-alone library. The parser cluster was only moved under Src/Eiffel for ease to users to check out and compile Eiffel. In that respect you should just create an application that uses the parser library, as I did. I then sent a generated error string, from the error classes, to the the command-line shell.&lt;br /&gt;
&lt;br /&gt;
[[User:Paulb|Paulb]] 22:14, 20 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm not sure if I understand what you mean. Basically, I should be able to take just the parser cluster and write a program that parses Eiffel files? But that's not possible, because EIFFEL_PARSER_SKELETON inherits from SHARED_ERROR_HANDLER, which is in the compiler cluster. Also, the error/warning classes in the parser cluster aren't used in ES, only the ones in the compiler cluster. I'd really like to create an application that uses the parser library, but I don't understand how it's going to work without the compiler cluster.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 01:38, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you take the configuration file parser.ecf in $EIFFEL_SRC/Eiffel/parser then it should include all you need.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 19:30, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Oh, you're right, everything's there, I just didn't see it. I could create a new project based on that file and it seems like there's really a lot to do in the ERROR classes.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:36, 22 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I didn't look into it too much, but the ERROR classes can do some stuff with TEXT_FORMATTERs (several elements of the GUI inherit from TEXT_FORMATTER) which could be useful to display information about the ERROR.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 02:22, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== suggestion for implementation ==&lt;br /&gt;
&lt;br /&gt;
I've added a suggestion how to implement our changes. How bad is it? Comments? Improvements?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:35, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
It's not bad, it sounds good ;)&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 12:39, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== acex for parser application ==&lt;br /&gt;
&lt;br /&gt;
I've uploaded a [http://n.ethz.ch/student/luderm/parser.acex parser.acex] (why can't I upload it to the wiki?). You can also use parser.ecf file in Eiffel/parser/ in the current trunk as Manu pointed out.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 17:01, 23 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2981</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2981"/>
				<updated>2006-05-21T22:36:31Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* find more than one error */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ERROR classes in Paul's code aren't compatible with the ones in the current version (mainly the versions of SYNTAX_ERROR and SYNTAX_MESSAGE are quite different). &lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:54, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That's correct. The existing error classes did not support everything they needed to support, so I reworte them. If you actually look at the parser error/warning classes in the parser cluster (not EiffelStudio's error classes) you'll see that the warning class is not even implemented!&lt;br /&gt;
&lt;br /&gt;
As I said, the parser is a stand-alone library. The parser cluster was only moved under Src/Eiffel for ease to users to check out and compile Eiffel. In that respect you should just create an application that uses the parser library, as I did. I then sent a generated error string, from the error classes, to the the command-line shell.&lt;br /&gt;
&lt;br /&gt;
[[User:Paulb|Paulb]] 22:14, 20 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm not sure if I understand what you mean. Basically, I should be able to take just the parser cluster and write a program that parses Eiffel files? But that's not possible, because EIFFEL_PARSER_SKELETON inherits from SHARED_ERROR_HANDLER, which is in the compiler cluster. Also, the error/warning classes in the parser cluster aren't used in ES, only the ones in the compiler cluster. I'd really like to create an application that uses the parser library, but I don't understand how it's going to work without the compiler cluster.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 01:38, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you take the configuration file parser.ecf in $EIFFEL_SRC/Eiffel/parser then it should include all you need.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 19:30, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Oh, you're right, everything's there, I just didn't see it. I could create a new project based on that file and it seems like there's really a lot to do in the ERROR classes.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:36, 22 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I didn't look into it too much, but the ERROR classes can do some stuff with TEXT_FORMATTERs (several elements of the GUI inherit from TEXT_FORMATTER) which could be useful to display information about the ERROR.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 02:22, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== suggestion for implementation ==&lt;br /&gt;
&lt;br /&gt;
I've added a suggestion how to implement our changes. How bad is it? Comments? Improvements?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:35, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
It's not bad, it sounds good ;)&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 12:39, 21 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2980</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2980"/>
				<updated>2006-05-21T22:04:22Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* find more than one error */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ERROR classes in Paul's code aren't compatible with the ones in the current version (mainly the versions of SYNTAX_ERROR and SYNTAX_MESSAGE are quite different). &lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:54, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That's correct. The existing error classes did not support everything they needed to support, so I reworte them. If you actually look at the parser error/warning classes in the parser cluster (not EiffelStudio's error classes) you'll see that the warning class is not even implemented!&lt;br /&gt;
&lt;br /&gt;
As I said, the parser is a stand-alone library. The parser cluster was only moved under Src/Eiffel for ease to users to check out and compile Eiffel. In that respect you should just create an application that uses the parser library, as I did. I then sent a generated error string, from the error classes, to the the command-line shell.&lt;br /&gt;
&lt;br /&gt;
[[User:Paulb|Paulb]] 22:14, 20 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm not sure if I understand what you mean. Basically, I should be able to take just the parser cluster and write a program that parses Eiffel files? But that's not possible, because EIFFEL_PARSER_SKELETON inherits from SHARED_ERROR_HANDLER, which is in the compiler cluster. Also, the error/warning classes in the parser cluster aren't used in ES, only the ones in the compiler cluster. I'd really like to create an application that uses the parser library, but I don't understand how it's going to work without the compiler cluster.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 01:38, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you take the configuration file parser.ecf in $EIFFEL_SRC/Eiffel/parser then it should include all you need.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 19:30, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Oh, you're right, everything's there, I just didn't see it.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:04, 22 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I didn't look into it too much, but the ERROR classes can do some stuff with TEXT_FORMATTERs (several elements of the GUI inherit from TEXT_FORMATTER) which could be useful to display information about the ERROR.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 02:22, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== suggestion for implementation ==&lt;br /&gt;
&lt;br /&gt;
I've added a suggestion how to implement our changes. How bad is it? Comments? Improvements?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:35, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
It's not bad, it sounds good ;)&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 12:39, 21 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2959</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2959"/>
				<updated>2006-05-21T00:22:26Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* Interface to visualization group */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ERROR classes in Paul's code aren't compatible with the ones in the current version (mainly the versions of SYNTAX_ERROR and SYNTAX_MESSAGE are quite different). &lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:54, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That's correct. The existing error classes did not support everything they needed to support, so I reworte them. If you actually look at the parser error/warning classes in the parser cluster (not EiffelStudio's error classes) you'll see that the warning class is not even implemented!&lt;br /&gt;
&lt;br /&gt;
As I said, the parser is a stand-alone library. The parser cluster was only moved under Src/Eiffel for ease to users to check out and compile Eiffel. In that respect you should just create an application that uses the parser library, as I did. I then sent a generated error string, from the error classes, to the the command-line shell.&lt;br /&gt;
&lt;br /&gt;
[[User:Paulb|Paulb]] 22:14, 20 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm not sure if I understand what you mean. Basically, I should be able to take just the parser cluster and write a program that parses Eiffel files? But that's not possible, because EIFFEL_PARSER_SKELETON inherits from SHARED_ERROR_HANDLER, which is in the compiler cluster. Also, the error/warning classes in the parser cluster aren't used in ES, only the ones in the compiler cluster. I'd really like to create an application that uses the parser library, but I don't understand how it's going to work without the compiler cluster.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 01:38, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I didn't look into it too much, but the ERROR classes can do some stuff with TEXT_FORMATTERs (several elements of the GUI inherit from TEXT_FORMATTER) which could be useful to display information about the ERROR.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 02:22, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== suggestion for implementation ==&lt;br /&gt;
&lt;br /&gt;
I've added a suggestion how to implement our changes. How bad is it? Comments? Improvements?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:35, 19 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/SRS&amp;diff=2958</id>
		<title>Talk:Syntax checking/SRS</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/SRS&amp;diff=2958"/>
				<updated>2006-05-21T00:16:40Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: Martin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Janick ==&lt;br /&gt;
Please give some feedback regarding SRS so far&lt;br /&gt;
&lt;br /&gt;
==Manus==&lt;br /&gt;
It is great. For the syntax validity, create an instance of EIFFEL_PARSER with the AST_NULL_FACTORY for the factory. That way it is quite efficient for the parsing.&lt;br /&gt;
&lt;br /&gt;
[[User:Manus|manus]] 19:03, 2 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
==Janick==&lt;br /&gt;
Manu, thanks for the feedback and hints. &lt;br /&gt;
&lt;br /&gt;
Some people thaught that an timing-based parser would be better. Who is of the same opionion? Please use this discussion, as we need to finalize the specifications soon.&lt;br /&gt;
&lt;br /&gt;
May 5th 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Martin ==&lt;br /&gt;
&lt;br /&gt;
What exactly do you mean by timing-based? As specified in the SRS but with a timeout before it starts parsing or really independent of user input? I think it's good the way it is now (if it is efficient enough). Just a little remark to the notes: If the state of an expression can only change when the cursor leaves it, does that include the items under 1.1.1? I think it should, although I guess you should get a little time to resume typing.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|Maser]] 23:57, 5 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
==Janick==&lt;br /&gt;
Timing based would mean that the document gets parsed and highlighted in specific intervals (like every 50ms). This would also imply that while writing not yet completed feature names etc. would get underlined.&lt;br /&gt;
&lt;br /&gt;
Stephan added that &amp;quot;when the cursor&amp;quot; leaves part, so he should answer that question. IMO if we have event-based parsing, that coursor leaves clause could be removed.&lt;br /&gt;
&lt;br /&gt;
01:59, May 6th 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Martin ==&lt;br /&gt;
&lt;br /&gt;
I've got a question to the interface section. Do you mean EDITOR_TOKEN or really the TOKEN class in the lex library? IMO it's not possible to do it this way, because the parser doesn't know that there is an editor. It can only generate a list of error descriptions, but cannot access the editor's data (if you use ec on the command line, there even is no editor whose data it could access). In a nutshell: the editor has to use the parser, not the other way around.&lt;br /&gt;
&lt;br /&gt;
(should this be in the SRS as it concerns implementation?)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And something else: There can be syntax warnings (eg. when you use the word 'only' you get a warning that this could become a keyword in a future version of the language), so we can either ignore them (display nothing), treat them as errors (not a good idea) or use a different colour.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 02:16, 21 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2957</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2957"/>
				<updated>2006-05-20T23:38:20Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* find more than one error */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ERROR classes in Paul's code aren't compatible with the ones in the current version (mainly the versions of SYNTAX_ERROR and SYNTAX_MESSAGE are quite different). &lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:54, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That's correct. The existing error classes did not support everything they needed to support, so I reworte them. If you actually look at the parser error/warning classes in the parser cluster (not EiffelStudio's error classes) you'll see that the warning class is not even implemented!&lt;br /&gt;
&lt;br /&gt;
As I said, the parser is a stand-alone library. The parser cluster was only moved under Src/Eiffel for ease to users to check out and compile Eiffel. In that respect you should just create an application that uses the parser library, as I did. I then sent a generated error string, from the error classes, to the the command-line shell.&lt;br /&gt;
&lt;br /&gt;
[[User:Paulb|Paulb]] 22:14, 20 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm not sure if I understand what you mean. Basically, I should be able to take just the parser cluster and write a program that parses Eiffel files? But that's not possible, because EIFFEL_PARSER_SKELETON inherits from SHARED_ERROR_HANDLER, which is in the compiler cluster. Also, the error/warning classes in the parser cluster aren't used in ES, only the ones in the compiler cluster. I'd really like to create an application that uses the parser library, but I don't understand how it's going to work without the compiler cluster.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 01:38, 21 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== suggestion for implementation ==&lt;br /&gt;
&lt;br /&gt;
I've added a suggestion how to implement our changes. How bad is it? Comments? Improvements?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:35, 19 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2937</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2937"/>
				<updated>2006-05-19T14:35:55Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: suggestion for implementation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ERROR classes in Paul's code aren't compatible with the ones in the current version (mainly the versions of SYNTAX_ERROR and SYNTAX_MESSAGE are quite different). &lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:54, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== suggestion for implementation ==&lt;br /&gt;
&lt;br /&gt;
I've added a suggestion how to implement our changes. How bad is it? Comments? Improvements?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:35, 19 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2936</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2936"/>
				<updated>2006-05-19T14:34:38Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: suggestion for implementation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING): Both save the results in match_list: LEAF_AS_LIST.&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
* based on Paul's code&lt;br /&gt;
===ERROR classes===&lt;br /&gt;
* Create new SYNTAX_ERROR classes that correspond to Paul's classes, but fit into the current hierarchy&lt;br /&gt;
* store start and end position of the error&lt;br /&gt;
===extend parser to generate the right ERRORs===&lt;br /&gt;
* Integrate Paul's changes to eiffel.l and eiffel.y into the current versions. &lt;br /&gt;
* add facilities from Paul's EIFFEL_PARSER_ERROR_REPORTER&lt;br /&gt;
** in existing class like EIFFEL_PARSER_SKELETON (EP_ERROR_REPORTER only inherits SHARED_ERROR_HANDLER and so does EP_SKELETON&lt;br /&gt;
** in new class&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2925</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2925"/>
				<updated>2006-05-18T22:54:07Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* find more than one error */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ERROR classes in Paul's code aren't compatible with the ones in the current version (mainly the versions of SYNTAX_ERROR and SYNTAX_MESSAGE are quite different). &lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 00:54, 19 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2924</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2924"/>
				<updated>2006-05-18T22:48:01Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: added eiffel.y&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes/Files==&lt;br /&gt;
&lt;br /&gt;
====eiffel.y====&lt;br /&gt;
* Eiffel grammar description. &lt;br /&gt;
* use [http://www.gobosoft.com/eiffel/gobo/geyacc/ geyacc] to generate eiffel_parser.e from this file&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* inherits from EIFFEL_PARSER_SKELETON (where the features parse, parse_string, make_with_factory are implemented)&lt;br /&gt;
* make_with_factory (a_factory: AST_FACTORY): give argument of type AST_NULL_FACTORY (inherits from AST_FACTORY)&lt;br /&gt;
* parse (a_file: KL_BINARY_INPUT_FILE) and parse_from_string (a_string: STRING): Both save the results in match_list: LEAF_AS_LIST.&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2921</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2921"/>
				<updated>2006-05-18T18:15:06Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* find more than one error */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everyone, I've sent Martin something that I worked on a couple a months ago. It's be no means finished or polished. It got put on the back burner because I need to work on other parts of EiffelEnvision. I also do not think it is the most recent version but I will need to check at home for the latest bits. &lt;br /&gt;
&lt;br /&gt;
Basically I sent him what I started implementing for a recoverable parser in the new EiffelEnvision editor. It supported recovering from errors (more complex cannot be support with ease because it's hard to find a recoverable token - Eiffel does not have mandatory end-of-statement tokens like C/C++/C#), precise error/warning reporting (a real message stating excatly what is wrong) and absolute error positions (if you notice EiffelStudio does not always give the exact error location.)&lt;br /&gt;
&lt;br /&gt;
One thing that I started doing, which you guys are going to need to address too, is error/warning spans. It would be nice if the error reporting indicated the start and end coordinates (x1, y1 - x2, y2) of the error, without draining performance. &lt;br /&gt;
&lt;br /&gt;
The parser is common to EiffelStudio/Compiler, EiffelEnvision and a number of internal tools, which is something you need to be aware of. That means do not add any references to anything related to the compiler or EiffelStudio. The parser itself is a stand-alone cluster.&lt;br /&gt;
&lt;br /&gt;
Creating a recoverable parser is hard and placement of those error token is a black art (that's what O'Reilly say and I agree)! Good luck :)&lt;br /&gt;
&lt;br /&gt;
--[[User:Paulb|Paulb]] 17:59, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks a lot for the code, Paul!&lt;br /&gt;
&lt;br /&gt;
I quickly looked through it and I'll summarize how (I think) it works: eiffel.y is extended is modified like described on the page Manu mentioned (according to Paul it contains bugs because he didn't finish it, and it isn't up to date because eiffel.y was extended to support new language features), so that it reports multiple errors (and stores them in SHARED_ERROR_HANDLER.error_list). It's about a thousand lines longer than the version in the repository. Additionally, there are new ERROR classes that describe the found syntax errors and some helper classes. Paul also mentioned that he made changes to EIFFEL_PARSER_SKELETON, but he couldn't find them.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 20:15, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2913</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2913"/>
				<updated>2006-05-18T14:43:40Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: Interface to visualization group&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Interface to visualization group ==&lt;br /&gt;
&lt;br /&gt;
As the parser produces ERROR objects and they contain information about position and description of the error and stores them in SHARED_ERROR_HANDLER.error_list, I suggest we use this as interface to exchange the data between the parser and visualisation groups.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:43, 18 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2912</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2912"/>
				<updated>2006-05-18T14:31:24Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maser: Couldn't we read several strings of the file and use parse_with_string instead of parse? I'm not sure...&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 15:52, 18 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Chrigu: A normal EIFFEL_PARSER accepts just classes, but you can use set_expression_parser (or some other `Parser type setting' feature) to create a parser that parses Eiffel expressions (I knew I had seen something like that before, but couldn't find it yesterday). But changing the eiffel.y file seems like a better solution. Maybe we should use expression and/or feature parsers while checking if a previously found error has been corrected by the user (I assume parsing just one expression is pretty fast).&lt;br /&gt;
&lt;br /&gt;
I've looked through the documentation of gayacc and I think it shouldn't be too difficult to change eiffel.y to our needs, the file's size will probably bethe biggest problem.&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 16:31, 18 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2903</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2903"/>
				<updated>2006-05-17T20:55:40Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hmmm... I don't know how to get all the errors with one call. But you haven't to parse the whole file, so you can parse piecewise and if an error occurs, you have to parse after the string that occurs the error. This is a way to get all errors, it's complicated, but it should work!?&lt;br /&gt;
&lt;br /&gt;
[[User:Chrigu|Chrigu]] 17:19, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
Actually read http://www.gobosoft.com/eiffel/gobo/geyacc/error.html for more info on how modifying `eiffel.y' to recover from error and therefore detect more than one error at a time.&lt;br /&gt;
&lt;br /&gt;
--[[User:Manus|manus]] 18:10, 17 May 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
Chrigu: How exactly do you parse piecewise? Though it wouldn't solve the problem because there can be several errors in one piece.&lt;br /&gt;
Manu: Thanks for the hint! Looks very promising!&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 22:55, 17 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2892</id>
		<title>Talk:Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Syntax_checking/Parser&amp;diff=2892"/>
				<updated>2006-05-17T12:55:20Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==find more than one error==&lt;br /&gt;
As far as I've seen, the Parser throws an ERROR as soon as it doesn't like something in the source, which aborts parsing. The found error is in the SHARED_ERROR_HANDLER's error_list (I've never seen more than one error in there, why is it a list anyway?). Has anybody found a way to tell the parser to parse the whole file?&lt;br /&gt;
&lt;br /&gt;
[[User:Maser|maser]] 14:55, 17 May 2006 (CEST)&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User:Maser&amp;diff=2866</id>
		<title>User:Maser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User:Maser&amp;diff=2866"/>
				<updated>2006-05-16T15:43:05Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Martin Luder=&lt;br /&gt;
&lt;br /&gt;
*email: luderm (at) student_ethz_ch&lt;br /&gt;
*mobile phone: 076 480 17 83&lt;br /&gt;
*MSN: martin_luder [AT] hotmail.com (this email address does not exist!)&lt;br /&gt;
*gtalk: martin.luder [AT] gmail.com&lt;br /&gt;
&lt;br /&gt;
==Work==&lt;br /&gt;
[[Syntax checking]] project&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2865</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2865"/>
				<updated>2006-05-16T15:41:20Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: added link to Syntax checking page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
[[Syntax_checking|back to Syntax checking page]]&lt;br /&gt;
&lt;br /&gt;
==Important Classes==&lt;br /&gt;
&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* has a feature parse(file)&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2864</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2864"/>
				<updated>2006-05-16T14:01:16Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* SHARED_ERROR_HANDLER */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==important classes==&lt;br /&gt;
&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* has a feature parse(file)&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton used by all relevant classes&lt;br /&gt;
&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2863</id>
		<title>Syntax checking/Parser</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking/Parser&amp;diff=2863"/>
				<updated>2006-05-16T13:55:57Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==important classes==&lt;br /&gt;
&lt;br /&gt;
====EIFFEL_PARSER====&lt;br /&gt;
* has a feature parse(file)&lt;br /&gt;
====CLASS_AS====&lt;br /&gt;
* AST of a class&lt;br /&gt;
====ERROR====&lt;br /&gt;
* deferred; superclass of all error types like EIFFEL_ERROR or SYNTAX_ERROR&lt;br /&gt;
* features line, column: INTEGER give location of error&lt;br /&gt;
====ERROR_HANDLER====&lt;br /&gt;
* feature error_list: ERROR is a list of errors found by the parser&lt;br /&gt;
====SHARED_ERROR_HANDLER====&lt;br /&gt;
* singleton&lt;br /&gt;
====EIFFEL_CLASS_C====&lt;br /&gt;
* features build_ast and parse_ast show how the parser can be used.&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking&amp;diff=2862</id>
		<title>Syntax checking</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking&amp;diff=2862"/>
				<updated>2006-05-16T13:39:58Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: /* Groups */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
The aim of this project is to provide adequate, but non intrusive feedback to user about syntax errors. This is done by checking syntax as you type and underlining syntax errors by the well knwon wavy red line. Furthermore, error descriptions and possible solutions should be provided.&lt;br /&gt;
&lt;br /&gt;
The Project is named '''SynChé''', which is a combination of syntax and checking.&lt;br /&gt;
The ''é'' at the end is important, as a cool name needs either a recursive acronym or a special character from a non English language.&lt;br /&gt;
&lt;br /&gt;
=Software Requirement Specification (SRS)=&lt;br /&gt;
You can find our SRS [[Syntax_checking/SRS|here]]&lt;br /&gt;
&lt;br /&gt;
=Groups=&lt;br /&gt;
&lt;br /&gt;
* [[Syntax_checking/Visualisation|Visualisation]]&lt;br /&gt;
* [[Syntax_checking/Parser|Parser]]&lt;br /&gt;
&lt;br /&gt;
=Milestones=&lt;br /&gt;
&lt;br /&gt;
==M1: April 25th==&lt;br /&gt;
* Get home-grown EiffelStudio up and running.&lt;br /&gt;
&lt;br /&gt;
==M2: May 2nd==&lt;br /&gt;
* '''Put your name in this Wiki!'''&lt;br /&gt;
* Analyse source code to certain degree, so discussion about interfaces between parser and visual is possible&lt;br /&gt;
&lt;br /&gt;
==M3: May 9th==&lt;br /&gt;
* SRS written&lt;br /&gt;
* Overview of relevant classes (BON diagram or more)&lt;br /&gt;
* Further Project Milestones specified, based on SRS and knowledge about code&lt;br /&gt;
&lt;br /&gt;
== May 12th == &lt;br /&gt;
'''Results of the Meeting:''' [[Syntax_checking/Visualisation| Visualisation]]&lt;br /&gt;
&lt;br /&gt;
==M4: May 23th==&lt;br /&gt;
*'''Parser Group''': Find out what results you get from the parser&lt;br /&gt;
*'''Visualisation Group''': Write a feature that draw the red underline&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
Everyone intrested in this project is welcome to join our mailinglist [http://origo.ethz.ch/cgi-bin/mailman/listinfo/es-ui es-ui@origo.ethz.ch]. &lt;br /&gt;
At this point, the team is divided into two groups at this point, one responsible for the parser, the other one for visual feedback (like underlininig).&lt;br /&gt;
&lt;br /&gt;
== Visual Feedback ==&lt;br /&gt;
* [[User:jabernet| Janick Bernet]] (project leader)&lt;br /&gt;
* [[User:fdevries| Fabien de Vries]]&lt;br /&gt;
* [[User:indermum| Matthias Indermühle]]&lt;br /&gt;
* [[User:clerco| Olivier Clerc]]&lt;br /&gt;
&lt;br /&gt;
== Parser ==&lt;br /&gt;
* [[User:maser| Martin Luder]]&lt;br /&gt;
* [[User:Chrigu| Christoph Huber]]&lt;br /&gt;
* [[User:goalgettah| Ueli Etter]]&lt;br /&gt;
* [[User:Squeezie| Michael Schär]]&lt;br /&gt;
* [[User:MarkoR| Marko Ristin]]&lt;br /&gt;
&lt;br /&gt;
== Assistant ==&lt;br /&gt;
* [[User:classens| Stephan Classen]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Syntax_checking&amp;diff=2861</id>
		<title>Syntax checking</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Syntax_checking&amp;diff=2861"/>
				<updated>2006-05-16T13:39:26Z</updated>
		
		<summary type="html">&lt;p&gt;Maser: added section with links to groups&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
[[Category:Editor]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
The aim of this project is to provide adequate, but non intrusive feedback to user about syntax errors. This is done by checking syntax as you type and underlining syntax errors by the well knwon wavy red line. Furthermore, error descriptions and possible solutions should be provided.&lt;br /&gt;
&lt;br /&gt;
The Project is named '''SynChé''', which is a combination of syntax and checking.&lt;br /&gt;
The ''é'' at the end is important, as a cool name needs either a recursive acronym or a special character from a non English language.&lt;br /&gt;
&lt;br /&gt;
=Software Requirement Specification (SRS)=&lt;br /&gt;
You can find our SRS [[Syntax_checking/SRS|here]]&lt;br /&gt;
&lt;br /&gt;
=Groups=&lt;br /&gt;
&lt;br /&gt;
* [[Syntax_checking/Visualisation]]&lt;br /&gt;
* [[Syntax_checking/Parser]]&lt;br /&gt;
&lt;br /&gt;
=Milestones=&lt;br /&gt;
&lt;br /&gt;
==M1: April 25th==&lt;br /&gt;
* Get home-grown EiffelStudio up and running.&lt;br /&gt;
&lt;br /&gt;
==M2: May 2nd==&lt;br /&gt;
* '''Put your name in this Wiki!'''&lt;br /&gt;
* Analyse source code to certain degree, so discussion about interfaces between parser and visual is possible&lt;br /&gt;
&lt;br /&gt;
==M3: May 9th==&lt;br /&gt;
* SRS written&lt;br /&gt;
* Overview of relevant classes (BON diagram or more)&lt;br /&gt;
* Further Project Milestones specified, based on SRS and knowledge about code&lt;br /&gt;
&lt;br /&gt;
== May 12th == &lt;br /&gt;
'''Results of the Meeting:''' [[Syntax_checking/Visualisation| Visualisation]]&lt;br /&gt;
&lt;br /&gt;
==M4: May 23th==&lt;br /&gt;
*'''Parser Group''': Find out what results you get from the parser&lt;br /&gt;
*'''Visualisation Group''': Write a feature that draw the red underline&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
Everyone intrested in this project is welcome to join our mailinglist [http://origo.ethz.ch/cgi-bin/mailman/listinfo/es-ui es-ui@origo.ethz.ch]. &lt;br /&gt;
At this point, the team is divided into two groups at this point, one responsible for the parser, the other one for visual feedback (like underlininig).&lt;br /&gt;
&lt;br /&gt;
== Visual Feedback ==&lt;br /&gt;
* [[User:jabernet| Janick Bernet]] (project leader)&lt;br /&gt;
* [[User:fdevries| Fabien de Vries]]&lt;br /&gt;
* [[User:indermum| Matthias Indermühle]]&lt;br /&gt;
* [[User:clerco| Olivier Clerc]]&lt;br /&gt;
&lt;br /&gt;
== Parser ==&lt;br /&gt;
* [[User:maser| Martin Luder]]&lt;br /&gt;
* [[User:Chrigu| Christoph Huber]]&lt;br /&gt;
* [[User:goalgettah| Ueli Etter]]&lt;br /&gt;
* [[User:Squeezie| Michael Schär]]&lt;br /&gt;
* [[User:MarkoR| Marko Ristin]]&lt;br /&gt;
&lt;br /&gt;
== Assistant ==&lt;br /&gt;
* [[User:classens| Stephan Classen]]&lt;/div&gt;</summary>
		<author><name>Maser</name></author>	</entry>

	</feed>