yard 0.9.20 → 0.9.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of yard might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.dockerignore +2 -0
- data/.github/ISSUE_TEMPLATE.md +33 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.rubocop.yml +99 -0
- data/.travis.yml +52 -0
- data/.yardopts_guide +19 -0
- data/.yardopts_i18n +23 -0
- data/CHANGELOG.md +16 -0
- data/CODE_OF_CONDUCT.md +15 -0
- data/CONTRIBUTING.md +140 -0
- data/Dockerfile.samus +28 -0
- data/Gemfile +32 -0
- data/README.md +2 -0
- data/SECURITY.md +26 -0
- data/lib/yard/code_objects/base.rb +8 -1
- data/lib/yard/code_objects/proxy.rb +4 -0
- data/lib/yard/handlers/ruby/attribute_handler.rb +1 -1
- data/lib/yard/handlers/ruby/dsl_handler_methods.rb +3 -3
- data/lib/yard/handlers/ruby/method_handler.rb +0 -10
- data/lib/yard/handlers/ruby/mixin_handler.rb +13 -1
- data/lib/yard/parser/c/statement.rb +2 -0
- data/lib/yard/parser/ruby/ast_node.rb +11 -0
- data/lib/yard/parser/ruby/legacy/irb/slex.rb +276 -0
- data/lib/yard/parser/ruby/legacy/ruby_lex.rb +3 -12
- data/lib/yard/parser/ruby/legacy/statement.rb +2 -0
- data/lib/yard/parser/ruby/ruby_parser.rb +1 -1
- data/lib/yard/registry_resolver.rb +47 -5
- data/lib/yard/registry_store.rb +6 -1
- data/lib/yard/templates/helpers/html_helper.rb +20 -3
- data/lib/yard/version.rb +1 -1
- data/po/ja.po +31108 -0
- data/samus.json +80 -0
- data/spec/code_objects/base_spec.rb +15 -0
- data/spec/code_objects/extra_file_object_spec.rb +4 -3
- data/spec/code_objects/proxy_spec.rb +6 -0
- data/spec/handlers/dsl_handler_spec.rb +7 -0
- data/spec/handlers/examples/dsl_handler_001.rb.txt +2 -0
- data/spec/handlers/examples/extend_handler_001.rb.txt +4 -1
- data/spec/handlers/examples/mixin_handler_001.rb.txt +3 -0
- data/spec/handlers/extend_handler_spec.rb +4 -0
- data/spec/handlers/method_handler_spec.rb +24 -0
- data/spec/handlers/mixin_handler_spec.rb +4 -0
- data/spec/registry_store_spec.rb +11 -0
- data/spec/templates/examples/module001.html +3 -3
- data/spec/templates/examples/module002.html +1 -1
- data/spec/templates/examples/module003.html +1 -1
- data/spec/templates/markup_processor_integrations/asciidoctor_spec.rb +60 -0
- data/spec/templates/markup_processor_integrations/integration_spec_helper.rb +46 -0
- data/spec/templates/markup_processor_integrations/rdoc_markdown_spec.rb +59 -0
- data/spec/templates/markup_processor_integrations/rdoc_spec.rb +39 -0
- data/spec/templates/markup_processor_integrations/redcarpet_spec.rb +59 -0
- data/spec/templates/markup_processor_integrations/redcloth_spec.rb +48 -0
- data/templates/default/docstring/setup.rb +1 -1
- data/templates/default/fulldoc/html/css/style.css +2 -2
- data/templates/default/fulldoc/html/frames.erb +1 -1
- data/templates/default/fulldoc/html/full_list.erb +1 -1
- data/templates/default/fulldoc/html/js/app.js +14 -3
- data/templates/default/fulldoc/html/js/jquery.js +2 -4
- data/templates/default/layout/html/headers.erb +1 -1
- data/templates/default/layout/html/script_setup.erb +1 -1
- data/templates/default/onefile/html/headers.erb +1 -1
- data/templates/default/tags/html/tag.erb +1 -1
- data/templates/guide/layout/html/layout.erb +1 -1
- data/yard.gemspec +1 -20
- metadata +27 -21
- data/spec/examples.txt +0 -1883
    
        data/Dockerfile.samus
    ADDED
    
    | @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            FROM lsegal/samus:latest as samus
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            FROM ruby:2
         | 
