Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fixed the generators to generate properly listified and quoted error messages |
---|---|
Timelines: | family | ancestors | descendants | both | pt-work |
Files: | files | file ages | folders |
SHA1: |
51a676d805f634f72aa7d0fdfb70ac3d |
User & Date: | aku 2014-06-28 21:16:03 |
Context
2014-06-28
| ||
21:17 | pt::rdengine (C) - Fixed the generation of error messages by the dynamic C runtime, i.e. made it generate proper lists. check-in: 5eca9d6009 user: aku tags: pt-work | |
21:16 | Fixed the generators to generate properly listified and quoted error messages check-in: 51a676d805 user: aku tags: pt-work | |
21:13 | pt::parse::peg - test - Moved table of constructed test cases, plus fixed variables out of the loop. And ensured that initialization does not extend the table evermore. check-in: 4be7c99b0d user: aku tags: pt-work | |
Changes
Changes to modules/pt/pkgIndex.tcl.
︙ | ︙ | |||
36 37 38 39 40 41 42 | # Import plugins, connecting manager to the core conversion packages. package ifneeded pt::peg::import::json 1 [list source [file join $dir pt_peg_import_json.tcl]] package ifneeded pt::peg::import::peg 1 [list source [file join $dir pt_peg_import_peg.tcl]] # Export core functionality: Conversion from PEG to a specific format. package ifneeded pt::peg::to::container 1 [list source [file join $dir pt_peg_to_container.tcl]] | | | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # Import plugins, connecting manager to the core conversion packages. package ifneeded pt::peg::import::json 1 [list source [file join $dir pt_peg_import_json.tcl]] package ifneeded pt::peg::import::peg 1 [list source [file join $dir pt_peg_import_peg.tcl]] # Export core functionality: Conversion from PEG to a specific format. package ifneeded pt::peg::to::container 1 [list source [file join $dir pt_peg_to_container.tcl]] package ifneeded pt::peg::to::cparam 1.1.3 [list source [file join $dir pt_peg_to_cparam.tcl]] package ifneeded pt::peg::to::json 1 [list source [file join $dir pt_peg_to_json.tcl]] package ifneeded pt::peg::to::param 1.0.1 [list source [file join $dir pt_peg_to_param.tcl]] package ifneeded pt::peg::to::peg 1.0.2 [list source [file join $dir pt_peg_to_peg.tcl]] package ifneeded pt::peg::to::tclparam 1.0.2 [list source [file join $dir pt_peg_to_tclparam.tcl]] # Import core functionality: Conversion from a specific format to PEG. package ifneeded pt::peg::from::json 1 [list source [file join $dir pt_peg_from_json.tcl]] package ifneeded pt::peg::from::peg 1.0.3 [list source [file join $dir pt_peg_from_peg.tcl]] # PARAM runtime. package ifneeded pt::rde 1.0.3 [list source [file join $dir pt_rdengine.tcl]] |
︙ | ︙ |
Changes to modules/pt/pt_peg_to_cparam.tcl.
︙ | ︙ | |||
37 38 39 40 41 42 43 | namespace ensemble create } # ### ### ### ######### ######### ######### ## API. proc ::pt::peg::to::cparam::reset {} { | > | | | | | | | | | | | | | | > > > | > | > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | namespace ensemble create } # ### ### ### ######### ######### ######### ## API. proc ::pt::peg::to::cparam::reset {} { variable insertcmd {} ; # -insert-command (hook) variable template @code@ ; # -template variable name a_pe_grammar ; # -name variable file unknown ; # -file variable user unknown ; # -user variable self {} ; # -self-command variable ns {} ; # -namespace variable def static ; # -fun-qualifier variable main __main ; # -main variable indent 0 ; # -indent variable comments 1 ; # -comments variable prelude {} ; # -prelude variable statedecl {RDE_PARAM p} ; # -state-decl variable stateref {p} ; # -state-ref variable strings p_string ; # -string-varname return } proc ::pt::peg::to::cparam::configure {args} { variable template variable name variable file variable user variable self variable ns variable def variable main variable omap variable indent variable insertcmd variable comments variable prelude variable statedecl variable stateref variable strings if {[llength $args] == 0} { return [list \ -comments $comments \ -file $file \ -fun-qualifier $def \ -indent $indent \ -insert-command $insertcmd \ -main $main \ -name $name \ -namespace $ns \ -self-command $self \ -state-decl $statedecl \ -state-ref $stateref \ -string-varname $strings \ -template $template \ -user $user \ ] } elseif {[llength $args] == 1} { lassign $args option set variable [string range $option 1 end] if {[info exists omap($variable)]} { return [set $omap($variable)] } else { # TODO: compute this string dynamically. return -code error "Expected one of -comments, -file, -fun-qualifier, -indent, -insert-cmd, -main, -name, -namespace, -self-command, -state-decl, -state-ref, -string-varname, -template, or -user, got \"$option\"" } } elseif {[llength $args] % 2 == 0} { foreach {option value} $args { set variable [string range $option 1 end] if {![info exists omap($variable)]} { # TODO: compute this string dynamically. return -code error "Expected one of -comments, -file, -fun-qualifier, -indent, -insert-cmd, -main, -name, -namespace, -self-command, -state-decl, -state-ref, -string-varname, -template, or -user, got \"$option\"" } } foreach {option value} $args { set variable $omap([string range $option 1 end]) switch -exact -- $variable { template { if {$value eq {}} { return -code error "Expected template, got the empty string" } } indent { if {![string is integer -strict $value] || ($value < 0)} { return -code error "Expected int > 0, got \"$value\"" } } comments { if {![string is boolean -strict $value]} { return -code error "Expected boolean, got \"$value\"" } } insert-cmd - statedecl - stateref - strings - self - def - ns - main - |
︙ | ︙ | |||
149 150 151 152 153 154 155 156 157 158 159 160 161 162 | variable file variable user variable self variable ns variable def variable main variable indent variable prelude variable statedecl variable stateref variable strings Op::Asm::Setup | > | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | variable file variable user variable self variable ns variable def variable main variable indent variable insertcmd variable prelude variable statedecl variable stateref variable strings Op::Asm::Setup |
︙ | ︙ | |||
260 261 262 263 264 265 266 | if {$indent} { set code [Indent $code $indent] } set xprelude $prelude ; if {$xprelude ne {}} { set xprelude " $xprelude" } set xself $self ; if {$xself ne {}} { append xself { } } | > > | > | > > | | | | | | > | > > | | | | | | | | > < | | > | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | if {$indent} { set code [Indent $code $indent] } set xprelude $prelude ; if {$xprelude ne {}} { set xprelude " $xprelude" } set xself $self ; if {$xself ne {}} { append xself { } } # I. run code through the insertcmd hook (if specified) to prepare it for embedding if {[llength $insertcmd]} { set code [{*}$insertcmd $code] } # II. Phase 1 merge of code into the template. # (Placeholders only in the template) lappend map @user@ $user lappend map @format@ C/PARAM lappend map @file@ $file lappend map @name@ $name lappend map @code@ $code set code [string map $map $template] unset map # III. Phase 2 merge of code into the template. # (Placeholders in generated code, and template). lappend map @statedecl@ $statedecl lappend map @stateref@ $stateref lappend map @strings@ $strings lappend map { @prelude@} $xprelude lappend map {@self@ } $xself lappend map @def@ $def lappend map @ns@ $ns lappend map @main@ $main set code [string map $map $code] return $code # ### ### ### ######### ######### ######### } # ### ### ### ######### ######### ######### ## Internals proc ::pt::peg::to::cparam::Indent {text n} { set b [string repeat { } $n] return $b[join [split $text \n] \n$b] } proc ::pt::peg::to::cparam::Expression {expression modes} { return [pt::pe bottomup \ [list [namespace current]::Op $modes] \ $expression] } proc ::pt::peg::to::cparam::Symbol {symbol mode rhs modes} { set expression [Expression $rhs $modes] text::write clear Op::Asm::Header "$mode Symbol '$symbol'" text::write store FUN_HEADER Op::Asm::Start Op::Asm::ReExpression $symbol Op::Asm::GenAST $expression Op::Asm::PE $rhs set gen [dict get $result gen] Op::Asm::Function sym_$symbol { # Message is Tcl list. Quote for C embedding. set msg [Op::Asm::String [char quote cstring [list n $symbol]]] # Quote for C embedding. set symbol [Op::Asm::String [char quote cstring $symbol]] # We have six possibilites for the combination of AST node # generation by the rhs and AST generation by the symbol. Two # of these (leaf/0, value/0 coincide, leaving 5). This # controls the use of AS/ARS instructions. switch -exact -- $mode/$gen { |
︙ | ︙ | |||
554 555 556 557 558 559 560 | }] } proc ::pt::peg::to::cparam::Op::t {modes char} { Asm::Start Asm::ReTerminal t $char Asm::Direct { | | | > > | | | | | > > | > | | | | | | > | > > | | > | > > | | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 | }] } proc ::pt::peg::to::cparam::Op::t {modes char} { Asm::Start Asm::ReTerminal t $char Asm::Direct { # Message is Tcl list. Quote for C embedding. set msg [Asm::String [char quote cstring [list t $char]]] # Quote for C embedding. set char [char quote cstring $char] #Asm::Ins input_next $msg #Asm::CStmt if (!rde_param_query_st(@stateref@)) return #Asm::Ins test_char \"$char\" $msg Asm::Ins next_char \"$char\" $msg } Asm::Done } proc ::pt::peg::to::cparam::Op::.. {modes chs che} { Asm::Start Asm::ReTerminal .. $chs $che Asm::Direct { # Message is Tcl list. Quote for C embedding. set msg [Asm::String [char quote cstring [list .. $chs $che]]] # Quote for C embedding set chs [char quote cstring $chs] set che [char quote cstring $che] #Asm::Ins input_next $msg #Asm::CStmt if (!rde_param_query_st(@stateref@)) return #Asm::Ins test_range \"$chs\" \"$che\" $msg Asm::Ins next_range \"$chs\" \"$che\" $msg } Asm::Done } proc ::pt::peg::to::cparam::Op::str {modes args} { Asm::Start Asm::ReTerminal str {*}$args Asm::Direct { set str [join $args {}] # Message is Tcl list. Quote for C embedding. set msg [Asm::String [char quote cstring [list str $str]]] # Quote for C embedding set str [char quote cstring $str] # Without fusing this would be rendered as a sequence of # characters, with associated stack churn for each # character/part (See Op::x, void/all). Asm::Ins next_str \"$str\" $msg } Asm::Done } proc ::pt::peg::to::cparam::Op::cl {modes args} { # rorc = Range-OR-Char-List Asm::Start Asm::ReTerminal cl {*}$args Asm::Direct { # Without fusing this would be rendered as a choice of # characters, with associated stack churn for each # character/branch (See Op::/, void/all). set cl [join [Ranges {*}$args] {}] # Message is Tcl list. Quote for C embedding. set msg [Asm::String [char quote cstring [list cl $cl]]] # Quote for C embedding set cl [char quote cstring $cl] Asm::Ins next_class \"$cl\" $msg } Asm::Done } proc ::pt::peg::to::cparam::Op::Ranges {args} { set res {} foreach rorc $args { lappend res [Range $rorc] } |
︙ | ︙ | |||
644 645 646 647 648 649 650 | set res {} for {set i $s} {$i <= $e} {incr i} { append res [format %c $i] } return $res } else { | | | 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | set res {} for {set i $s} {$i <= $e} {incr i} { append res [format %c $i] } return $res } else { return $rorc ;#[char quote tcl $rorc] } } proc ::pt::peg::to::cparam::Op::n {modes symbol} { # symbol mode determines AST generation # void => non-generative, # leaf/value => generative. |
︙ | ︙ | |||
1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 | # Map from option name (without leading dash) to the name of the # variable used to store setting. variable omap ; array set omap { comments comments file file fun-qualifier def indent indent main main name name namespace ns prelude prelude self-command self state-decl statedecl state-ref stateref string-varname strings template template user user } variable comments 1 variable self {} variable ns {} variable def static variable main __main variable indent 0 variable prelude {} variable statedecl {RDE_PARAM p} variable stateref p variable strings p_string | > > | > | | | | 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 | # Map from option name (without leading dash) to the name of the # variable used to store setting. variable omap ; array set omap { comments comments file file fun-qualifier def indent indent insert-cmd insertcmd main main name name namespace ns prelude prelude self-command self state-decl statedecl state-ref stateref string-varname strings template template user user } variable insertcmd {} variable comments 1 variable self {} variable ns {} variable def static variable main __main variable indent 0 variable prelude {} variable statedecl {RDE_PARAM p} variable stateref p variable strings p_string variable template @code@ ; # A string. Together with the # insertcmd (if any) it specifies # how to embed the generated code # into a larger framework (the # template). variable name a_pe_grammar ; # String. Name of the grammar. variable file unknown ; # String. Name of the file or # other entity the grammar came # from. variable user unknown ; # String. Name of the user on # which behalf the conversion has # been invoked. } # ### ### ### ######### ######### ######### ## Ready package provide pt::peg::to::cparam 1.1.3 return |
Changes to modules/pt/pt_peg_to_param.tcl.
1 2 3 4 | # peg_to_param.tcl -- # # Conversion of PEG to PARAM assembler. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 | # peg_to_param.tcl -- # # Conversion of PEG to PARAM assembler. # # Copyright (c) 2009-2014 Andreas Kupries <[email protected]> # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: pt_peg_to_param.tcl,v 1.1 2010/03/26 05:07:24 andreas_kupries Exp $ # This package takes the canonical serialization of a parsing |
︙ | ︙ | |||
368 369 370 371 372 373 374 | proc ::pt::peg::to::param::Op::t {modes char} { variable ::pt::peg::to::param::inline Asm::Start Asm::ReTerminal t $char if {$inline} { Asm::Direct { | | | | | | | | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | proc ::pt::peg::to::param::Op::t {modes char} { variable ::pt::peg::to::param::inline Asm::Start Asm::ReTerminal t $char if {$inline} { Asm::Direct { set c [char quote string $char] Asm::Ins input_next "\"t $c\"" Asm::Ins ok! test_char \"$c\" } } else { Asm::Function [Asm::NewBlock char ] { set c [char quote string $char] Asm::Ins input_next "\"t $c\"" Asm::Ins ok! test_char \"$c\" } } Asm::Done } proc ::pt::peg::to::param::Op::.. {modes chstart chend} { variable ::pt::peg::to::param::inline Asm::Start Asm::ReTerminal .. $chstart $chend if {$inline} { Asm::Direct { set s [char quote string $chstart] set e [char quote string $chend] Asm::Ins input_next "\".. $s $e\"" Asm::Ins ok! test_range \"$s\" \"$e\" } } else { Asm::Function [Asm::NewBlock range] { set s [char quote string $chstart] set e [char quote string $chend] Asm::Ins input_next "\".. $s $e\"" Asm::Ins ok! test_range \"$s\" \"$e\" } } Asm::Done } |
︙ | ︙ | |||
1021 1022 1023 1024 1025 1026 1027 | # which behalf the conversion has # been invoked. } # ### ### ### ######### ######### ######### ## Ready | | | 1021 1022 1023 1024 1025 1026 1027 1028 1029 | # which behalf the conversion has # been invoked. } # ### ### ### ######### ######### ######### ## Ready package provide pt::peg::to::param 1.0.1 return |
Changes to modules/pt/pt_peg_to_tclparam.tcl.
︙ | ︙ | |||
421 422 423 424 425 426 427 | }] } proc ::pt::peg::to::tclparam::Op::t {modes char} { Asm::Start Asm::ReTerminal t $char Asm::Direct { | | | | | | | | | | | | < < > > > | > > > > > > > | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | }] } proc ::pt::peg::to::tclparam::Op::t {modes char} { Asm::Start Asm::ReTerminal t $char Asm::Direct { set char [char quote tcl $char] #Asm::Ins i_input_next "\{t $char\}" #Asm::Ins i:fail_return #Asm::Ins i_test_char $char Asm::Ins si:next_char $char } Asm::Done } proc ::pt::peg::to::tclparam::Op::.. {modes chs che} { Asm::Start Asm::ReTerminal .. $chs $che Asm::Direct { set chs [char quote tcl $chs] set che [char quote tcl $che] #Asm::Ins i_input_next "\{.. $chs $che\}" #Asm::Ins i:fail_return #Asm::Ins i_test_range $chs $che Asm::Ins si:next_range $chs $che } Asm::Done } proc ::pt::peg::to::tclparam::Op::str {modes args} { Asm::Start Asm::ReTerminal str {*}$args Asm::Direct { # Without fusing this would be rendered as a sequence of # characters, with associated stack churn for each character/part # (See Op::x, void/all). set str [join $args {}] set str [char quote tcl $str] Asm::Ins si:next_str $str } Asm::Done } proc ::pt::peg::to::tclparam::Op::cl {modes args} { # rorc = Range-OR-Char-List Asm::Start Asm::ReTerminal cl {*}$args Asm::Direct { # Without fusing this would be rendered as a choice of # characters, with associated stack churn for each # character/branch (See Op::/, void/all). set cl [join [Ranges {*}$args] {}] set cl [char quote tcl $cl] Asm::Ins si:next_class $cl } Asm::Done } proc ::pt::peg::to::tclparam::Op::Ranges {args} { set res {} foreach rorc $args { lappend res [Range $rorc] } return $res } proc ::pt::peg::to::tclparam::Op::Range {rorc} { # See also pt::peg::to::peg # We use string ops here to distinguish terminals and ranges. The # input can be a single char, not a list, and further the char may # not be a proper list. Example: double-apostroph. |
︙ | ︙ | |||
503 504 505 506 507 508 509 | set res {} for {set i $s} {$i <= $e} {incr i} { append res [format %c $i] } return $res } else { | | | 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | set res {} for {set i $s} {$i <= $e} {incr i} { append res [format %c $i] } return $res } else { return $rorc ;#[char quote tcl $rorc] } } proc ::pt::peg::to::tclparam::Op::n {modes symbol} { # symbol mode determines AST generation # void => non-generative, # leaf/value => generative. |
︙ | ︙ | |||
1257 1258 1259 1260 1261 1262 1263 | # which behalf the conversion has # been invoked. } # ### ### ### ######### ######### ######### ## Ready | | | 1265 1266 1267 1268 1269 1270 1271 1272 1273 | # which behalf the conversion has # been invoked. } # ### ### ### ######### ######### ######### ## Ready package provide pt::peg::to::tclparam 1.0.2 return |