Recent

Author Topic: Porting a Delphi Project  (Read 20800 times)

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Porting a Delphi Project
« Reply #15 on: August 26, 2016, 07:11:49 pm »
Dear Markov, where can I find it in FPC distribution?
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

Thaddy

  • Hero Member
  • *****
  • Posts: 14211
  • Probably until I exterminate Putin.
Re: Porting a Delphi Project
« Reply #16 on: August 26, 2016, 07:22:02 pm »
under <fpcroot source>/utils/tply
Specialize a type, not a var.

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Porting a Delphi Project
« Reply #17 on: August 26, 2016, 11:19:46 pm »
Dear all,

thanks to your suggestions I'm tried to completely port on Lazarus, as GUI application, the original GOLD Parser engine of Martin Van Der Geer written for Delphi (http://www.goldparser.org/engine/1/delphi/van-der-geer/van-der-geer-delphi-src-v0.2.zip).

I used the conversion tool, added {$M+} directive in MainForm.pas unit and removed some unnecessary module dependencies in uses clause.
I ignored other hints and warnings of compiler, to not introduce bug, due to my little experience with Lazarus.

On Windows platform the project compile and run without problems.

Below I attach the zip file archive with sources. If in your opinion my work is correct, I will send sources to author of GOLD for the pubblication in the web site.

Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

Thaddy

  • Hero Member
  • *****
  • Posts: 14211
  • Probably until I exterminate Putin.
Re: Porting a Delphi Project
« Reply #18 on: August 27, 2016, 09:26:28 am »
My evaluation follows:

There are a number of places where you really should have cleaned up the warnings and most of the hints. One hint can not be cleaned up, only supressed, so I left that.
You also left out the component. I do not think that's a good idea, because it is installable in Lazarus too.
Furthermore, this code will only compile in FPC and there is no good reason for that since the sourcecode itself is fully compatible between Delphi and Freepascal.
There are no dialect specifics in the sources!
I think it is a better idea to keep it compilable in both Delphi and fpc.
This takes little effort.

Since the code contains a lot of sub-optimal string handling (propably for lack of knowledge by the original authors) let us fix that too.
Then we can together present an improved version that really serves both communities.
I will attach a cleaned up version of your code, including the component and the relevant Delphi files, so we can present a version that is better and serves both FPC and freepascal.
i.e. completely cleaned up and much faster because string parameters are now e.g. passed as const.

Ok?. I will attach it later in a separate post. You could have used my original sources: these were already cleaned up, so I just merge the two and double check.
« Last Edit: August 27, 2016, 09:29:42 am by Thaddy »
Specialize a type, not a var.

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Porting a Delphi Project
« Reply #19 on: August 27, 2016, 09:49:03 am »
I agree! I tried to do everything myself, but unfortunately I have not yet quite familiar with Lazarus and so I missed importante things. Thank you for cooperation!

PS: I noticed that there are two versions of GOLD for Delphi, with different GUI and functions. What is the best?
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

Thaddy

  • Hero Member
  • *****
  • Posts: 14211
  • Probably until I exterminate Putin.
Re: Porting a Delphi Project
« Reply #20 on: August 27, 2016, 11:42:34 am »
I agree! I tried to do everything myself, but unfortunately I have not yet quite familiar with Lazarus and so I missed importante things. Thank you for cooperation!

PS: I noticed that there are two versions of GOLD for Delphi, with different GUI and functions. What is the best?

Don't worry. Here's a version that should compile in both Delphi and Freepascal/Lazarus and with further improvements and some missing files added: the readme, the resource, the delphi dfm and the component.
We'll ask for testers here ;) It still needs adapting the headers but it is code complete.
I am still making the code more robust, but is already faster and much cleaner.