| 4 | 
            +
            ARG VERSION
         | 
| 5 | 
            +
            ENV VERSION=${VERSION}
         | 
| 6 | 
            +
            WORKDIR /github/lsegal/yard
         | 
| 7 | 
            +
            ENTRYPOINT samus publish release-v${VERSION}.tar.gz
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # Prepare credential config
         | 
| 10 | 
            +
            RUN mkdir -p ~/.ssh
         | 
| 11 | 
            +
            RUN echo "Host *" > ~/.ssh/config
         | 
| 12 | 
            +
            RUN echo "    StrictHostKeyChecking no" >> ~/.ssh/config
         | 
| 13 | 
            +
            RUN chmod 400 ~/.ssh/config
         | 
| 14 | 
            +
            COPY ./.samusprep/.samus /root/.samus
         | 
| 15 | 
            +
            COPY ./.samusprep/.gitconfig /root/.gitconfig
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            # Setup Samus
         | 
| 18 | 
            +
            ENV PATH=$PATH:/samus/bin
         | 
| 19 | 
            +
            COPY --from=samus /samus /samus
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            # Install gems
         | 
| 22 | 
            +
            ENV BUNDLE_PATH=/var/gems
         | 
| 23 | 
            +
            COPY Gemfile /github/lsegal/yard
         | 
| 24 | 
            +
            RUN bundle
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            # Run build
         | 
| 27 | 
            +
            COPY . /github/lsegal/yard
         | 
| 28 | 
            +
            RUN samus build --skip-restore ${VERSION}
         | 
    
        data/Gemfile
    ADDED
    
    | @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
            source 'https://rubygems.org'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            group :development do
         | 
| 5 | 
            +
              gem 'rspec'
         | 
| 6 | 
            +
              gem 'rake'
         | 
| 7 | 
            +
              gem 'rdoc'
         | 
| 8 | 
            +
              gem 'json'
         | 
| 9 | 
            +
              gem 'simplecov'
         | 
| 10 | 
            +
              gem 'samus', '~> 3.0.8', :require => false
         | 
| 11 | 
            +
              gem 'coveralls', :require => false
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            group :asciidoc do
         | 
| 15 | 
            +
              gem 'asciidoctor'
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            group :markdown do
         | 
| 19 | 
            +
              gem 'redcarpet', :platforms => [:ruby]
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            group :textile do
         | 
| 23 | 
            +
              gem 'RedCloth', :platforms => [:ruby]
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            group :server do
         | 
| 27 | 
            +
              gem 'rack'
         | 
| 28 | 
            +
            end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            group :i18n do
         | 
| 31 | 
            +
              gem 'gettext'
         | 
| 32 | 
            +
            end
         | 
    
        data/README.md
    CHANGED
    
    | @@ -226,6 +226,8 @@ The second most obvious is to generate docs via a Rake task. You can do this by | |
| 226 226 | 
             
            adding the following to your `Rakefile`:
         | 
