Recent

Author Topic: Plex/Pyacc read from source file?  (Read 9834 times)

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Plex/Pyacc read from source file?
« on: September 01, 2018, 10:21:14 pm »
I'm working on creating an interpreter using plex/pyacc, and I have a few examples working.

But I can't figure out how to read and parse from one (or more) files rather than standard input.

The wiki mentions yywrap but has no example, anyone got an example of reading input from a file?

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Plex/Pyacc read from source file?
« Reply #1 on: September 01, 2018, 11:00:00 pm »
Just a suggestion, since I've not seen the example: Can't you change wherever something is read from standard input to read from file? I.e. if there is a Read(something) or ReadLn(Something) change them to Read(myfile, something) and ReadLn(myfile, Something) respectively---after calling AssignFile(myfile, './mightyfile') and Reset(myfile), of course.

Alternatively, just redirect the input at the command prompt:
    myprogram < mightyfile
« Last Edit: September 01, 2018, 11:04:37 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: Plex/Pyacc read from source file?
« Reply #2 on: September 02, 2018, 02:57:03 am »
lucamar, the parsing function is just yyparse(); and it defaults to standard input, so when I run it I can type things and it parses/interprets/executes it just fine.

The problem with redirecting to standard input is if I have several files.

There's a function called yywrap() which is apparently used for this kind of thing, but I can't find any examples for how to use it.

It doesn't help that the info for yywrap is confusing as well, it's a function that returns 1 or 0, "if you have more to parse", but that's pretty much all the wiki mentions, and even looking for c/c++ examples (Lex/Yacc) they're not very forthcoming either  :/

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Plex/Pyacc read from source file?
« Reply #3 on: September 02, 2018, 03:10:51 am »
lucamar, the parsing function is just yyparse(); and it defaults to standard input, so when I run it I can type things and it parses/interprets/executes it just fine.

Sorry, haven't had time to dive into the source yet (too many open projects ... which keep me up at three in the morning :) ).

Anyway, how does yyparse() get its input? You say it defaults to standard input so, can it be made to use anything other than its default? Maybe extending it? Or just replacing Read and ReadLn() as I asked above?

It shouldn't be too difficult; after all it must be getting its input in a standard way, and most (all?) of those can be easily replaced to read from file(s).

I'll try to look a little more into this tomorrow, but I can't promise anything. Wish you luck, anway.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: Plex/Pyacc read from source file?
« Reply #4 on: September 02, 2018, 03:14:09 am »
Thanks lucamar, I appreciate your help  :)

I'll see if I can get somewhere with read/readln, I'm very surprised I can't pass something to the function/procedure, but I guess that was done to follow the original lex/yacc implementation.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: Plex/Pyacc read from source file?
« Reply #5 on: September 02, 2018, 03:15:35 am »
Here's the FPC wiki for Plex/Pyacc - http://wiki.freepascal.org/Plex_and_Pyacc

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: Plex/Pyacc read from source file?
« Reply #6 on: September 02, 2018, 03:38:51 am »
Ok looks like this works for a single file, going to see if I can get it working with several files

This will parse all the lines in the specified file by the looks of it.

Code: Pascal  [Select][+][-]
  1.         Assign(srcFile, SRC_FNAME);
  2.         reset(srcFile);
  3.         yyinput := srcFile;
  4.  
  5.         yyparse();
  6.  

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: Plex/Pyacc read from source file?
« Reply #7 on: September 02, 2018, 03:45:13 am »
Ok I'm getting somewhere now.

Code: Pascal  [Select][+][-]
  1. function yywrap():Boolean;
  2. begin
  3.   Close(srcFile);
  4.   Assign(srcFile, 'secondFile.f');
  5.   reset(srcFile);
  6.   Result := false;
  7. end;
  8.  
  9. -----
  10.  
  11. begin
  12.   Assign(srcFile, 'firstFile.f');
  13.   reset(srcFile);
  14.   yyinput := srcFile;
  15.  
  16.   yyparse();
  17. end.
  18.  

This will loop endlessly, but proves that I can load and parse a second file.

I'll update the wiki once I have some more solid examples.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: Plex/Pyacc read from source file?
« Reply #8 on: September 02, 2018, 08:15:40 pm »
I wrote a lex/yacc interface ions ago (2003) for Delphi. Maybe a good time to translate it. I will report back.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Plex/Pyacc read from source file?
« Reply #9 on: September 02, 2018, 09:52:32 pm »
Based on this comment on lexlib.pas:
Quote
(* yywrap:
   The yywrap function is called by yylex at end-of-file (unless you have
   specified a rule matching end-of-file). You may redefine this routine
   in your Lex program to do application-dependent processing at end of
   file. In particular, yywrap may arrange for more input and return false
   in which case the yylex routine resumes lexical analysis. *)

it could be something like this (warning: untested!):

