File: reader_peg.tcl

package info (click to toggle)
tcllib 1.20%2Bdfsg-1
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 68,064 kB
  • sloc: tcl: 216,842; ansic: 14,250; sh: 2,846; xml: 1,766; yacc: 1,145; pascal: 881; makefile: 107; perl: 84; f90: 84; python: 33; ruby: 13; php: 11
file content (169 lines) | stat: -rw-r--r-- 3,879 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# -*- tcl -*- 
# -- $Id: reader_peg.tcl,v 1.1 2005/09/28 04:51:22 andreas_kupries Exp $ ---
#
# PAGE plugin - reader - PEG ~ Parsing Expression Grammar
#

# ### ### ### ######### ######### #########
## Imported API

# -----------------+--
# page_read        | Access to the input stream.
# page_read_done   |
# page_eof         |
# -----------------+--
# page_info        | Reporting to the user.
# page_warning     |
# page_error       |
# -----------------+--
# page_log_error   | Reporting of internals.
# page_log_warning |
# page_log_info    |
# -----------------+--

# ### ### ### ######### ######### #########
## Exported API

# -----------------+--
# page_rfeature    | Query for special plugin features page might wish to use.
# page_rtime       | Activate collection of timing statistics.
# page_rgettime    | Return the collected timing statistics.
# page_rlabel      | User readable label for the plugin.
# page_rhelp       | Doctools help text for plugin.
# page_roptions    | Options understood by plugin.
# page_rconfigure  | Option (re)configuration.
# page_rdata       | External access to processed input stream.
# page_rrun        | Process input stream per plugin configuration and hardwiring.
# -----------------+--

# ### ### ### ######### ######### #########
## Requisites

package require page::util::norm::peg ; # Normalize AST generated by reader of PEG grammars
package require page::parse::peg      ; # Mengine based parser for PE grammars.
package require struct::tree          ; # Data structure.
package require grammar::me::util     ; # AST conversion

global usec
global timed
set    timed 0

global cline
global ccol

# ### ### ### ######### ######### #########
## Implementation of exported API

proc page_rlabel {} {
    return {Parsing Expression Grammar}
}

proc page_rfeature {key} {
    return [string eq $key timeable]
}

proc page_rtime {} {
    global timed
    set    timed 1
    return
}

proc page_rgettime {} {
    global  usec
    return $usec
}

proc page_rhelp {} {
    return {}
}

proc page_roptions {} {
    return {}
}

proc page_rconfigure {option value} {
    return -code error "Cannot set value of unknown option \"$option\""
}

## proc page_rdata {} {}
## Created in 'Initialize'

proc page_rrun {} {
    global timed usec cline ccol
    page_log_info "reader/peg/run/parse"

    set ast {}
    set err {}

    # Location of the next character to be read.
    set cline 1
    set ccol  0

    if {$timed} {
	set usec [lindex [time {
	    set ok [::page::parse::peg::parse ::Next err ast]
	}] 0] ; #{}
    } else {
	set ok [::page::parse::peg::parse ::Next err ast]
    }
    page_read_done
    page_log_info "reader/peg/run/check-for-errors"

    if {!$ok} {
	foreach {olc   messages} $err     break
	foreach {offset linecol} $olc     break
	foreach {line       col} $linecol break

	set olc [string map {{ } _} \
		[format %5d $line]]@[string map {{ } _} \
		[format %3d $col]]/([format %5d $offset])

	foreach m $messages {
	    page_log_error "reader/peg/run: $olc: $m"
	    page_error $m $linecol
	}

	page_log_info "reader/peg/run/failed"
	return {}
    }

    page_log_info "reader/peg/run/ast-conversion"

    struct::tree                        ::tree
    ::grammar::me::util::ast2etree $ast ::grammar::me::tcl ::tree
    ::page::util::norm::peg             ::tree

    set ast [::tree serialize]
    ::tree destroy

    page_log_info "reader/peg/run/ok"
    return $ast
}

# ### ### ### ######### ######### #########
## Internal helper code.

proc Next {} {
    global cline ccol

    if {[page_eof]} {return {}}

    set ch [page_read 1]

    if {$ch eq ""} {return {}}

    set tok [list $ch {} $cline $ccol]

    if {$ch eq "\n"} {
	incr cline ; set ccol 0
    } else {
	incr ccol
    }

    return $tok
}

# ### ### ### ######### ######### #########
## Initialization

package provide page::reader::peg 0.1