| 227 227 |  | 
| 228 228 | 
             
            ```ruby
         | 
| 229 | 
            +
            require 'yard'
         | 
| 230 | 
            +
             | 
| 229 231 | 
             
            YARD::Rake::YardocTask.new do |t|
         | 
| 230 232 | 
             
             t.files   = ['lib/**/*.rb', OTHER_PATHS]   # optional
         | 
| 231 233 | 
             
             t.options = ['--any', '--extra', '--opts'] # optional
         | 
    
        data/SECURITY.md
    ADDED
    
    | @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            # Security Policy
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## Supported Versions
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            The following versions are supported with security patches for
         | 
| 6 | 
            +
            any reported vulnerabilities in YARD or dependent software.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            | Version | Supported          |
         | 
| 9 | 
            +
            | ------- | ------------------ |
         | 
| 10 | 
            +
            | 0.9.x   | :white_check_mark: |
         | 
| 11 | 
            +
            | < 0.9   | :x:                |
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            ## Reporting a Vulnerability
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            If you've discovered a vulnerability in YARD source code, please email
         | 
| 16 | 
            +
            lsegal@soen.ca with as much information as possible. You should typically
         | 
| 17 | 
            +
            receive a response within 24-48 hours, though depending on scheduling
         | 
| 18 | 
            +
            it may take up to a week to respond. If you do not get a response on
         | 
| 19 | 
            +
            your initial email within a few days, please re-send your email or
         | 
| 20 | 
            +
            reach out on other channels (such as yardoc@googlegroups.com) to
         | 
| 21 | 
            +
            try to get a hold of a maintainer. Please do not include sensitive
         | 
| 22 | 
            +
            material if you are reaching out through secondary channels unless
         | 
| 23 | 
            +
            you first receive confirmation that it is okay.
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            Thank you for your help and cooperation in making YARD a stable and
         | 
| 26 | 
            +
            safe piece of software.
         | 
| @@ -189,6 +189,10 @@ module YARD | |
| 189 189 | 
             
                    def new(namespace, name, *args, &block)
         | 
| 190 190 | 
             
                      raise ArgumentError, "invalid empty object name" if name.to_s.empty?
         | 
| 191 191 | 
             
                      if namespace.is_a?(ConstantObject)
         | 
| 192 | 
            +
                        unless namespace.value =~ /\A#{NAMESPACEMATCH}\Z/
         | 
| 193 | 
            +
                          raise Parser::UndocumentableError, "constant mapping"
         | 
| 194 | 
            +
                        end
         | 
| 195 | 
            +
             | 
| 192 196 | 
             
                        namespace = Proxy.new(namespace.namespace, namespace.value)
         | 
| 193 197 | 
             
                      end
         | 
| 194 198 |  | 
| @@ -382,11 +386,14 @@ module YARD | |
| 382 386 | 
             
                  #   as a +String+ for the definition of the code object only (not the block)
         | 
| 383 387 | 
             
                  def source=(statement)
         | 
| 384 388 | 
             
                    if statement.respond_to?(:source)
         | 
| 385 | 
            -
                      self.signature = statement.first_line
         | 
| 386 389 | 
             
                      @source = format_source(statement.source.strip)
         | 
| 387 390 | 
             
                    else
         | 
| 388 391 | 
             
                      @source = format_source(statement.to_s)
         | 
| 389 392 | 
             
                    end
         | 
| 393 | 
            +
             | 
| 394 | 
            +
                    if statement.respond_to?(:signature)
         | 
| 395 | 
            +
                      self.signature = statement.signature
         | 
| 396 | 
            +
                    end
         | 
| 390 397 | 
             
                  end
         | 
| 391 398 |  | 
| 392 399 | 
             
                  # The documentation string associated with the object
         | 
| @@ -58,6 +58,10 @@ module YARD | |
| 58 58 | 
             
                    self.type = type
         | 
| 59 59 |  | 
| 60 60 | 
             
                    if @namespace.is_a?(ConstantObject)
         | 
| 61 | 
            +
                      unless @namespace.value =~ /\A#{NAMESPACEMATCH}\Z/
         | 
| 62 | 
            +
                        raise Parser::UndocumentableError, "constant mapping"
         | 
| 63 | 
            +
                      end
         | 
| 64 | 
            +
             | 
| 61 65 | 
             
                      @origname = nil # forget these for a constant
         | 
| 62 66 | 
             
                      @orignamespace = nil
         | 
| 63 67 | 
             
                      @namespace = Proxy.new(@namespace.namespace, @namespace.value)
         | 
| @@ -45,7 +45,7 @@ class YARD::Handlers::Ruby::AttributeHandler < YARD::Handlers::Ruby::Base | |
| 45 45 | 
             
                      else
         | 
| 46 46 | 
             
                        src = "def #{meth}"
         | 
| 47 47 | 
             
                        full_src = "#{src}\n  @#{name}\nend"
         | 
| 48 | 
            -
                        doc = "Returns the value of attribute #{name}"
         | 
| 48 | 
            +
                        doc = "Returns the value of attribute #{name}."
         | 
| 49 49 | 
             
                      end
         | 
| 50 50 | 
             
                      o.source ||= full_src
         | 
| 51 51 | 
             
                      o.signature ||= src
         | 
| @@ -40,9 +40,9 @@ module YARD | |
| 40 40 | 
             
                        return register_docstring(nil)
         | 
| 41 41 | 
             
                      end
         | 
| 42 42 |  | 
| 43 | 
            -
                       | 
| 44 | 
            -
             | 
| 45 | 
            -
                       | 
| 43 | 
            +
                      register MethodObject.new(namespace, method_name, scope) do |o|
         | 
| 44 | 
            +
                        o.signature = method_signature
         | 
| 45 | 
            +
                      end
         | 
| 46 46 | 
             
                    end
         | 
| 47 47 |  | 
| 48 48 | 
             
                    def register_docstring(object, docstring = @docstring, stmt = statement)
         | 
| @@ -21,7 +21,6 @@ class YARD::Handlers::Ruby::MethodHandler < YARD::Handlers::Ruby::Base | |
| 21 21 |  | 
| 22 22 | 
             
                nobj = P(namespace, nobj.value) while nobj.type == :constant
         | 
| 23 23 | 
             
                obj = register MethodObject.new(nobj, meth, mscope) do |o|
         | 
| 24 | 
            -
                  o.signature = method_signature
         | 
| 25 24 | 
             
                  o.explicit = true
         | 
| 26 25 | 
             
                  o.parameters = args
         | 
| 27 26 | 
             
                end
         | 
| @@ -102,13 +101,4 @@ class YARD::Handlers::Ruby::MethodHandler < YARD::Handlers::Ruby::Base | |
| 102 101 |  | 
| 103 102 | 
             
                params
         | 
| 104 103 | 
             
              end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
              def method_signature
         | 
| 107 | 
            -
                method_name = statement.method_name(true)
         | 
| 108 | 
            -
                if statement.parameters.any? {|e| e }
         | 
| 109 | 
            -
                  "def #{method_name}(#{statement.parameters.source})"
         | 
| 110 | 
            -
                else
         | 
| 111 | 
            -
                  "def #{method_name}"
         | 
| 112 | 
            -
                end
         | 
| 113 | 
            -
              end
         | 
| 114 104 | 
             
            end
         | 
| @@ -32,6 +32,18 @@ class YARD::Handlers::Ruby::MixinHandler < YARD::Handlers::Ruby::Base | |
| 32 32 | 
             
                  obj = Proxy.new(namespace, mixin.source, :module)
         | 
| 33 33 | 
             
                end
         | 
| 34 34 |  | 
| 35 | 
            -
                 | 
| 35 | 
            +
                rec = recipient(mixin)
         | 
| 36 | 
            +
                return if rec.nil? || rec.mixins(scope).include?(obj)
         | 
| 37 | 
            +
                rec.mixins(scope).unshift(obj)
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              def recipient(mixin)
         | 
| 41 | 
            +
                if statement[0].type == :var_ref && statement[0][0] != s(:kw, "self")
         | 
| 42 | 
            +
                  statement[0][0].type == :const ?
         | 
| 43 | 
            +
                    Proxy.new(namespace, statement.namespace.source) :
         | 
| 44 | 
            +
                    nil
         | 
| 45 | 
            +
                else
         | 
| 46 | 
            +
                  namespace
         | 
| 47 | 
            +
                end
         | 
| 36 48 | 
             
              end
         | 
| 37 49 | 
             
            end
         | 
| @@ -485,6 +485,17 @@ module YARD | |
| 485 485 | 
             
                      include_block_param ? params : params[0...-1]
         | 
| 486 486 | 
             
                    end
         | 
| 487 487 |  | 
| 488 | 
            +
                    def signature
         | 
| 489 | 
            +
                      params_src = ''
         | 
| 490 | 
            +
                      params = self[1 + index_adjust]
         | 
| 491 | 
            +
                      if params.first
         | 
| 492 | 
            +
                        params_src = params.type == :paren ? '' : ' '
         | 
| 493 | 
            +
                        params_src += params.source.gsub(/\s+(\s|\))/m, '\1')
         | 
| 494 | 
            +
                      end
         | 
| 495 | 
            +
             | 
| 496 | 
            +
                      "def #{method_name(true)}#{params_src}"
         | 
| 497 | 
            +
                    end
         | 
| 498 | 
            +
             | 
| 488 499 | 
             
                    alias block last
         | 
| 489 500 |  | 
| 490 501 | 
             
                    private
         | 
| @@ -0,0 +1,276 @@ | |
| 1 | 
            +
            # frozen_string_literal: false
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            #   irb/slex.rb - simple lex analyzer
         | 
| 4 | 
            +
            #   	$Release Version: 0.9.6$
         | 
| 5 | 
            +
            #   	$Revision$
         | 
| 6 | 
            +
            #   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
         | 
| 7 | 
            +
            #
         | 
| 8 | 
            +
            # --
         | 
| 9 | 
            +
            #
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            #
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            require "irb/notifier"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            # :stopdoc:
         | 
| 16 | 
            +
            module IRB
         | 
| 17 | 
            +
              class SLex
         | 
| 18 | 
            +
                DOUT = Notifier::def_notifier("SLex::")
         | 
| 19 | 
            +
                D_WARN = DOUT::def_notifier(1, "Warn: ")
         | 
| 20 | 
            +
                D_DEBUG = DOUT::def_notifier(2, "Debug: ")
         | 
| 21 | 
            +
                D_DETAIL = DOUT::def_notifier(4, "Detail: ")
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                DOUT.level = Notifier::D_NOMSG
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def initialize
         | 
| 26 | 
            +
                  @head = Node.new("")
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def def_rule(token, preproc = nil, postproc = nil, &block)
         | 
| 30 | 
            +
                  D_DETAIL.pp token
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  postproc = block if block_given?
         | 
| 33 | 
            +
                  create(token, preproc, postproc)
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def def_rules(*tokens, &block)
         | 
| 37 | 
            +
                  if block_given?
         | 
| 38 | 
            +
                    p = block
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
                  for token in tokens
         | 
| 41 | 
            +
                    def_rule(token, nil, p)
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def preproc(token, proc)
         | 
| 46 | 
            +
                  node = search(token)
         | 
| 47 | 
            +
                  node.preproc=proc
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                # need a check?
         | 
| 51 | 
            +
                def postproc(token)
         | 
| 52 | 
            +
                  node = search(token, proc)
         | 
| 53 | 
            +
                  node.postproc=proc
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def search(token)
         | 
| 57 | 
            +
                  @head.search(token.split(//))
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def create(token, preproc = nil, postproc = nil)
         | 
| 61 | 
            +
                  @head.create_subnode(token.split(//), preproc, postproc)
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                def match(token)
         | 
| 65 | 
            +
                  case token
         | 
| 66 | 
            +
                  when Array
         | 
| 67 | 
            +
                  when String
         | 
| 68 | 
            +
                    return match(token.split(//))
         | 
| 69 | 
            +
                  else
         | 
| 70 | 
            +
                    return @head.match_io(token)
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                  ret = @head.match(token)
         | 
| 73 | 
            +
                  D_DETAIL.exec_if{D_DETAIL.printf "match end: %s:%s\n", ret, token.inspect}
         | 
| 74 | 
            +
                  ret
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                def inspect
         | 
| 78 | 
            +
                  format("<SLex: @head = %s>", @head.inspect)
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                #----------------------------------------------------------------------
         | 
| 82 | 
            +
                #
         | 
| 83 | 
            +
                #   class Node -
         | 
| 84 | 
            +
                #
         | 
| 85 | 
            +
                #----------------------------------------------------------------------
         | 
| 86 | 
            +
                class Node
         | 
| 87 | 
            +
                  # if postproc is nil, this node is an abstract node.
         | 
| 88 | 
            +
                  # if postproc is non-nil, this node is a real node.
         | 
| 89 | 
            +
                  def initialize(preproc = nil, postproc = nil)
         | 
| 90 | 
            +
                    @Tree = {}
         | 
| 91 | 
            +
                    @preproc = preproc
         | 
| 92 | 
            +
                    @postproc = postproc
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                  attr_accessor :preproc
         | 
| 96 | 
            +
                  attr_accessor :postproc
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                  def search(chrs, opt = nil)
         | 
| 99 | 
            +
                    return self if chrs.empty?
         | 
| 100 | 
            +
                    ch = chrs.shift
         | 
| 101 | 
            +
                    if node = @Tree[ch]
         | 
| 102 | 
            +
                      node.search(chrs, opt)
         | 
| 103 | 
            +
                    else
         | 
| 104 | 
            +
                      if opt
         | 
| 105 | 
            +
                        chrs.unshift ch
         | 
| 106 | 
            +
                        self.create_subnode(chrs)
         | 
| 107 | 
            +
                      else
         | 
| 108 | 
            +
                        raise "node nothing"
         | 
| 109 | 
            +
                      end
         | 
| 110 | 
            +
                    end
         | 
| 111 | 
            +
                  end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                  def create_subnode(chrs, preproc = nil, postproc = nil)
         | 
| 114 | 
            +
                    if chrs.empty?
         | 
| 115 | 
            +
                      if @postproc
         | 
| 116 | 
            +
                        D_DETAIL.pp node
         | 
| 117 | 
            +
                        raise "node already exists"
         | 
| 118 | 
            +
                      else
         | 
| 119 | 
            +
                        D_DEBUG.puts "change abstract node to real node."
         | 
| 120 | 
            +
                        @preproc = preproc
         | 
| 121 | 
            +
                        @postproc = postproc
         | 
| 122 | 
            +
                      end
         | 
| 123 | 
            +
                      return self
         | 
| 124 | 
            +
                    end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                    ch = chrs.shift
         | 
| 127 | 
            +
                    if node = @Tree[ch]
         | 
| 128 | 
            +
                      if chrs.empty?
         | 
| 129 | 
            +
                        if node.postproc
         | 
| 130 | 
            +
                          DebugLogger.pp node
         | 
| 131 | 
            +
                          DebugLogger.pp self
         | 
| 132 | 
            +
                          DebugLogger.pp ch
         | 
| 133 | 
            +
                          DebugLogger.pp chrs
         | 
| 134 | 
            +
                          raise "node already exists"
         | 
| 135 | 
            +
                        else
         | 
| 136 | 
            +
                          D_WARN.puts "change abstract node to real node"
         | 
| 137 | 
            +
                          node.preproc = preproc
         | 
| 138 | 
            +
                          node.postproc = postproc
         | 
| 139 | 
            +
                        end
         | 
| 140 | 
            +
                      else
         | 
| 141 | 
            +
                        node.create_subnode(chrs, preproc, postproc)
         | 
| 142 | 
            +
                      end
         | 
| 143 | 
            +
                    else
         | 
| 144 | 
            +
                      if chrs.empty?
         | 
| 145 | 
            +
                        node = Node.new(preproc, postproc)
         | 
| 146 | 
            +
                      else
         | 
| 147 | 
            +
                        node = Node.new
         | 
| 148 | 
            +
                        node.create_subnode(chrs, preproc, postproc)
         | 
| 149 | 
            +
                      end
         | 
| 150 | 
            +
                      @Tree[ch] = node
         | 
| 151 | 
            +
                    end
         | 
| 152 | 
            +
                    node
         | 
| 153 | 
            +
                  end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                  #
         | 
| 156 | 
            +
                  # chrs: String
         | 
| 157 | 
            +
                  #       character array
         | 
| 158 | 
            +
                  #       io must have getc()/ungetc(); and ungetc() must be
         | 
| 159 | 
            +
                  #       able to be called arbitrary number of times.
         | 
| 160 | 
            +
                  #
         | 
| 161 | 
            +
                  def match(chrs, op = "")
         | 
| 162 | 
            +
                    D_DETAIL.print "match>: ", chrs, "op:", op, "\n"
         | 
| 163 | 
            +
                    if chrs.empty?
         | 
| 164 | 
            +
                      if @preproc.nil? || @preproc.call(op, chrs)
         | 
| 165 | 
            +
                        DOUT.printf(D_DETAIL, "op1: %s\n", op)
         | 
| 166 | 
            +
                        @postproc.call(op, chrs)
         | 
| 167 | 
            +
                      else
         | 
| 168 | 
            +
                        nil
         | 
| 169 | 
            +
                      end
         | 
| 170 | 
            +
                    else
         | 
| 171 | 
            +
                      ch = chrs.shift
         | 
| 172 | 
            +
                      if node = @Tree[ch]
         | 
| 173 | 
            +
                        if ret = node.match(chrs, op+ch)
         | 
| 174 | 
            +
                          return ret
         | 
| 175 | 
            +
                        else
         | 
| 176 | 
            +
                          chrs.unshift ch
         | 
| 177 | 
            +
                          if @postproc and @preproc.nil? || @preproc.call(op, chrs)
         | 
| 178 | 
            +
                            DOUT.printf(D_DETAIL, "op2: %s\n", op.inspect)
         | 
| 179 | 
            +
                            ret = @postproc.call(op, chrs)
         | 
| 180 | 
            +
                            return ret
         | 
| 181 | 
            +
                          else
         | 
| 182 | 
            +
                            return nil
         | 
| 183 | 
            +
                          end
         | 
| 184 | 
            +
                        end
         | 
| 185 | 
            +
                      else
         | 
| 186 | 
            +
                        chrs.unshift ch
         | 
| 187 | 
            +
                        if @postproc and @preproc.nil? || @preproc.call(op, chrs)
         | 
| 188 | 
            +
                          DOUT.printf(D_DETAIL, "op3: %s\n", op)
         | 
| 189 | 
            +
                          @postproc.call(op, chrs)
         | 
| 190 | 
            +
                          return ""
         | 
| 191 | 
            +
                        else
         | 
| 192 | 
            +
                          return nil
         | 
| 193 | 
            +
                        end
         | 
| 194 | 
            +
                      end
         | 
| 195 | 
            +
                    end
         | 
| 196 | 
            +
                  end
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                  def match_io(io, op = "")
         | 
| 199 | 
            +
                    if op == ""
         | 
| 200 | 
            +
                      ch = io.getc
         | 
| 201 | 
            +
                      if ch == nil
         | 
| 202 | 
            +
                        return nil
         | 
| 203 | 
            +
                      end
         | 
| 204 | 
            +
                    else
         | 
| 205 | 
            +
                      ch = io.getc_of_rests
         | 
| 206 | 
            +
                    end
         | 
| 207 | 
            +
                    if ch.nil?
         | 
| 208 | 
            +
                      if @preproc.nil? || @preproc.call(op, io)
         | 
| 209 | 
            +
                        D_DETAIL.printf("op1: %s\n", op)
         | 
| 210 | 
            +
                        @postproc.call(op, io)
         | 
| 211 | 
            +
                      else
         | 
| 212 | 
            +
                        nil
         | 
| 213 | 
            +
                      end
         | 
| 214 | 
            +
                    else
         | 
| 215 | 
            +
                      if node = @Tree[ch]
         | 
| 216 | 
            +
                        if ret = node.match_io(io, op+ch)
         | 
| 217 | 
            +
                          ret
         | 
| 218 | 
            +
                        else
         | 
| 219 | 
            +
                          io.ungetc ch
         | 
| 220 | 
            +
                          if @postproc and @preproc.nil? || @preproc.call(op, io)
         | 
| 221 | 
            +
                            DOUT.exec_if{D_DETAIL.printf "op2: %s\n", op.inspect}
         | 
| 222 | 
            +
                            @postproc.call(op, io)
         | 
| 223 | 
            +
                          else
         | 
| 224 | 
            +
                            nil
         | 
| 225 | 
            +
                          end
         | 
| 226 | 
            +
                        end
         | 
| 227 | 
            +
                      else
         | 
| 228 | 
            +
                        io.ungetc ch
         | 
| 229 | 
            +
                        if @postproc and @preproc.nil? || @preproc.call(op, io)
         | 
| 230 | 
            +
                          D_DETAIL.printf("op3: %s\n", op)
         | 
| 231 | 
            +
                          @postproc.call(op, io)
         | 
| 232 | 
            +
                        else
         | 
| 233 | 
            +
                          nil
         | 
| 234 | 
            +
                        end
         | 
| 235 | 
            +
                      end
         | 
| 236 | 
            +
                    end
         | 
| 237 | 
            +
                  end
         | 
| 238 | 
            +
                end
         | 
| 239 | 
            +
              end
         | 
| 240 | 
            +
            end
         | 
| 241 | 
            +
            # :startdoc:
         | 
| 242 | 
            +
             | 
| 243 | 
            +
            if $0 == __FILE__
         | 
| 244 | 
            +
              case $1
         | 
| 245 | 
            +
              when "1"
         | 
| 246 | 
            +
                tr = SLex.new
         | 
| 247 | 
            +
                print "0: ", tr.inspect, "\n"
         | 
| 248 | 
            +
                tr.def_rule("=") {print "=\n"}
         | 
| 249 | 
            +
                print "1: ", tr.inspect, "\n"
         | 
| 250 | 
            +
                tr.def_rule("==") {print "==\n"}
         | 
| 251 | 
            +
                print "2: ", tr.inspect, "\n"
         | 
| 252 | 
            +
             | 
| 253 | 
            +
                print "case 1:\n"
         | 
| 254 | 
            +
                print tr.match("="), "\n"
         | 
| 255 | 
            +
                print "case 2:\n"
         | 
| 256 | 
            +
                print tr.match("=="), "\n"
         | 
| 257 | 
            +
                print "case 3:\n"
         | 
| 258 | 
            +
                print tr.match("=>"), "\n"
         | 
| 259 | 
            +
             | 
| 260 | 
            +
              when "2"
         | 
| 261 | 
            +
                tr = SLex.new
         | 
| 262 | 
            +
                print "0: ", tr.inspect, "\n"
         | 
| 263 | 
            +
                tr.def_rule("=") {print "=\n"}
         | 
| 264 | 
            +
                print "1: ", tr.inspect, "\n"
         | 
| 265 | 
            +
                tr.def_rule("==", proc{false}) {print "==\n"}
         | 
| 266 | 
            +
                print "2: ", tr.inspect, "\n"
         | 
| 267 | 
            +
             | 
| 268 | 
            +
                print "case 1:\n"
         | 
| 269 | 
            +
                print tr.match("="), "\n"
         | 
| 270 | 
            +
                print "case 2:\n"
         | 
| 271 | 
            +
                print tr.match("=="), "\n"
         | 
| 272 | 
            +
                print "case 3:\n"
         | 
| 273 | 
            +
                print tr.match("=>"), "\n"
         | 
| 274 | 
            +
              end
         | 
| 275 | 
            +
              exit
         | 
| 276 | 
            +
            end
         |