nandoc 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README +5 -4
- data/Rakefile +1 -1
- data/bin/nandoc +2 -1
- data/doc/FAQ.md +3 -0
- data/doc/PROVISO.md +39 -0
- data/doc/commands/diff.md +49 -0
- data/doc/svg/less-fonts.svg +2 -2
- data/lib/nandoc/cli/README.md +6 -0
- data/lib/nandoc/cli/command-methods.rb +38 -0
- data/lib/nandoc/cli/option-methods/exclusive-options.rb +56 -0
- data/lib/nandoc/cli/option-methods/option-enum.rb +64 -0
- data/lib/nandoc/cli/option-methods.rb +35 -0
- data/lib/nandoc/cli.rb +3 -0
- data/lib/nandoc/commands/create-nandoc-site.rb +9 -12
- data/lib/nandoc/commands/diff.rb +14 -11
- data/lib/nandoc/commands.rb +9 -0
- data/lib/nandoc/{config.rb → core/config.rb} +18 -9
- data/lib/nandoc/core/project.rb +50 -0
- data/lib/nandoc/doc/hack-free-zone-defined.md +33 -0
- data/lib/nandoc/erb/agent.rb +5 -5
- data/lib/nandoc/{test/minitest-extlib.rb → extlib/minitest.rb} +1 -1
- data/lib/nandoc/filters/builtin-tags/fence/terminal.rb +24 -0
- data/lib/nandoc/filters/builtin-tags/fence-dispatcher.rb +43 -0
- data/lib/nandoc/filters/builtin-tags/fences.rb +4 -0
- data/lib/nandoc/filters/builtin-tags/see-test.rb +67 -0
- data/lib/nandoc/filters/builtin-tags.rb +11 -0
- data/lib/nandoc/filters/custom-tag.rb +43 -0
- data/lib/nandoc/filters/custom-tags.rb +19 -0
- data/lib/nandoc/filters/tag-parse-instance-methods.rb +11 -0
- data/lib/nandoc/filters/tag-parser.rb +206 -0
- data/lib/nandoc/filters.rb +11 -585
- data/lib/nandoc/{cri-hacks.rb → hacks/cri-hacks.rb} +4 -3
- data/lib/nandoc/{data-source.rb → hacks/data-source.rb} +5 -4
- data/lib/nandoc/{item-class-hacks.rb → hacks/item-class-hacks.rb} +3 -1
- data/lib/nandoc/hacks.rb +6 -0
- data/lib/nandoc/helpers/menu-bouncy.rb +1 -1
- data/lib/nandoc/helpers/site-map.rb +3 -0
- data/lib/nandoc/helpers.rb +1 -1
- data/lib/nandoc/html/tags.rb +65 -0
- data/lib/nandoc/html.rb +6 -0
- data/lib/nandoc/parse-readme.rb +4 -0
- data/lib/nandoc/spec-doc/agent-instance-methods.rb +24 -0
- data/lib/nandoc/spec-doc/code-snippet.rb +59 -0
- data/lib/nandoc/spec-doc/generic-agent.rb +40 -0
- data/lib/nandoc/spec-doc/mock-prompt.rb +3 -9
- data/lib/nandoc/spec-doc/parse-trace.rb +25 -0
- data/lib/nandoc/spec-doc/{mini-test/spec-instance-methods.rb → playback/html/foo-bar.rb} +0 -0
- data/lib/nandoc/spec-doc/playback/html.rb +2 -0
- data/lib/nandoc/spec-doc/playback/players/method.rb +64 -0
- data/lib/nandoc/spec-doc/playback/players/ruby.rb +158 -0
- data/lib/nandoc/spec-doc/playback/players/terminal.rb +93 -0
- data/lib/nandoc/spec-doc/playback/players.rb +4 -0
- data/lib/nandoc/spec-doc/playback/support/playback-methods.rb +44 -0
- data/lib/nandoc/spec-doc/playback/support/sexp-scanner.rb +61 -0
- data/lib/nandoc/spec-doc/playback/support.rb +3 -0
- data/lib/nandoc/spec-doc/playback/terminal/color-to-html.rb +100 -0
- data/lib/nandoc/spec-doc/playback.rb +3 -0
- data/lib/nandoc/spec-doc/recordings.rb +55 -0
- data/lib/nandoc/spec-doc/ruby2ruby-standin.rb +37 -0
- data/lib/nandoc/spec-doc/test-case-agent.rb +1 -1
- data/lib/nandoc/spec-doc/{mini-test.rb → test-framework/mini-test/proxy.rb} +9 -31
- data/lib/nandoc/spec-doc/{test-framework-proxy.rb → test-framework/proxy.rb} +27 -50
- data/lib/nandoc/spec-doc.rb +57 -13
- data/lib/nandoc/{test → support}/diff-to-string.rb +0 -0
- data/lib/nandoc/support/regexp-enhance.rb +6 -0
- data/lib/nandoc/support/regexp.rb +12 -0
- data/lib/nandoc/support/secret-parent.rb +21 -0
- data/lib/nandoc/support/shared-attr-reader.rb +32 -0
- data/lib/nandoc/support/site-merge.rb +1 -1
- data/lib/nandoc/support/site-methods.rb +4 -4
- data/lib/nandoc/support/stream-colorizer.rb +1 -1
- data/lib/nandoc/support/string-methods.rb +56 -0
- data/lib/nandoc.rb +12 -35
- data/proto/README.md +4 -2
- data/test/test.rb +1 -0
- metadata +58 -25
- data/doc/bar/baz.md +0 -4
- data/doc/bar/bliff.md +0 -8
- data/doc/foo.md +0 -5
- data/doc/getting-started.rb +0 -13
- data/lib/nandoc/spec-doc/support-modules.rb +0 -158
- data/lib/nandoc/spec-doc/test-framework-dispatcher.rb +0 -15
- data/lib/nandoc/support-modules.rb +0 -273
- data/lib/nandoc/treebis/NOGIT-DOCS/NEWS.md +0 -5
- data/lib/nandoc/treebis/NOGIT-README.md +0 -65
- data/lib/nandoc/treebis/nandoc.persistent.json +0 -3
@@ -0,0 +1,33 @@
|
|
1
|
+
## hack free zones defined
|
2
|
+
|
3
|
+
the intended audience of this document is developers of nanDoc.
|
4
|
+
|
5
|
+
out of necessity parts of this project are hack-ful zone. but parts of it are designated hack-free. Following is a definition of what it means to be hack-free.
|
6
|
+
|
7
|
+
these guidelines are to encourage consistency, clarity of intent (self-documenting code), and code that is susceptible to being refactored (agile) with the least hassle.
|
8
|
+
|
9
|
+
(in the below as in ruby a `class` is a `module`, so 'module' also refers to class.)
|
10
|
+
|
11
|
+
a 'hack free zone' is:
|
12
|
+
|
13
|
+
* no opening up of other people's gem classes. this also applies to Stdlib and Corelib! (except special cases for testing.)
|
14
|
+
* no being inside of other people's gem modules unless necessitated by their api
|
15
|
+
* module dependencies SHOULD be cited appropriately when not explicit from requires at the top of the file
|
16
|
+
* no policy yet on circular dependencies, but if we can avoid them, MUST not reopen classes, *or reopening of modules*, except to add modules.
|
17
|
+
* each module MUST be defined in a file named after the module with one exception[^1]. a corollary of this is and the above is that at most one module can be defined in a file. [^1]:The one exception to this is class-private classes or modules.
|
18
|
+
* module hierarchy MUST be reflected in folder hierarchy
|
19
|
+
* however, folder hierarchy CAN be semantic (logical groupings) and doesn't have to follow module hierarchy exactly, but must fall within it:
|
20
|
+
* so, the module tree MUST fit cleanly inside the filesystem tree, while the opposite is not necessarily true
|
21
|
+
* for example, NanDoc::StringMethods could be pulled in by `require 'nandoc/support/string-methods.rb`' but each component of the full constant name must appear in the path.
|
22
|
+
* a module 1) SHOULD first have at least one line of documentation comment, 2) MUST then have any includes or `extend`s 3) MUST then open up the class or module's singleton class if necesssary to define any class or module methods 4) SHOULD list method definitions in alphabetical order (exception intialize with MUST (5) come at the top.)
|
23
|
+
* every file is a leaf file or a branch file. which it is is not discernible from looking at the filename.
|
24
|
+
* branch files are files whose sole purpose include other files (primarily) that are children of a folder sibling to that file which shares the same name as that file without the '*.rb' extension.
|
25
|
+
* any require statements MUST occur as the first lines in a file, unless the point below
|
26
|
+
* if a module depends on another module:
|
27
|
+
* if the dependee is above and/or outside and around, just include it with rubygems-style "require 'nandoc/foo/bar'". If you don't and you instead reach up with File.expand_path(..) then a child node in the filestem tree cannot as easily move around because it is coupled with parent, uncle, or cousin node structure.
|
28
|
+
* use the "require File.dirname(__FILE__)"-style of include only for files that require files below them.
|
29
|
+
* modules that require other modules SHOULD require the files for those other modules _in situ_, and not rely on a parent branch-node file having knowledge of the child module's dependencies. exceptions for a branch file that can require module files that many child modules require.
|
30
|
+
* a module can load a dependee conditionally from a method (with the `require` statement occuring in a method and not at the top of the file), but the way in which the file is required MUST follow the above guidelines.
|
31
|
+
|
32
|
+
|
33
|
+
the end.
|
data/lib/nandoc/erb/agent.rb
CHANGED
@@ -6,7 +6,7 @@ module NanDoc::Erb
|
|
6
6
|
#
|
7
7
|
|
8
8
|
class << self
|
9
|
-
include NanDoc::
|
9
|
+
include NanDoc::Cli::OptionMethods
|
10
10
|
|
11
11
|
# put parameter values from the command line into the erb files
|
12
12
|
# in the task
|
@@ -30,7 +30,7 @@ module NanDoc::Erb
|
|
30
30
|
def args_none
|
31
31
|
err "Please provide args for the erb templates."
|
32
32
|
show_usage
|
33
|
-
|
33
|
+
command_abort
|
34
34
|
end
|
35
35
|
|
36
36
|
def args_parse
|
@@ -39,7 +39,7 @@ module NanDoc::Erb
|
|
39
39
|
unless /\A--([-_a-z0-9]*)=(.+)\Z/ =~ str
|
40
40
|
err "couldn't parse #{str.inspect} -- expecting \"--foo='bar'\""
|
41
41
|
show_usage
|
42
|
-
|
42
|
+
command_abort
|
43
43
|
end
|
44
44
|
hash[normalize_opt_key($1)] = $2
|
45
45
|
end
|
@@ -64,7 +64,7 @@ module NanDoc::Erb
|
|
64
64
|
err "missing erb parameter(s): #{miss.join(' ')}" if miss.any?
|
65
65
|
if miss.any? or suck.any?
|
66
66
|
show_usage;
|
67
|
-
|
67
|
+
command_abort
|
68
68
|
end
|
69
69
|
have
|
70
70
|
end
|
@@ -73,7 +73,7 @@ module NanDoc::Erb
|
|
73
73
|
$stderr.puts(*a)
|
74
74
|
end
|
75
75
|
|
76
|
-
def
|
76
|
+
def command_abort
|
77
77
|
exit(1)
|
78
78
|
end
|
79
79
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'nandoc/spec-doc/playback'
|
2
|
+
require 'nandoc/spec-doc/ruby2ruby-standin'
|
3
|
+
|
4
|
+
module NanDoc::Filters::Fence
|
5
|
+
class Terminal
|
6
|
+
include NanDoc::SpecDoc::Ruby2RubyStandin
|
7
|
+
include NanDoc::SpecDoc::Playback::Terminal::ColorToHtml
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def =~ str
|
11
|
+
str =~ /\Afrom the command line\Z/
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def run out, indent, label, content
|
16
|
+
content_ind = reindent_content content, indent
|
17
|
+
# if color codes colorize color codes, else prompts
|
18
|
+
html = terminal_color_to_html(content_ind)
|
19
|
+
html ||= prompt_highlight(content_ind)
|
20
|
+
out.push_tag_now 'pre', 'terminal', html
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'nandoc/html'
|
2
|
+
|
3
|
+
module NanDoc::Filters
|
4
|
+
class FenceDispatcher
|
5
|
+
Re = %r<
|
6
|
+
(.*?)
|
7
|
+
^((?:[ ]|\t)*)((?:[a-z]|[ ])+):(?:[ ]|\t)*\n
|
8
|
+
\2~~~(?:[ ]|\t)*\n
|
9
|
+
(.*?)\n
|
10
|
+
\2~~~(?:[ ]|\t)*\n
|
11
|
+
>mx
|
12
|
+
@fences = []
|
13
|
+
class << self
|
14
|
+
def =~ item_content
|
15
|
+
Re =~ item_content
|
16
|
+
end
|
17
|
+
def register fent
|
18
|
+
@fences.push fent
|
19
|
+
end
|
20
|
+
attr_reader :fences
|
21
|
+
end
|
22
|
+
def run item_content
|
23
|
+
scn = StringScanner.new(item_content)
|
24
|
+
out = NanDoc::Html::Tags.new
|
25
|
+
while (match = scn.scan_until(Re))
|
26
|
+
Re =~ match or fail("internal parse fail :(")
|
27
|
+
noparse, indent, label, content = $~.captures
|
28
|
+
fence_cls = self.class.fences.detect{ |fent| fent =~ label }
|
29
|
+
if ! fence_cls
|
30
|
+
# silently fail on unidentified blocks for now, pass them thru
|
31
|
+
out.push_raw $~[0]
|
32
|
+
else
|
33
|
+
out.push_raw noparse
|
34
|
+
fence_tag = fence_cls.new
|
35
|
+
fence_tag.run(out, indent, label, content)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
out.push_raw scn.rest
|
39
|
+
html = out.to_html
|
40
|
+
html
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
require 'nandoc/spec-doc'
|
3
|
+
require 'nandoc/spec-doc/playback'
|
4
|
+
require 'nandoc/html'
|
5
|
+
|
6
|
+
module NanDoc::Filters
|
7
|
+
class SeeTest
|
8
|
+
include TagParseInstanceMethods
|
9
|
+
private
|
10
|
+
Re = %r{\(see:[ ]*(?:spec|test)[^\s]+
|
11
|
+
(?:
|
12
|
+
[ ]*
|
13
|
+
(?:--?|/)
|
14
|
+
[ ]*
|
15
|
+
(?:
|
16
|
+
'[^']*' |
|
17
|
+
"[^"]*" |
|
18
|
+
[^\s'"]+
|
19
|
+
)
|
20
|
+
)+ \)[ ]*\n
|
21
|
+
}x
|
22
|
+
Re2 = /(.*)(#{Re.source})/mx
|
23
|
+
class << self
|
24
|
+
def =~ item_content
|
25
|
+
Re =~ item_content
|
26
|
+
end
|
27
|
+
end
|
28
|
+
public
|
29
|
+
def run item_content
|
30
|
+
scn = MyStringScanner.new(item_content)
|
31
|
+
doc = NanDoc::Html::Tags.new
|
32
|
+
while (match = scn.scan_until(Re))
|
33
|
+
noparse, parse = Re2 =~ match && $1, $2
|
34
|
+
doc.push_raw noparse
|
35
|
+
scn2 = MyStringScanner.new(parse)
|
36
|
+
scn2.skip(/\(see: */)
|
37
|
+
path = scn2.scan_assert(/[-\w]+\.\w+/i, 'path')
|
38
|
+
things = []
|
39
|
+
loop do
|
40
|
+
scn2.skip(%r<\s*(?:--?|/)\s*>)
|
41
|
+
this = scn2.scan(/ '[^']*' | "[^"]*" | [^\s'"]+ /x) or
|
42
|
+
fail("internal parse fail near #{scn2.rest.inspect}")
|
43
|
+
things.push unquote(this)
|
44
|
+
scn2.skip(/\)\s*/)
|
45
|
+
scn2.eos? and break
|
46
|
+
end
|
47
|
+
playback = NanDoc::SpecDoc::Playback::Method.new(path, things)
|
48
|
+
playback.make_html doc
|
49
|
+
end
|
50
|
+
doc.push_raw scn.rest
|
51
|
+
html = doc.to_html
|
52
|
+
html
|
53
|
+
end
|
54
|
+
# push it up if desired
|
55
|
+
class MyStringScanner < StringScanner
|
56
|
+
def scan_assert foo, name=nil
|
57
|
+
ret = scan(foo)
|
58
|
+
unless ret
|
59
|
+
use_name = name ? "#{name} (/#{foo.source}/)" :
|
60
|
+
"/#{foo.source}/"
|
61
|
+
fail("Unable to find #{use_name} in #{rest.inspect}")
|
62
|
+
end
|
63
|
+
ret
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
require File.dirname(__FILE__)+'/tag-parser.rb'
|
3
|
+
require 'nandoc/spec-doc'
|
4
|
+
|
5
|
+
module NanDoc::Filters
|
6
|
+
class CustomTag
|
7
|
+
include TagParsingInstanceMethods
|
8
|
+
def initialize
|
9
|
+
end
|
10
|
+
def name
|
11
|
+
@name || 'anonymous custom filter'
|
12
|
+
end
|
13
|
+
def tag_parser
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
private :tag_parser
|
17
|
+
def wants? md
|
18
|
+
tp = tag_parser
|
19
|
+
ret = nil
|
20
|
+
if ! tp
|
21
|
+
ret = false
|
22
|
+
@last_failure_lines = ["#{name} doesn't want #{md[:content].inspect}"]
|
23
|
+
else
|
24
|
+
if tree = tp.parse(md[:content])
|
25
|
+
ret = true
|
26
|
+
@last_tree = tree
|
27
|
+
else
|
28
|
+
ret = false
|
29
|
+
these = tp.failure_lines(md[:content])
|
30
|
+
these.unshift("#{name} couldn't parse tag:")
|
31
|
+
@last_failure_lines = these
|
32
|
+
end
|
33
|
+
end
|
34
|
+
ret
|
35
|
+
end
|
36
|
+
def get_failure_lines md
|
37
|
+
@last_failure_lines
|
38
|
+
end
|
39
|
+
def render_block filter, md
|
40
|
+
fail("this is the one you want to implement. look at @last_tree maybe.")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module NanDoc::Filters
|
2
|
+
class CustomTagsClass < Array
|
3
|
+
def register_class cls
|
4
|
+
unshift cls
|
5
|
+
end
|
6
|
+
def change_item_content content
|
7
|
+
each do |cls|
|
8
|
+
if cls =~ content
|
9
|
+
tag_filter = cls.new
|
10
|
+
new_content = tag_filter.run(content)
|
11
|
+
content.replace(new_content)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
content
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
CustomTags = CustomTagsClass.new
|
19
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
module NanDoc::Filters
|
2
|
+
class CustomTag # we are just (re) opening this class
|
3
|
+
|
4
|
+
class TagParser
|
5
|
+
# treetop?
|
6
|
+
#
|
7
|
+
def initialize
|
8
|
+
@last_failure_lines = nil
|
9
|
+
end
|
10
|
+
def failure_lines *ignored
|
11
|
+
@last_failure_lines
|
12
|
+
end
|
13
|
+
def get_symbol mixed
|
14
|
+
if mixed.kind_of?(ParserSymbol)
|
15
|
+
mixed
|
16
|
+
elsif :start == mixed
|
17
|
+
name = symbols[:start]
|
18
|
+
sym = get_symbol_with_name(name)
|
19
|
+
elsif :end == mixed
|
20
|
+
sym = EndSymbol
|
21
|
+
elsif mixed.kind_of?(Array)
|
22
|
+
sym = Seq.new(self, mixed)
|
23
|
+
else
|
24
|
+
sym = get_symbol_with_name(mixed)
|
25
|
+
end
|
26
|
+
sym
|
27
|
+
end
|
28
|
+
def get_symbol_with_name name
|
29
|
+
thing = symbols[name] or fail("Symbol not found: #{name.inspect}")
|
30
|
+
sym = case thing
|
31
|
+
when Hash
|
32
|
+
RegexpSymbol.new(self, thing, name)
|
33
|
+
else
|
34
|
+
fail("no: #{thing.inspect}")
|
35
|
+
end
|
36
|
+
sym
|
37
|
+
end
|
38
|
+
def get_start_symbol
|
39
|
+
get_symbol(:start)
|
40
|
+
end
|
41
|
+
# return tree or (nil and set failure lines)
|
42
|
+
def parse str
|
43
|
+
sym = get_start_symbol
|
44
|
+
scn = StringScanner.new(str)
|
45
|
+
sex = []
|
46
|
+
fails = []
|
47
|
+
ok = true
|
48
|
+
while sym
|
49
|
+
ch_ret = sym.parse(scn, sex, fails)
|
50
|
+
case ch_ret
|
51
|
+
when ParserSymbol
|
52
|
+
sym = ch_ret
|
53
|
+
when false;
|
54
|
+
ok = false
|
55
|
+
break
|
56
|
+
when true;
|
57
|
+
ok = true
|
58
|
+
break
|
59
|
+
else
|
60
|
+
debugger; 'x'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
if ok
|
64
|
+
sex
|
65
|
+
else
|
66
|
+
@last_failure_lines = fails
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
def symbols
|
71
|
+
@symbols ||= begin
|
72
|
+
self.class.const_get(:Symbols) or
|
73
|
+
fail("Symbols constant not found in #{self.class}")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
module ParserSymbol
|
77
|
+
def secret_grammar grammar
|
78
|
+
sing = class << self; self end
|
79
|
+
kelsey = grammar
|
80
|
+
sing.send(:define_method, :grammar){ kelsey }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
class EndSymbolClass
|
84
|
+
include ParserSymbol
|
85
|
+
def parse scn, sex, fails
|
86
|
+
puts "END is parsing #{scn.rest.inspect}"
|
87
|
+
ret = nil
|
88
|
+
if scn.rest == ""
|
89
|
+
ret = true
|
90
|
+
sex.push [:end]
|
91
|
+
else
|
92
|
+
fails.push "expecting end of input near #{scn.rest.inspect}"
|
93
|
+
ret = false
|
94
|
+
end
|
95
|
+
ret
|
96
|
+
end
|
97
|
+
end
|
98
|
+
EndSymbol = EndSymbolClass.new
|
99
|
+
class RegexpSymbol
|
100
|
+
include ParserSymbol
|
101
|
+
def initialize(grammar, hash, name)
|
102
|
+
secret_grammar grammar
|
103
|
+
@desc = hash[:desc] or fail("no")
|
104
|
+
@re = hash[:re] or fail("no")
|
105
|
+
@next = hash[:next]
|
106
|
+
@no_sexp = hash[:no_sexp]
|
107
|
+
self.name = name
|
108
|
+
end
|
109
|
+
attr_reader :desc
|
110
|
+
attr_accessor :name
|
111
|
+
attr_reader :re
|
112
|
+
attr_reader :next
|
113
|
+
def next_symbol_or_nil
|
114
|
+
self.next and grammar.get_symbol(self.next)
|
115
|
+
end
|
116
|
+
# @return nil iff you succeed and have no next
|
117
|
+
# @return next parser if you succeed and have a next parser
|
118
|
+
# @return false if you fail
|
119
|
+
def parse scn, sex, fails
|
120
|
+
print "[#{name.inspect}] is parsing #{scn.rest.inspect}"
|
121
|
+
my_ret = nil
|
122
|
+
if matched = scn.scan(re)
|
123
|
+
sex.push([name, matched]) unless @no_sexp
|
124
|
+
my_ret = next_symbol_or_nil
|
125
|
+
my_ret ||= true # assume no next and we parsed it ok
|
126
|
+
puts " matched: #{matched}"
|
127
|
+
else
|
128
|
+
fails.push "expecting #{desc} near #{scn.rest.inspect}."
|
129
|
+
my_ret = false
|
130
|
+
puts " not found"
|
131
|
+
end
|
132
|
+
my_ret
|
133
|
+
end
|
134
|
+
end
|
135
|
+
# union production
|
136
|
+
class Or < Array
|
137
|
+
include ParserSymbol
|
138
|
+
class << self
|
139
|
+
def [](*arr)
|
140
|
+
new(arr)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
# def parse scn, sex, fails
|
144
|
+
# debugger; 'x'
|
145
|
+
# my_fails = []
|
146
|
+
# my_ret = nil
|
147
|
+
# found = false
|
148
|
+
# self.each do |child|
|
149
|
+
# ch_fails = []
|
150
|
+
# ch_ret = child.parse(scn, sex, ch_fails)
|
151
|
+
# end
|
152
|
+
# end
|
153
|
+
end
|
154
|
+
# concatentation production
|
155
|
+
class Seq
|
156
|
+
include ParserSymbol
|
157
|
+
def initialize grammar, arr
|
158
|
+
secret_grammar grammar
|
159
|
+
@arr = arr
|
160
|
+
@parsers = Array.new(arr.size)
|
161
|
+
@done = false
|
162
|
+
end
|
163
|
+
def get_parser_at offset
|
164
|
+
@parsers[offset] ||= begin
|
165
|
+
def_thing = @arr[offset]
|
166
|
+
sym = nil
|
167
|
+
if def_thing
|
168
|
+
sym = grammar.get_symbol(def_thing)
|
169
|
+
end
|
170
|
+
sym
|
171
|
+
end
|
172
|
+
end
|
173
|
+
def parse scn, sex, fails
|
174
|
+
my_ret = nil
|
175
|
+
current = 0
|
176
|
+
last = @arr.size - 1
|
177
|
+
sym = get_parser_at(current)
|
178
|
+
while sym
|
179
|
+
puts "sequence at #{current} about to parse #{scn.rest.inspect}"
|
180
|
+
ch_ret = sym.parse(scn, sex, fails)
|
181
|
+
if ch_ret.kind_of?(ParserSymbol)
|
182
|
+
sym = ch_ret
|
183
|
+
elsif ch_ret == false
|
184
|
+
sym = false
|
185
|
+
my_ret = false
|
186
|
+
break
|
187
|
+
elsif ch_ret == true
|
188
|
+
current += 1
|
189
|
+
sym = get_parser_at(current)
|
190
|
+
else
|
191
|
+
fail("don't know what to do with this: #{ch_ret.inspect}")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
if my_ret.nil?
|
195
|
+
if current <= last
|
196
|
+
fail("what happened?")
|
197
|
+
else
|
198
|
+
my_ret = true
|
199
|
+
end
|
200
|
+
end
|
201
|
+
my_ret
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|