About the versions: this one is in my opinion the cleanest code. The other one takes even more work. We'll get back at that one later ;)
This one was also easier to make cross-platform: I did the work under linux debian on a Raspberry Pi 3 :)
« Last Edit: August 27, 2016, 11:52:59 am by Thaddy »
Specialize a type, not a var.

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Porting a Delphi Project
« Reply #21 on: August 27, 2016, 01:37:41 pm »
As soon as possible I perform some black box test on your version (Windows platform) using grammars available on the web site and I report results. Thanks again!

Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Porting a Delphi Project
« Reply #22 on: August 28, 2016, 01:33:46 pm »
I have tested the GOLD engine (compiled with Lazarus 1.6 + FPC 3.0.0 on Win32) using as input to parse some program source codes. I used the grammar for Delphi 7 provided by web site(http://www.goldparser.org/grammars/files/Delphi-7_v11.zip).

The engine seems to work properly. I only found some issues to fix in the BNF grammar I used, that has some holes. Due to this reason, for example, comment marked with (* *) and uses clauses  of form <unitname in 'unitfilename'>, are not recognized.

Moreover, obviously the grammar is not able to deal with more recent feature of language, as class helpers and generics, for example.

The parser is slow (I presume that automatically generated parsers are in general slower than language tailored). Indeed the parsing of a program source require more time than entire compilation process performed by FPC.

I planned to update the BNF grammar in order to comply with the actual syntax of FreePascal.

About this task, I have some questions for the forum, but I will start another thread in other section, because as noted this is not a topic for beginners.
« Last Edit: August 28, 2016, 01:36:20 pm by simone »
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

Thaddy

  • Hero Member
  • *****
  • Posts: 14211
  • Probably until I exterminate Putin.
Re: Porting a Delphi Project
« Reply #23 on: August 28, 2016, 02:37:34 pm »
Yes, it is not fast and it is already faster than the original code by passing strings as const.
There are many good candidates for inlining as well. I suppose I guess we can speed it up by about 15% w/o changing logic by using inlining alone..
But I have also seen places where more modern features can speed things up considerably.
Specialize a type, not a var.

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Porting a Delphi Project
« Reply #24 on: August 28, 2016, 04:37:43 pm »
In your opinion with GOLD it's  possible to associate semantic actions to the syntax rules, as in other parser generators?
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

Leledumbo

  • Hero Member
  • *****
  • Posts: 8747
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Porting a Delphi Project
« Reply #25 on: August 28, 2016, 04:55:23 pm »
The parser is slow (I presume that automatically generated parsers are in general slower than language tailored). Indeed the parsing of a program source require more time than entire compilation process performed by FPC.
Don't hope too much from a table driven parser, stack simulation on software level is always slower than hardware stack, which recursive descent parser is based on to make it run blazingly fast. Also, Pascal grammar is designed with LL POV, adapting it to LR might also incure some additional overhead.

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Porting a Delphi Project
« Reply #26 on: August 29, 2018, 10:56:08 am »
We'll ask for testers here ;)

I know this was in 2016, but better late bug report then never  ;)