Code: Pascal  [Select][+][-]
  1. program parsetest;
  2.  
  3. uses
  4.   Classes, StrUtils, FileUtils;
  5.   { This uses clause lacks something ...?}
  6.  
  7. var
  8.   filespec: String;
  9.   Files: TStringList;
  10.   srcFile: TextFile;
  11.  
  12. function my_yywrap: Boolean;
  13. { I'm not entirely happy with this, but it should work...}
  14. begin
  15.   Close(srcFile);
  16.   if Files.Count = 0 then
  17.     Result := True {No more files, we have ended!}
  18.   else begin
  19.     Assign(srcFile, Files[0]);
  20.     Files.Delete(0);
  21.     Reset(srcFile);
  22.     Result := false;
  23.   end;
  24. end;
  25.  
  26. procedure ShowHelp;
  27. begin
  28.   writeln('Call as: parsetest filename [filename2] [filename3] [...]');
  29.   writeln('or as : parsetest "filemask"');
  30.   writeln('Examples:');
  31.   writeln('    parsetest source1 source2');
  32.   writeln('    parsetest "source?"');
  33. end;
  34.  
  35. procedure ParseCmdLine;
  36. { This procedure fills up a string list "Files"
  37.   with the names of the files  to process.
  38.   Of course, this is a extremely simplistic implementation!
  39. }
  40. var
  41.   i: Integer;
  42. begin
  43.   if ParamCount = 1 then begin { if a single-file or filemask }
  44.     filespec := ParamStr(1);
  45.     Files := FindAllFiles(ExtractFilePath(filespec),
  46.                           ExtractFileName(filespec));
  47.   end else begin  { if various files }
  48.     Files := TStringList.Create;
  49.     for i := 1 to ParamCount do
  50.       Files.Add(ParamStr(i));
  51.   end;
  52. end;
  53.  
  54. begin
  55.   if ParamCount < 1 then
  56.     ShowHelp
  57.   else begin
  58.     ParseCmdLine;
  59.     if Files.Count > 0 then
  60.     try
  61.       Assign(srcFile, Files[0]);
  62.       Files.Delete(0);
  63.       Reset(srcFile);
  64.       yyinput := srcFile;
  65.       yywrap := @my_yywrap; {I *think* this is needed, but...}
  66.       yyparse();
  67.     finally
  68.       Files.Free;
  69.     end;
  70. end.
  71.  

Note that this code is a quick kluge thrown out in a hurry in a text editor. It hasn't undergone even a syntax check, let alone a compilation/run cycle. Caveat emptor! :D
« Last Edit: September 02, 2018, 11:28:59 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: Plex/Pyacc read from source file?
« Reply #10 on: September 04, 2018, 04:15:40 am »
lucamar, I did get multiple-file parsing working (Not sure if it's a good way of doing it, but it works).

I took a step back and am trying to figure out the basics.

My goal is to implement a subset of cfscript (ColdFusion script), so I have a "blueprint" of sorts to work off of, for better or worse.

I'm having trouble figuring out how to do recursion in yacc though  :/

console("data") <- Easy
console(randRage(10,100)) <- Haven't figured out how to recurse through nested function calls

This is fun though, I'm starting a little blog series on this adventure.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Plex/Pyacc read from source file?
« Reply #11 on: September 04, 2018, 02:42:45 pm »
I'm having trouble figuring out how to do recursion in yacc though  :/

console("data") <- Easy
console(randRage(10,100)) <- Haven't figured out how to recurse through nested function calls

I can't help you much there; I've been trying (on and off) to understand how they work for close to 30 years and I'm not much closer to the goal. I've got too little formal training ... :-[

This is fun though, I'm starting a little blog series on this adventure.

Oh, good! Where is it if I may ask? I may learn something new :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: Plex/Pyacc read from source file?
« Reply #12 on: September 04, 2018, 03:41:24 pm »
Lucamar https://marcusfernstrom.wordpress.com/

I don't have any formal training either, I'm just doing stuff  :)

I went to music school, doesn't help much with the internal workings of compilers, lol

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: Plex/Pyacc read from source file?
« Reply #13 on: September 04, 2018, 05:27:36 pm »
The wiki entry is actually quite good, apart from the language. I will try to translate that part to english.

Can you explain the problems you have with recursion? I can probably help if I know what you mean.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: Plex/Pyacc read from source file?
« Reply #14 on: September 04, 2018, 08:29:22 pm »
Thaddy, that would be awesome, thanks!

About the Wiki, it has one main issue, and lacking information.

There are two sections, one marked as Bad and then one with how to do it right. IMO there should only be the one section showing how to do it well.

It doesn't show recursion.

The example is not in English, though not a huge issue it helps put a little context in an unfamiliar area (Lex/parse).

I plan on expanding the Wiki section as I learn  :)

Ok, so what I'm trying to achieve is this:

I'm implementing a large subset of the cfml script language, which lets you do things like

console( RandRange(100, 1000) );

IE. using one functions output as the input of the next one.

I can't figure out how to recurse through from "inner" to "outer" while passing the result "upward" (For lack of a better term)

http://openbd.org/manual/?/function/ <-- List of CFML script functions

--edit
I'm not on the computer with source code at the moment, but I've tried a bunch of things in various configurations.

Could you show a minimal example that allows for recursive use of say, two functions? I'm just looking for a working example that isn't theoretical.
« Last Edit: September 04, 2018, 09:00:49 pm by Trenatos »

 

TinyPortal © 2005-2018