www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why Pegged action dont not work in this case ?

reply Basile B. <b2.temp gmx.com> writes:
I 've started experimenting Pegged action. Quickly i got blocked 
by this problem. The start action works where I use the rule but 
not directly in the rule. Test program:

gdb_commander.d:
---
/+dub.sdl:
dependency "pegged" version="~>0.4.4"
versions "dub_run"
+/
module gdb_commander;

import core.stdc.string, std.json;
import pegged.grammar, pegged.peg;

enum gdbMiOutput = `GdbmiOutput:

     Output          < OutOfBandRecord* ResultRecord? '(gdb)' 
#HERE before ResRec OK
     ResultRecord    < {beginResultRecord} Token? '^' ResultClass 
(',' Result)* {endResultRecord}
     OutOfBandRecord < AsyncRecord
                     / StreamRecord
     AsyncRecord     < ExecAsyncOutput
                     / StatusAsyncOutput
                     / NotifyAsyncOutput
     ExecAsyncOutput < Token? '*' AsyncOutput
     StatusAsyncOutput   < Token? '+' AsyncOutput
     NotifyAsyncOutput   < Token? '=' AsyncOutput
     AsyncOutput     < AsyncClass ( ',' Result )*
     ResultClass     < 'done'
                     / 'running'
                     / 'connected'
                     / 'error'
                     / 'exit'
     AsyncClass      < 'stopped'
     Result          < Variable '=' Value
     Variable        < String
     Value           < Const / Object / List
     Const           < CString
     Object          < '{}'
                     / '{' Result ( ',' Result )* '}'
     List            < '[]'
                     / '[' Value ( ',' Value )* ']'
                     / '[' Result ( ',' Result )* ']'
     StreamRecord    < ConsoleStreamOutput
                     / TargetStreamOutput
                     / LogStreamOutput
     ConsoleStreamOutput < '~' CString
     TargetStreamOutput  < ' ' CString
     LogStreamOutput     < '&' CString
     Token           <~ [a-zA-Z_][a-zA-Z0-9_]*
     CString         <~ "\"" (EscapedQuotes / (!"\"" .) )* :"\""
     EscapedQuotes   <~ backslash doublequote
     String          <~ [a-zA-Z0-9_\-]*`;

T beginResultRecord(T)(T t)
{
     import std.stdio;
     writeln(__PRETTY_FUNCTION__);
     return t;
}

T endResultRecord(T)(T t)
{
     import std.stdio;
     writeln(t);
     return t;
}

mixin(grammar(gdbMiOutput));

version(dub_run)
{
     import std.stdio, std.path, std.file, std.process;
     import pegged.tohtml;

     enum testString01 = `^done,path="/usr/bin"
     (gdb)`;
     enum testString02 = `^done,threads=[
     {id="2",target-id="Thread 0xb7e14b90 (LWP 21257)",
     frame={level="0",addr="0xffffe410",func="__kernel_vsyscall",
     args=[]},state="running"},
     {id="1",target-id="Thread 0xb7e156b0 (LWP 21254)",
     frame={level="0",addr="0x0804891f",func="foo",
     args=[{name="i",value="10"}],
     
file="/tmp/a.c",fullname="/tmp/a.c",line="158",arch="i386:x86_64"},
     state="running"}],
     current-thread-id="1"
     (gdb)`;
     enum testString03 = `^done,new-thread-id="3",
     frame={level="0",func="vprintf",
     args=[{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""},
     
{name="arg",value="0x2"}],file="vprintf.c",line="31",arch="i386:x86_64"}
     (gdb)`;

     void exportHTMLandBrowse(T)(auto ref T tree, string name)
     {
         string fname = __FILE_FULL_PATH__.dirName ~ "/" ~ name ~ 
".html";
         if (fname.exists)
             remove(fname);
         toHTML(tree, fname);
         browse(fname);
     }

     void main()
     {
         GdbmiOutput(testString01).exportHTMLandBrowse("t1");
         GdbmiOutput(testString02).exportHTMLandBrowse("t2");
         GdbmiOutput(testString03).exportHTMLandBrowse("t3");
     }
}
---

---
$ dub gdb_commander.d
---

Also I'd like to report that actions dont work with partially 
specialized templates:

---
T handleResultRecord(bool end,  T)(T t);
// then you use handleResultRecord!true and 
handleResultRecord!false in the PEG.
---
Apr 19 2020
parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Sunday, 19 April 2020 at 16:47:06 UTC, Basile B. wrote:
 I 've started experimenting Pegged action. Quickly i got 
 blocked by this problem. The start action works where I use the 
 rule but not directly in the rule.
I don't understand the difference between how you use "where" and "directly in". Note that semantic actions are executed during the parsing process, even in branches that eventually fail, before the parser back tracks. They are not a substitute for traversing the final parse tree, rather, they are a method for manipulating the parsing process as it happens. That's why `endResultRecord` is executed directly after `(',' Result)*` succeeds, and `beginResultRecord` is executed directly after `ResultRecord` succeeds (even if `'(gdb)'` would not match).
 Test program:
[...]
     ResultRecord    < {beginResultRecord} Token? '^' 
 ResultClass (',' Result)* {endResultRecord}
Remove the space between "<" and "{", then it works.
 Also I'd like to report that actions dont work with partially 
 specialized templates:

 ---
 T handleResultRecord(bool end,  T)(T t);
 // then you use handleResultRecord!true and 
 handleResultRecord!false in the PEG.
 ---
That fails for the same reason as `handleResultRecord!true(1)` fails to instantiate. -- Bastiaan.
Jun 11 2020