Jump to content

Delphi parser development


Recommended Posts

Update: empty lines are correctly handled too (see github).


But how should comments be treated? Are they included with the span of an item (but which? previous or next?) or as a seperate node?


Comments can be written as a separate node, but we recommend to include them as part of the text of the declaration they are referring to. Therefore, the declaration can have leading comments and trailing comments.
You have two options to handle the comments:
Option I: the declarations can have only one trailing comment. The comment exists if it is in the same line where the declaration ends.
Option II: the comments on lines following to declarations must be a part of the trailing comments, until an additional end of line appears (or the next declaration).
The next declaration starts where the previous declaration ends, therefore it includes the leading comments.
Please, see the attached examples.



Link to comment
Share on other sites

Hi all,


Here, we have the first merge for the Delphi language. Thanks André!! :)


BASE file structure:


unit "Unit1"

  interface "interface"

    type "type"

      class "TTest"

method "Test"

    implementation "implementation"

      method implementation "TTest.Test"


Changes done on SRC file:


  * add method "Source"

  * add method implementation "TTest.Source"

  * modify class "TTest"

  * modify method implementation "TTest.Test"


Changes done on DST file:      


  * add method "Dest"

  * add method implementation "TTest.Dest"

  * modify class "TTest" 


The source files, which are used in the example, are attached.


Now, we invoke semanticmerge:

semanticmergetool.exe -s src.pas -d dst.pas -b base.pas -r output.pas -emt=default -ep=pas2yaml.exe

Go to "source diffs" view to see the differences between the base and the source contributor:



Go to "destination diffs" view to see the differences between the base and the destination contributor:



As we can see, the "TTest" class has been modified in both contributors. 

Therefore, we need to solve manually the conflict! To do that, go to "pending conflict" view and click the "merge" button.



Now, go to "rearrange file" view to check the result :)



And.. of course, our last feature: visual merge!





Best regards.



Link to comment
Share on other sites

small update: more "items" are supported now:

- uses list with item per unit 

- visibility parent (public, private, etc)

- properties, fields, functions


Also did some refactoring: it should be very easy now to support other types (using AddNewItem and AddNewParent functions) which does all the span determining etc.



- globals vars, const, other types (enums etc), global functions

- inner class types

- class functions, vars, etc?

- generics?

- better support for comments (everything between 2 items is included in previous span but no algoritm for determining to which (prev or next item)

- other pascal language dialects (Oxygene, Smart/op4js, etc)


Is there anyone who would like to help to support the remaining language features?

Or at least generate a file with all possible Delphi features? Same for oxygene?

Link to comment
Share on other sites

Hi I forked the project on Github and I am trying to get the Delphi code to compile on Oxygene (using massive amounts of {$IFDEF})

Once that works then I can start working on adding the Oxygene specific parsing code...

We can still compile it in Delphi or we can compile it in .NET (using Oxygene (there is a free commandline compiler)) once that all is finished.

Link to comment
Share on other sites

Hi André,


Can you try to clone this repo:



And see if it still compiles correctly under Delphi?


It now runs on Oxygene and generates the same output file as your exe.


If it does compile, would you like to merge this into your repo? then we can both work on it... (I can test it using Oxygene)


Best Regards,



Link to comment
Share on other sites



Technically yes, The generated assembly is a 100% .NET 4.0  dll

But for now I created an exe that does the job (same as the Delphi exe)


Thank you for testing the source!


I am now working on adding some Oxygene syntax stuff (like 'method') but I have a hard time getting it in there...

There is function  Func9  to Func191, they are also put into an array, but I don't understand how they are called...

If I want to add another function 'Func192' how does it work?


Best Regards,



Link to comment
Share on other sites



I have a suggestion...

Would it be a good idea to have an extra field in the YAML output?

When a node has children this field can indicate if the order of the children is important or not...

This can then be used by you guys to know if this can be swapped around in a file...

for example: the order of the uses clause can influence how the software works, but the order of the methods in the interface section does not...


Best Regards,



Link to comment
Share on other sites

  • 2 weeks later...
Hi Jeroen,


First of all thank you for your suggestion.

I suppose that the only difference for those "order aware" children would be not to apply automatically the moved-moved conflicts, right?


Are the "use clauses" the only declarations of this type in Delphy language? In addition, could you provide us a source code example to better study the case?


Thanks in advance. :)


Best regards


Link to comment
Share on other sites



Well of course it all depends on how far the parser will go :)

suppose we would parse a enum then the members order would be important.


I guess it could be used when for example one dev cleans up a file a bit (by moving methods that belong together) and another one adds a method.

This is mostly a case that gives a lot of conflicts in normal diff tools...





  TMyColors = public enum(red, green, blue);



 TMyColors = public enum(red, green, orange, blue);



 TMyColors = public enum(red, green, purple, blue);


This is a conflict a developer must solve



Best Regards,



Link to comment
Share on other sites

  • 2 months later...
  • Create New...