From: Googie on 11 Jun 2010 09:15 W dniu 2010-06-05 10:41, Fredrik Karlsson pisze: > Hi, > > I've been trying to get hold of a parser generator + lexer combination > that would give me a parser implemented in Tcl, that actually works. > > My experience so far: > > taccle + fickle - just outputs nothing. Even the demos fails to give > any ouput. > Yeti - I get bus error every time I use either the parser or the lexer > demos. > > I am using UTF-8 encoding.. Are there other options out there that I > should try before continuing my current work of rolling my own parser > from scratch? > > /Fredrik I faced the same problem months ago and after few weeks of trying to get anything work (I think I managed fickle to create some output, but it's buggy) I finally wrote my own lexer and parser. I can support you relating this subject if you have any problems or questions - I propably passed them already. Oh... and I have same thoughts about the 'page' package. I've never managed to get it working, even after some source code examining. Regards, Googie
From: tom.rmadilo on 11 Jun 2010 12:21 On Jun 11, 6:15 am, Googie <n...(a)sp4m.c0m> wrote: > W dniu 2010-06-05 10:41, Fredrik Karlsson pisze: > > > > > > > Hi, > > > I've been trying to get hold of a parser generator + lexer combination > > that would give me a parser implemented in Tcl, that actually works. > > > My experience so far: > > > taccle + fickle - just outputs nothing. Even the demos fails to give > > any ouput. > > Yeti - I get bus error every time I use either the parser or the lexer > > demos. > > > I am using UTF-8 encoding.. Are there other options out there that I > > should try before continuing my current work of rolling my own parser > > from scratch? > > > /Fredrik > > I faced the same problem months ago and after few weeks of trying to get > anything work (I think I managed fickle to create some output, but it's > buggy) I finally wrote my own lexer and parser. I can support you > relating this subject if you have any problems or questions - I propably > passed them already. > > Oh... and I have same thoughts about the 'page' package. I've never > managed to get it working, even after some source code examining. Page and pt seem to have well written and extensive APIs, but zero example applications. A good example would be to implement json::json2dict using these tools. Instead json2dict is hand written and produces a dictionary value which cannot be transformed back to a json text. However, it is five times faster than my json parser: http://tnt.rmadilo.com/json/json.tcl You can view the application code at http://tnt.rmadilo.com/json/ (.txt,.tmpl files).
From: JHJL on 13 Jun 2010 08:37 On Jun 10, 1:09 am, Andreas Kupries <akupr...(a)shaw.ca> wrote: > Fredrik Karlsson <dargo...(a)gmail.com> writes: > > Hi, > > > This looks very promising indeed, but still at bit opaque (at least > > for me). Given that I have a grammar in PEG format in the file > > grammar.peg, how do I get a TclOO that would be a parser for that > > grammar? > > > What I have is: > > ---- > > set peg [read [open grammar.peg r] ] > > set gram [pt::peg::import $peg] > > --- > > > , but how to get the parser? > > And here I thought that I had an example of that in the > docs. Apparently I confused myself with the pt_parser_api manpage, > which has an example of the use, when you have the class. > > Ok. > ============================================== > package require pt::pgen > package require fileutil > > set script [pt::pgen \ > peg [fileutil::cat grammar.peg] > oo \ > -file grammar.peg \ > -name name-of-grammar \ > -user $tcl_platform(user) \ > -class name-of-oo-class] > # Options are specific to the output format. > > fileutil::writeFile your-tcl-file.tcl $script > ============================================== > > There is also the 'pt' application, a light wrapper around pt::pgen. > > ============================================== > pt generate \ > peg grammar.peg > oo your-tcl-file.tcl \ > -name name-of-grammar \ > -class name-of-oo-clas > ============================================== > > HTH. > > > /Fredrik > > > On Jun 8, 7:46 am, Andreas Kupries <akupr...(a)shaw.ca> wrote: > >> I recently created a replacement, 'pt', also in tcllib. > > >> Documentation starts here > > >> http://docs.activestate.com/activetcl/8.5/tcllib/pt/pt_introduction.html > >> and http://docs.activestate.com/activetcl/8.5/tcllib/pt/pt.html > > >> Hopefully that is better. > > -- > So long, > Andreas Kupries <akupr...(a)shaw.ca> > <http://www.purl.org/NET/akupries/> > Developer @ <http://www.activestate.com/> > ------------------------------------------------------------------------------- I tried the above but am getting a run-time error (running in Tkcon, Tcl8.6b2) ============================================== loading history file ... 48 events added buffer line limit: 512 max line length: unlimited Main console display active (Tcl8.6b1.2 / Tk8.6b1.2) (PEG) 49 % ls /Volumes/jhjl/Development/PEG: example.peg* testpeg.tcl* (PEG) 50 % pt invalid command name "pt" (PEG) 51 % package require pt::pgen 1 (PEG) 52 % package require fileutil 1.14.2 (PEG) 53 % set script [pt::pgen \ peg [fileutil::cat example.peg] oo \ -file example.peg \ -name calculator \ -user $tcl_platform(user) \ -class calculator] unknown or ambiguous subcommand "pt::grammar::peg {rules {AddOp {is {/ {t +} {t -}} mode value} Digit {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}} mode value} Expression {is {/ {x {t (} {n Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}} mode value} Factor {is {x {n Term} {* {x {n AddOp} {n Term}}}} mode value} MulOp {is {/ {t *} {t /}} mode value} Number {is {x {? {n Sign}} {+ {n Digit}}} mode value} Sign {is {/ {t -} {t +}} mode value} Term {is {n Number} mode value}} start {n Expression}}": must be c, container, critcl, json, oo, param, peg, or snit (PEG) 54 ============================================== The above error expanded is unknown or ambiguous subcommand "pt::grammar::peg {rules {AddOp {is {/ {t +} {t -}} mode value} Digit {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}} mode value} Expression {is {/ {x {t (} {n Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}} mode value} Factor {is {x {n Term} {* {x {n AddOp} {n Term}}}} mode value} MulOp {is {/ {t *} {t /}} mode value} Number {is {x {? {n Sign}} {+ {n Digit}}} mode value} Sign {is {/ {t -} {t +}} mode value} Term {is {n Number} mode value}} start {n Expression}}": must be c, container, critcl, json, oo, param, peg, or snit while executing "Write {*}$args [pt::peg::from::peg convert $input]" (procedure "::pt::pgen::peg" line 3) invoked from within "pt::pgen \ peg [fileutil::cat example.peg]" ("uplevel" body line 1) invoked from within "uplevel #0 set\ script\ \[pt::pgen\ \\\n\ \ \ \ \ \ \ \ peg\ \ [fileutil::cat\ example.peg\]\n\ \ \ \ \ \ \ \ oo\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ -file\ ..." ============================================== example.peg contains: ============================================== PEG calculator (Expression) Digit <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9' ; Sign <- '-' / '+' ; Number <- Sign? Digit+ ; Expression <- '(' Expression ')' / (Factor (MulOp Factor)*) ; MulOp <- '*' / '/' ; Factor <- Term (AddOp Term)* ; AddOp <- '+'/'-' ; Term <- Number ; END; ============================================== Any ideas?
From: tom.rmadilo on 13 Jun 2010 12:58 On Jun 13, 5:37 am, JHJL <j...(a)hippospace.com> wrote: > On Jun 10, 1:09 am, Andreas Kupries <akupr...(a)shaw.ca> wrote: > > > > > > > Fredrik Karlsson <dargo...(a)gmail.com> writes: > > > Hi, > > > > This looks very promising indeed, but still at bit opaque (at least > > > for me). Given that I have a grammar in PEG format in the file > > > grammar.peg, how do I get a TclOO that would be a parser for that > > > grammar? > > > > What I have is: > > > ---- > > > set peg [read [open grammar.peg r] ] > > > set gram [pt::peg::import $peg] > > > --- > > > > , but how to get the parser? > > > And here I thought that I had an example of that in the > > docs. Apparently I confused myself with the pt_parser_api manpage, > > which has an example of the use, when you have the class. > > > Ok. > > ============================================== > > package require pt::pgen > > package require fileutil > > > set script [pt::pgen \ > > peg [fileutil::cat grammar.peg] > > oo \ > > -file grammar.peg \ > > -name name-of-grammar \ > > -user $tcl_platform(user) \ > > -class name-of-oo-class] > > # Options are specific to the output format. > > > fileutil::writeFile your-tcl-file.tcl $script > > ============================================== > > > There is also the 'pt' application, a light wrapper around pt::pgen. > > > ============================================== > > pt generate \ > > peg grammar.peg > > oo your-tcl-file.tcl \ > > -name name-of-grammar \ > > -class name-of-oo-clas > > ============================================== > > > HTH. > > > > /Fredrik > > > > On Jun 8, 7:46 am, Andreas Kupries <akupr...(a)shaw.ca> wrote: > > >> I recently created a replacement, 'pt', also in tcllib. > > > >> Documentation starts here > > > >> http://docs.activestate.com/activetcl/8.5/tcllib/pt/pt_introduction.html > > >> and http://docs.activestate.com/activetcl/8.5/tcllib/pt/pt.html > > > >> Hopefully that is better. > > > -- > > So long, > > Andreas Kupries <akupr...(a)shaw.ca> > > <http://www.purl.org/NET/akupries/> > > Developer @ <http://www.activestate.com/> > > --------------------------------------------------------------------------- ---- > > I tried the above but am getting a run-time error (running in Tkcon, > Tcl8.6b2) > > ============================================== > loading history file ... 48 events added > buffer line limit: 512 max line length: unlimited > Main console display active (Tcl8.6b1.2 / Tk8.6b1.2) > (PEG) 49 % ls > /Volumes/jhjl/Development/PEG: > example.peg* testpeg.tcl* > (PEG) 50 % pt > invalid command name "pt" > (PEG) 51 % package require pt::pgen > 1 > (PEG) 52 % package require fileutil > 1.14.2 > (PEG) 53 % set script [pt::pgen \ > peg [fileutil::cat example.peg] > oo \ > -file example.peg \ > -name calculator \ > -user $tcl_platform(user) \ > -class calculator] > unknown or ambiguous subcommand "pt::grammar::peg {rules {AddOp {is {/ > {t +} {t -}} mode value} Digit {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t > 5} {t 6} {t 7} {t 8} {t 9}} mode value} Expression {is {/ {x {t (} {n > Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}} mode > value} Factor {is {x {n Term} {* {x {n AddOp} {n Term}}}} mode value} > MulOp {is {/ {t *} {t /}} mode value} Number {is {x {? {n Sign}} {+ {n > Digit}}} mode value} Sign {is {/ {t -} {t +}} mode value} Term {is {n > Number} mode value}} start {n Expression}}": must be c, container, > critcl, json, oo, param, peg, or snit > (PEG) 54 > ============================================== > > The above error expanded is > > unknown or ambiguous subcommand "pt::grammar::peg {rules {AddOp {is {/ > {t +} {t -}} mode value} Digit {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t > 5} {t 6} {t 7} {t 8} {t 9}} mode value} Expression {is {/ {x {t (} {n > Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}} mode > value} Factor {is {x {n Term} {* {x {n AddOp} {n Term}}}} mode value} > MulOp {is {/ {t *} {t /}} mode value} Number {is {x {? {n Sign}} {+ {n > Digit}}} mode value} Sign {is {/ {t -} {t +}} mode value} Term {is {n > Number} mode value}} start {n Expression}}": must be c, container, > critcl, json, oo, param, peg, or snit > while executing > "Write {*}$args [pt::peg::from::peg convert $input]" > (procedure "::pt::pgen::peg" line 3) > invoked from within > "pt::pgen \ > peg [fileutil::cat example.peg]" > ("uplevel" body line 1) > invoked from within > "uplevel #0 set\ script\ \[pt::pgen\ \\\n\ \ \ \ \ \ \ \ peg\ \ > [fileutil::cat\ example.peg\]\n\ \ \ \ \ \ \ \ oo\ \\\n\ \ \ \ \ \ \ \ > \ \ \ \ \ -file\ ..." > > ============================================== > > example.peg contains: > > ============================================== > > PEG calculator (Expression) > Digit <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9' ; > Sign <- '-' / '+' ; > Number <- Sign? Digit+ ; > Expression <- '(' Expression ')' / (Factor (MulOp Factor)*) ; > MulOp <- '*' / '/' ; > Factor <- Term (AddOp Term)* ; > AddOp <- '+'/'-' ; > Term <- Number ; > END; > ============================================== > > Any ideas? Here are three different scripts which work. Note that the options are different depending on what you want $script to be: #gen-json.tcl package require pt::pgen package require fileutil set script [pt::pgen peg [fileutil::cat grammar.peg] json -aligned 1] puts "$script" # gen-c.tcl package require pt::pgen package require fileutil set script [pt::pgen peg [fileutil::cat grammar.peg] c] puts "$script" #gen-oo.tcl package require pt::pgen package require fileutil set script [pt::pgen peg [fileutil::cat grammar.peg] oo -class calc] puts "$script" I got this to work with ActiveTcl and: $ teacup install pt $ teacup install page $ teacup install pt::pgen The output of the gen-oo.tcl file was this: tom(a)boron:~/activetcl$ ./bin/tclsh % cd test % % source gen-oo.tcl ## -*- tcl -*- ## ## OO-based Tcl/PARAM implementation of the parsing ## expression grammar ## ## a_pe_grammar ## ## Generated from file unknown ## for user unknown ## # # ## ### ##### ######## ############# ##################### ## Requirements package require Tcl 8.5 package require OO package require pt::rde::oo ; # OO-based implementation of the # PARAM virtual machine # underlying the Tcl/PARAM code # used below. # # ## ### ##### ######## ############# ##################### ## oo::class create calc { # # ## ### ##### ######## ############# ## Public API superclass pt::rde::oo ; # TODO - Define this class. # Or can we inherit from a snit # class too ? method parse {channel} { my reset $channel my MAIN ; # Entrypoint for the generated code. return [my complete] } method parset {text} { my reset my data $text my MAIN ; # Entrypoint for the generated code. return [my complete] } # # ## ### ###### ######## ############# ## BEGIN of GENERATED CODE. DO NOT EDIT. # # Grammar Start Expression # method MAIN {} { my sym_Expression return } # # value Symbol 'AddOp' # method sym_AddOp {} { # [+-] my si:void_symbol_start AddOp my si:next_class +- my si:void_leaf_symbol_end AddOp return } # # value Symbol 'Digit' # method sym_Digit {} { # [0123456789] my si:void_symbol_start Digit my si:next_class 0123456789 my si:void_leaf_symbol_end Digit return } # # value Symbol 'Expression' # method sym_Expression {} { # / # x # '\(' # (Expression) # '\)' # x # (Factor) # * # x # (MulOp) # (Factor) my si:value_symbol_start Expression my choice_20 my si:reduce_symbol_end Expression return } method choice_20 {} { # / # x # '\(' # (Expression) # '\)' # x # (Factor) # * # x # (MulOp) # (Factor) my si:value_state_push my sequence_9 my si:valuevalue_branch my sequence_18 my si:value_state_merge return } method sequence_9 {} { # x # '\(' # (Expression) # '\)' my si:void_state_push my si:next_char \50 my si:voidvalue_part my sym_Expression my si:valuevalue_part my si:next_char \51 my si:value_state_merge return } method sequence_18 {} { # x # (Factor) # * # x # (MulOp) # (Factor) my si:value_state_push my sym_Factor my si:valuevalue_part my kleene_16 my si:value_state_merge return } method kleene_16 {} { # * # x # (MulOp) # (Factor) while {1} { my si:void2_state_push my sequence_14 my si:kleene_close } return } method sequence_14 {} { # x # (MulOp) # (Factor) my si:value_state_push my sym_MulOp my si:valuevalue_part my sym_Factor my si:value_state_merge return } # # value Symbol 'Factor' # method sym_Factor {} { # x # (Term) # * # x # (AddOp) # (Term) my si:value_symbol_start Factor my sequence_30 my si:reduce_symbol_end Factor return } method sequence_30 {} { # x # (Term) # * # x # (AddOp) # (Term) my si:value_state_push my sym_Term my si:valuevalue_part my kleene_28 my si:value_state_merge return } method kleene_28 {} { # * # x # (AddOp) # (Term) while {1} { my si:void2_state_push my sequence_26 my si:kleene_close } return } method sequence_26 {} { # x # (AddOp) # (Term) my si:value_state_push my sym_AddOp my si:valuevalue_part my sym_Term my si:value_state_merge return } # # value Symbol 'MulOp' # method sym_MulOp {} { # [*/] my si:void_symbol_start MulOp my si:next_class */ my si:void_leaf_symbol_end MulOp return } # # value Symbol 'Number' # method sym_Number {} { # x # ? # (Sign) # + # (Digit) my si:value_symbol_start Number my sequence_41 my si:reduce_symbol_end Number return } method sequence_41 {} { # x # ? # (Sign) # + # (Digit) my si:value_state_push my optional_36 my si:valuevalue_part my poskleene_39 my si:value_state_merge return } method optional_36 {} { # ? # (Sign) my si:void2_state_push my sym_Sign my si:void_state_merge_ok return } method poskleene_39 {} { # + # (Digit) my i_loc_push my sym_Digit my si:kleene_abort while {1} { my si:void2_state_push my sym_Digit my si:kleene_close } return } # # value Symbol 'Sign' # method sym_Sign {} { # [-+] my si:void_symbol_start Sign my si:next_class -+ my si:void_leaf_symbol_end Sign return } # # value Symbol 'Term' # method sym_Term {} { # (Number) my si:value_symbol_start Term my sym_Number my si:reduce_symbol_end Term return } ## END of GENERATED CODE. DO NOT EDIT. # # ## ### ###### ######## ############# } # # ## ### ##### ######## ############# ##################### ## Ready package provide PACKAGE 1 return % The output for the gen-json.tcl, which for some reason is incorrect in the manpages is: % source gen-json.tcl { "pt::grammar::peg" : { "rules" : { "AddOp" : { "is" : "\/ {t +} {t -}", "mode" : "value" }, "Digit" : { "is" : "\/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}", "mode" : "value" }, "Expression" : { "is" : "\/ {x {t (} {n Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}", "mode" : "value" }, "Factor" : { "is" : "x {n Term} {* {x {n AddOp} {n Term}}}", "mode" : "value" }, "MulOp" : { "is" : "\/ {t *} {t \/}", "mode" : "value" }, "Number" : { "is" : "x {? {n Sign}} {+ {n Digit}}", "mode" : "value" }, "Sign" : { "is" : "\/ {t -} {t +}", "mode" : "value" }, "Term" : { "is" : "n Number", "mode" : "value" } }, "start" : "n Expression" } } %
From: JHJL on 14 Jun 2010 03:20
On Jun 13, 5:58 pm, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote: > On Jun 13, 5:37 am, JHJL <j...(a)hippospace.com> wrote: > > > > > > > On Jun 10, 1:09 am, Andreas Kupries <akupr...(a)shaw.ca> wrote: > > > > Fredrik Karlsson <dargo...(a)gmail.com> writes: > > > > Hi, > > > > > This looks very promising indeed, but still at bit opaque (at least > > > > for me). Given that I have a grammar in PEG format in the file > > > > grammar.peg, how do I get a TclOO that would be a parser for that > > > > grammar? > > > > > What I have is: > > > > ---- > > > > set peg [read [open grammar.peg r] ] > > > > set gram [pt::peg::import $peg] > > > > --- > > > > > , but how to get the parser? > > > > And here I thought that I had an example of that in the > > > docs. Apparently I confused myself with the pt_parser_api manpage, > > > which has an example of the use, when you have the class. > > > > Ok. > > > ============================================== > > > package require pt::pgen > > > package require fileutil > > > > set script [pt::pgen \ > > > peg [fileutil::cat grammar.peg] > > > oo \ > > > -file grammar.peg \ > > > -name name-of-grammar \ > > > -user $tcl_platform(user) \ > > > -class name-of-oo-class] > > > # Options are specific to the output format. > > > > fileutil::writeFile your-tcl-file.tcl $script > > > ============================================== > > > > There is also the 'pt' application, a light wrapper around pt::pgen. > > > > ============================================== > > > pt generate \ > > > peg grammar.peg > > > oo your-tcl-file.tcl \ > > > -name name-of-grammar \ > > > -class name-of-oo-clas > > > ============================================== > > > > HTH. > > > > > /Fredrik > > > > > On Jun 8, 7:46 am, Andreas Kupries <akupr...(a)shaw.ca> wrote: > > > >> I recently created a replacement, 'pt', also in tcllib. > > > > >> Documentation starts here > > > > >> http://docs.activestate.com/activetcl/8.5/tcllib/pt/pt_introduction.html > > > >> and http://docs.activestate.com/activetcl/8.5/tcllib/pt/pt.html > > > > >> Hopefully that is better. > > > > -- > > > So long, > > > Andreas Kupries <akupr...(a)shaw.ca> > > > <http://www.purl.org/NET/akupries/> > > > Developer @ <http://www.activestate.com/> > > > --------------------------------------------------------------------------- ---- > > > I tried the above but am getting a run-time error (running in Tkcon, > > Tcl8.6b2) > > > ============================================== > > loading history file ... 48 events added > > buffer line limit: 512 max line length: unlimited > > Main console display active (Tcl8.6b1.2 / Tk8.6b1.2) > > (PEG) 49 % ls > > /Volumes/jhjl/Development/PEG: > > example.peg* testpeg.tcl* > > (PEG) 50 % pt > > invalid command name "pt" > > (PEG) 51 % package require pt::pgen > > 1 > > (PEG) 52 % package require fileutil > > 1.14.2 > > (PEG) 53 % set script [pt::pgen \ > > peg [fileutil::cat example.peg] > > oo \ > > -file example.peg \ > > -name calculator \ > > -user $tcl_platform(user) \ > > -class calculator] > > unknown or ambiguous subcommand "pt::grammar::peg {rules {AddOp {is {/ > > {t +} {t -}} mode value} Digit {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t > > 5} {t 6} {t 7} {t 8} {t 9}} mode value} Expression {is {/ {x {t (} {n > > Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}} mode > > value} Factor {is {x {n Term} {* {x {n AddOp} {n Term}}}} mode value} > > MulOp {is {/ {t *} {t /}} mode value} Number {is {x {? {n Sign}} {+ {n > > Digit}}} mode value} Sign {is {/ {t -} {t +}} mode value} Term {is {n > > Number} mode value}} start {n Expression}}": must be c, container, > > critcl, json, oo, param, peg, or snit > > (PEG) 54 > > ============================================== > > > The above error expanded is > > > unknown or ambiguous subcommand "pt::grammar::peg {rules {AddOp {is {/ > > {t +} {t -}} mode value} Digit {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t > > 5} {t 6} {t 7} {t 8} {t 9}} mode value} Expression {is {/ {x {t (} {n > > Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}} mode > > value} Factor {is {x {n Term} {* {x {n AddOp} {n Term}}}} mode value} > > MulOp {is {/ {t *} {t /}} mode value} Number {is {x {? {n Sign}} {+ {n > > Digit}}} mode value} Sign {is {/ {t -} {t +}} mode value} Term {is {n > > Number} mode value}} start {n Expression}}": must be c, container, > > critcl, json, oo, param, peg, or snit > > while executing > > "Write {*}$args [pt::peg::from::peg convert $input]" > > (procedure "::pt::pgen::peg" line 3) > > invoked from within > > "pt::pgen \ > > peg [fileutil::cat example.peg]" > > ("uplevel" body line 1) > > invoked from within > > "uplevel #0 set\ script\ \[pt::pgen\ \\\n\ \ \ \ \ \ \ \ peg\ \ > > [fileutil::cat\ example.peg\]\n\ \ \ \ \ \ \ \ oo\ \\\n\ \ \ \ \ \ \ \ > > \ \ \ \ \ -file\ ..." > > > ============================================== > > > example.peg contains: > > > ============================================== > > > PEG calculator (Expression) > > Digit <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9' ; > > Sign <- '-' / '+' ; > > Number <- Sign? Digit+ ; > > Expression <- '(' Expression ')' / (Factor (MulOp Factor)*) ; > > MulOp <- '*' / '/' ; > > Factor <- Term (AddOp Term)* ; > > AddOp <- '+'/'-' ; > > Term <- Number ; > > END; > > ============================================== > > > Any ideas? > > Here are three different scripts which work. Note that the options are > different depending on what you want $script to be: > > #gen-json.tcl > > package require pt::pgen > package require fileutil > set script [pt::pgen peg [fileutil::cat grammar.peg] json -aligned > 1] > > puts "$script" > > # gen-c.tcl > > package require pt::pgen > package require fileutil > set script [pt::pgen peg [fileutil::cat grammar.peg] c] > > puts "$script" > > #gen-oo.tcl > > package require pt::pgen > package require fileutil > set script [pt::pgen peg [fileutil::cat grammar.peg] oo -class > calc] > > puts "$script" > > I got this to work with ActiveTcl and: > $ teacup install pt > $ teacup install page > $ teacup install pt::pgen > > The output of the gen-oo.tcl file was this: > > tom(a)boron:~/activetcl$ ./bin/tclsh > % cd test > % > % source gen-oo.tcl > ## -*- tcl -*- > ## > ## OO-based Tcl/PARAM implementation of the parsing > ## expression grammar > ## > ## a_pe_grammar > ## > ## Generated from file unknown > ## for user unknown > ## > # # ## ### ##### ######## ############# ##################### > ## Requirements > > package require Tcl 8.5 > package require OO > package require pt::rde::oo ; # OO-based implementation of the > # PARAM virtual machine > # underlying the Tcl/PARAM code > # used below. > > # # ## ### ##### ######## ############# ##################### > ## > > oo::class create calc { > # # ## ### ##### ######## ############# > ## Public API > > superclass pt::rde::oo ; # TODO - Define this class. > # Or can we inherit from a snit > # class too ? > > method parse {channel} { > my reset $channel > my MAIN ; # Entrypoint for the generated code. > return [my complete] > } > > method parset {text} { > my reset > my data $text > my MAIN ; # Entrypoint for the generated code. > return [my complete] > } > > # # ## ### ###### ######## ############# > ## BEGIN of GENERATED CODE. DO NOT EDIT. > > # > # Grammar Start Expression > # > > method MAIN {} { > my sym_Expression > return > } > > # > # value Symbol 'AddOp' > # > > method sym_AddOp {} { > # [+-] > > my si:void_symbol_start AddOp > my si:next_class +- > my si:void_leaf_symbol_end AddOp > return > } > > # > # value Symbol 'Digit' > # > > method sym_Digit {} { > # [0123456789] > > my si:void_symbol_start Digit > my si:next_class 0123456789 > my si:void_leaf_symbol_end Digit > return > } > > # > # value Symbol 'Expression' > # > > method sym_Expression {} { > # / > # x > # '\(' > # (Expression) > # '\)' > # x > # (Factor) > # * > # x > # (MulOp) > # (Factor) > > my si:value_symbol_start Expression > my choice_20 > my si:reduce_symbol_end Expression > return > } > > method choice_20 {} { > # / > # x > # '\(' > # (Expression) > # '\)' > # x > # (Factor) > # * > # x > # (MulOp) > # (Factor) > > my si:value_state_push > my sequence_9 > my si:valuevalue_branch > my sequence_18 > my si:value_state_merge > return > } > > method sequence_9 {} { > # x > # '\(' > # (Expression) > # '\)' > > my si:void_state_push > my si:next_char \50 > my si:voidvalue_part > my sym_Expression > my si:valuevalue_part > my si:next_char \51 > my si:value_state_merge > return > } > > method sequence_18 {} { > # x > # (Factor) > # * > # x > # (MulOp) > # (Factor) > > my si:value_state_push > my sym_Factor > my si:valuevalue_part > my kleene_16 > my si:value_state_merge > return > } > > method kleene_16 {} { > # * > > read more »- Hide quoted text - > > - Show quoted text -... Many thanks Tom for the above kick in the right direction and to Andreas, for what is an incredible body of work, greatly appreciated. Now that I can generate an AST from the example I just have towrk out how to cook it :) kind regards Julian |