When I use this grammar in Gold parser Builder 5.2:
Code: bnf  [Select][+][-]
  1. ! -----------------------------------------------------------------------
  2. ! Standard Pascal Grammar
  3. ! -----------------------------------------------------------------------
  4.  
  5.  
  6. "Name"    = 'Pascal'
  7. "Version" = '1973'
  8. "Author"  = 'Niklaus Wirth'
  9. "About"   = 'PASCAL was developed by NIKLAUS WIRTH of the ETH Technical Institute of Zuerich in 1970-1971.(published in 1973)'
  10.  
  11. "Case Sensitive" = False
  12. "Start Symbol"   = <Program>
  13.  
  14. {Hex Digit}      = {Digit} + [abcdefABCDEF]
  15.  
  16. {Id Head}        = {Letter} + [_]
  17. {Id Tail}        = {Id Head} + {Digit}
  18.  
  19. {String Ch}      = {Printable} - ['']
  20. {Char Ch}        = {Printable} - ['']
  21.  
  22. DecLiteral       = [123456789]{Digit}*
  23. HexLiteral       = '$'{Hex Digit}+
  24. FloatLiteral     = {Digit}*'.'{Digit}+
  25. StringLiteral    = ''( {String Ch} | '\'{Printable} )* ''
  26. CharLiteral      = '' ( {Char Ch} | '\'{Printable} )''
  27.  
  28. id               = {Id Head}{Id Tail}*
  29.  
  30. <constant>         ::= DecLiteral
  31.                      | StringLiteral
  32.                      | FloatLiteral
  33.                      | HexLiteral
  34.                      | CharLiteral
  35.  
  36.  
  37. !=========================================== Program
  38.  
  39. <Program> ::= <ProgramHeader> <Declarations> <CompoundStatement> '.'
  40.  
  41. <ProgramHeader> ::= PROGRAM id ';'
  42.                   | PROGRAM id '(' <IdList> ')' ';'
  43.  
  44. <Declarations> ::= <ConstantDefinitions> <TypeDefinitions> <VariableDeclarations> <ProcedureDeclarations>
  45.  
  46. <ConstantDefinitions> ::= CONST <ConstantDefinitionList>
  47.                         |
  48.  
  49. <ConstantDefinitionList> ::= <ConstantDef>
  50.                            | <ConstantDef> <ConstantDefinitionList>
  51.  
  52. <ConstantDef> ::= id '=' <constant> ';'
  53.  
  54. <TypeDefinitions> ::= TYPE <TypeDefinitionList>
  55.                      |
  56.  
  57. <TypeDefinitionList> ::= <TypeDef>
  58.                        | <TypeDef> <TypeDefinitionList>
  59.  
  60. <TypeDef> ::= id '=' <TypeSpecifier> ';'
  61.  
  62. <VariableDeclarations> ::= VAR <VariableDeclarationList>
  63.                         |
  64.  
  65. <VariableDeclarationList> ::= <VariableDec>
  66.                             | <VariableDec> <VariableDeclarationList>
  67.  
  68. <VariableDec> ::= <IdList> ':' <TypeSpecifier> ';'
  69.  
  70. <ProcedureDeclarations> ::= <ProcedureDec> <ProcedureDeclarations>
  71.                           |
  72.  
  73. <ProcedureDec> ::= <ProcedureHeader> FORWARD ';'
  74.                  | <ProcedureHeader> <Declarations> <CompoundStatement> ';'
  75.                  | <FunctionHeader> FORWARD ';'
  76.                  | <FunctionHeader> <Declarations> <CompoundStatement> ';'
  77.  
  78. <ProcedureHeader> ::= PROCEDURE id <Arguments> ';'
  79.  
  80. <FunctionHeader> ::= FUNCTION id <Arguments> ':' <TypeSpecifier> ';'
  81.  
  82. <Arguments> ::= '(' <ArgumentList> ')'
  83.               |
  84.  
  85. <ArgumentList> ::= <Arg>
  86.                  | <Arg> ';' <ArgumentList>
  87.  
  88. <Arg> ::= <IdList> ':' <TypeSpecifier>
  89.         | VAR <IdList> ':' <TypeSpecifier>
  90.  
  91. <CompoundStatement> ::= BEGIN <StatementList> END
  92.  
  93. <StatementList> ::= <Statement>
  94.                   | <Statement> ';' <StatementList>
  95.  
  96. <Statement> ::= <CompoundStatement>
  97.               | <AssignmentStatement>
  98.               | <ProcedureCall>
  99.               | <ForStatement>
  100.               | <WhileStatement>
  101.               | <IfStatement>
  102.               | <CaseStatement>
  103.               | <RepeatStatement>
  104.               |
  105.  
  106. <AssignmentStatement> ::= <Variable> ':=' <Expression>
  107.  
  108. <ProcedureCall> ::= id <Actuals>
  109.                  
  110. <FunctionCall>  ::= id <Actuals>
  111.                
  112. <ForStatement> ::= FOR id ':=' <Expression> TO <Expression> DO <Statement>
  113.                  | FOR id ':=' <Expression> DOWNTO <Expression> DO <Statement>
  114.  
  115. <WhileStatement> ::= WHILE <Expression> DO <Statement>
  116.  
  117. <IfStatement> ::= IF <Expression> THEN <Statement> ELSE <Statement>
  118.  
  119. <RepeatStatement> ::= REPEAT <StatementList> UNTIL <Expression>
  120.  
  121. <CaseStatement> ::= CASE <Expression> OF <CaseList> END
  122.  
  123. <CaseList> ::= <Case>
  124.              | <Case> ';' <CaseList>
  125.  
  126. <Case> ::= <ConstantList> ':' <Statement>
  127.  
  128. <ConstantList> ::= <constant>
  129.                  | <constant> ',' <ConstantList>
  130.  
  131. <Expression> ::= <SimpleExpression>
  132.                | <SimpleExpression> '=' <SimpleExpression>
  133.                | <SimpleExpression> '<>' <SimpleExpression>
  134.                | <SimpleExpression> '<' <SimpleExpression>
  135.                | <SimpleExpression> '<=' <SimpleExpression>
  136.                | <SimpleExpression> '>' <SimpleExpression>
  137.                | <SimpleExpression> '>=' <SimpleExpression>
  138.  
  139. <SimpleExpression> ::= <Term>
  140.                     | <SimpleExpression> '+' <Term>
  141.                     | <SimpleExpression> '-' <Term>
  142.                     | <SimpleExpression> OR <Term>
  143.  
  144. <Term> ::= <Factor>
  145.          | <Term> '*' <Factor>
  146.          | <Term> '/' <Factor>
  147.          | <Term> 'DIV' <Factor>
  148.          | <Term> 'MOD' <Factor>
  149.          | <Term> 'AND' <Factor>
  150.  
  151. <Factor> ::= '(' <Expression> ')'
  152.            | '+' <Factor>
  153.            | '-' <Factor>
  154.            | NOT <Factor>
  155.            | <constant>
  156.            | <Variable>
  157.  
  158. <Actuals> ::= '(' <ExpressionList> ')'
  159.             |
  160.  
  161. <ExpressionList> ::= <Expression>
  162.                    | <Expression> ',' <ExpressionList>
  163.  
  164. <Variable> ::= id
  165.              | <Variable> '.' id
  166.              | <Variable> '^'
  167.              | <Variable> '[' <ExpressionList> ']'
  168.  
  169. <TypeSpecifier> ::= id
  170.                   | '^' <TypeSpecifier>
  171.                   | '(' <IdList> ')'
  172.                   | <constant> '..' <constant>
  173.                   | ARRAY '[' <DimensionList> ']' OF <TypeSpecifier>
  174.                   | RECORD <FieldList> END
  175.                   | FILE OF <TypeSpecifier>
  176.  
  177. <DimensionList> ::= <Dimension>
  178.                   | <Dimension> ',' <DimensionList>
  179.  
  180. <Dimension> ::= <constant> '..' <constant>
  181.               | id
  182.  
  183. <FieldList> ::= <Field>
  184.               | <Field> ';' <FieldList>
  185.  
  186. <Field> ::= <IdList> ':' <TypeSpecifier>
  187.  
  188. <IdList> ::= id
  189.            | id ',' <IdList>
  190.  

I can successfuly parse this code in Gold Test Grammar module:
Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. const
  4.   PI = 3.14;
  5.  
  6. var
  7.   a, b: real;
  8.  
  9. procedure hello(s: string; n: real);
  10. begin
  11.   writeln(s);
  12. end;
  13.  
  14. begin
  15.   a := PI;
  16.   b := a * 10;
  17.   hello('Hello World!', b);
  18.   for i := 1 to 10 do
  19.     write(i);
  20. end.
  21.  

Unfortunately when I load compiled grammar table into lazarus GoldEngine I get errors like this one:
Quote
Line 9: Syntax Error: Expecting the following tokens: ( ;

I had to over simplify the code like this, in order for Lazarus GoldEngine to be able to successfuly parse pascal source:
Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. const
  4.   PI = 3.14;
  5.  
  6. var
  7.   a, b: real;
  8.  
  9. procedure hello;
  10. begin
  11.   writeln;
  12. end;
  13.  
  14. begin
  15.   a := PI;
  16.   b := a * 10;
  17.   hello;
  18.   for i := 1 to 10 do
  19.     write;
  20. end.
  21.  

EDIT: Added forgotten do at the end of for-loop.
« Last Edit: August 31, 2018, 09:39:06 pm by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

Thaddy

  • Hero Member
  • *****
  • Posts: 14211
  • Probably until I exterminate Putin.
Re: Porting a Delphi Project
« Reply #27 on: August 29, 2018, 01:43:31 pm »
I recently did quite a bit of refactoring on the engine. Have to package it up and will attach later.
But that was not directly related to parser improvements.
Specialize a type, not a var.

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Porting a Delphi Project
« Reply #28 on: August 29, 2018, 02:56:35 pm »
Thanks a lot!  :)

That will give me time to take a look at plex/pyacc and Delphi Compiler Generator in peace.  :D
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Porting a Delphi Project
« Reply #29 on: August 29, 2018, 03:32:40 pm »
Note that Martok very recently enhanced tply in his github resource compiler branch.

 

TinyPortal © 2005-2018