├── .codespellignore ├── .github ├── dependabot.yml └── workflows │ ├── codespell.yaml │ ├── gh-pages.yml │ └── test.yaml ├── .gitignore ├── .rdoc_options ├── .rspec ├── Gemfile ├── LEGAL.md ├── MIT ├── NEWS.md ├── README.md ├── Rakefile ├── Steepfile ├── doc ├── Index.md └── development │ └── compressed_state_table │ ├── main.md │ ├── parse.output │ ├── parse.y │ └── parser.rb ├── exe └── lrama ├── lib ├── lrama.rb └── lrama │ ├── bitmap.rb │ ├── command.rb │ ├── context.rb │ ├── counterexamples.rb │ ├── counterexamples │ ├── derivation.rb │ ├── example.rb │ ├── node.rb │ ├── path.rb │ ├── state_item.rb │ └── triple.rb │ ├── diagram.rb │ ├── digraph.rb │ ├── erb.rb │ ├── grammar.rb │ ├── grammar │ ├── auxiliary.rb │ ├── binding.rb │ ├── code.rb │ ├── code │ │ ├── destructor_code.rb │ │ ├── initial_action_code.rb │ │ ├── no_reference_code.rb │ │ ├── printer_code.rb │ │ └── rule_action.rb │ ├── counter.rb │ ├── destructor.rb │ ├── error_token.rb │ ├── inline.rb │ ├── inline │ │ └── resolver.rb │ ├── parameterized.rb │ ├── parameterized │ │ ├── resolver.rb │ │ ├── rhs.rb │ │ └── rule.rb │ ├── percent_code.rb │ ├── precedence.rb │ ├── printer.rb │ ├── reference.rb │ ├── rule.rb │ ├── rule_builder.rb │ ├── stdlib.y │ ├── symbol.rb │ ├── symbols.rb │ ├── symbols │ │ └── resolver.rb │ ├── type.rb │ └── union.rb │ ├── lexer.rb │ ├── lexer │ ├── grammar_file.rb │ ├── location.rb │ ├── token.rb │ └── token │ │ ├── char.rb │ │ ├── ident.rb │ │ ├── instantiate_rule.rb │ │ ├── tag.rb │ │ └── user_code.rb │ ├── logger.rb │ ├── option_parser.rb │ ├── options.rb │ ├── output.rb │ ├── parser.rb │ ├── reporter.rb │ ├── reporter │ ├── conflicts.rb │ ├── grammar.rb │ ├── profile.rb │ ├── profile │ │ ├── call_stack.rb │ │ └── memory.rb │ ├── rules.rb │ ├── states.rb │ └── terms.rb │ ├── state.rb │ ├── state │ ├── action.rb │ ├── action │ │ ├── goto.rb │ │ ├── reduce.rb │ │ └── shift.rb │ ├── inadequacy_annotation.rb │ ├── reduce_reduce_conflict.rb │ ├── resolved_conflict.rb │ └── shift_reduce_conflict.rb │ ├── states.rb │ ├── states │ └── item.rb │ ├── tracer.rb │ ├── tracer │ ├── actions.rb │ ├── closure.rb │ ├── duration.rb │ ├── only_explicit_rules.rb │ ├── rules.rb │ └── state.rb │ ├── version.rb │ ├── warnings.rb │ └── warnings │ ├── conflicts.rb │ ├── redefined_rules.rb │ └── required.rb ├── lrama.gemspec ├── parser.y ├── rbs_collection.lock.yaml ├── rbs_collection.yaml ├── sample ├── calc.output ├── calc.y ├── diagram.html ├── json.y ├── parse.y └── sql.y ├── sig ├── generated │ └── lrama │ │ ├── bitmap.rbs │ │ ├── counterexamples.rbs │ │ ├── counterexamples │ │ ├── derivation.rbs │ │ ├── example.rbs │ │ ├── node.rbs │ │ ├── path.rbs │ │ ├── state_item.rbs │ │ └── triple.rbs │ │ ├── diagram.rbs │ │ ├── digraph.rbs │ │ ├── erb.rbs │ │ ├── grammar.rbs │ │ ├── grammar │ │ ├── auxiliary.rbs │ │ ├── binding.rbs │ │ ├── code.rbs │ │ ├── code │ │ │ ├── destructor_code.rbs │ │ │ ├── initial_action_code.rbs │ │ │ ├── no_reference_code.rbs │ │ │ ├── printer_code.rbs │ │ │ └── rule_action.rbs │ │ ├── counter.rbs │ │ ├── destructor.rbs │ │ ├── error_token.rbs │ │ ├── inline │ │ │ └── resolver.rbs │ │ ├── parameterized │ │ │ ├── resolver.rbs │ │ │ ├── rhs.rbs │ │ │ └── rule.rbs │ │ ├── percent_code.rbs │ │ ├── precedence.rbs │ │ ├── printer.rbs │ │ ├── reference.rbs │ │ ├── rule.rbs │ │ ├── rule_builder.rbs │ │ ├── symbol.rbs │ │ ├── symbols │ │ │ └── resolver.rbs │ │ ├── type.rbs │ │ └── union.rbs │ │ ├── lexer.rbs │ │ ├── lexer │ │ ├── grammar_file.rbs │ │ ├── location.rbs │ │ ├── token.rbs │ │ └── token │ │ │ ├── char.rbs │ │ │ ├── ident.rbs │ │ │ ├── instantiate_rule.rbs │ │ │ ├── tag.rbs │ │ │ └── user_code.rbs │ │ ├── logger.rbs │ │ ├── option_parser.rbs │ │ ├── options.rbs │ │ ├── reporter.rbs │ │ ├── reporter │ │ ├── conflicts.rbs │ │ ├── grammar.rbs │ │ ├── profile │ │ │ ├── call_stack.rbs │ │ │ └── memory.rbs │ │ ├── rules.rbs │ │ ├── states.rbs │ │ └── terms.rbs │ │ ├── state.rbs │ │ ├── state │ │ ├── action │ │ │ ├── goto.rbs │ │ │ ├── reduce.rbs │ │ │ └── shift.rbs │ │ ├── inadequacy_annotation.rbs │ │ ├── reduce_reduce_conflict.rbs │ │ ├── resolved_conflict.rbs │ │ └── shift_reduce_conflict.rbs │ │ ├── states.rbs │ │ ├── states │ │ └── item.rbs │ │ ├── tracer.rbs │ │ ├── tracer │ │ ├── actions.rbs │ │ ├── closure.rbs │ │ ├── duration.rbs │ │ ├── only_explicit_rules.rbs │ │ ├── rules.rbs │ │ └── state.rbs │ │ ├── version.rbs │ │ ├── warnings.rbs │ │ └── warnings │ │ ├── conflicts.rbs │ │ ├── redefined_rules.rbs │ │ └── required.rbs ├── railroad_diagrams │ └── railroad_diagrams.rbs └── stdlib │ └── strscan │ └── string_scanner.rbs ├── spec ├── fixtures │ ├── command │ │ └── basic.y │ ├── common │ │ ├── basic.y │ │ ├── nullable.y │ │ └── unexpected_token.y │ ├── context │ │ └── basic.y │ ├── inlining │ │ ├── basic.y │ │ ├── resolve_index.y │ │ ├── resolve_index_at.y │ │ ├── resolve_index_reverse.y │ │ ├── rhs_include_parameterized.y │ │ └── with_parameters.y │ ├── integration │ │ ├── after_shift.l │ │ ├── after_shift.y │ │ ├── calculator.l │ │ ├── calculator.y │ │ ├── contains_at_reference.l │ │ ├── contains_at_reference.y │ │ ├── destructors.l │ │ ├── destructors.y │ │ ├── error_recovery.l │ │ ├── error_recovery.y │ │ ├── ielr.l │ │ ├── ielr.y │ │ ├── line_number.l │ │ ├── line_number.y │ │ ├── named_references.l │ │ ├── named_references.y │ │ ├── parameterized.l │ │ ├── parameterized.y │ │ ├── params.l │ │ ├── params.y │ │ ├── printers.l │ │ ├── printers.y │ │ ├── prologue_epilogue_optional.l │ │ ├── prologue_epilogue_optional.y │ │ ├── typed_midrule_actions.l │ │ ├── typed_midrule_actions.y │ │ ├── user_defined_parameterized.l │ │ └── user_defined_parameterized.y │ ├── lexer │ │ └── location.y │ ├── parameterized │ │ ├── error │ │ │ ├── invalid_argument_number.y │ │ │ └── invalid_rule_name.y │ │ ├── stdlib │ │ │ ├── delimited.y │ │ │ ├── ioption.y │ │ │ ├── list.y │ │ │ ├── nonempty_list.y │ │ │ ├── option.y │ │ │ ├── option_between_rhs.y │ │ │ ├── option_with_tag.y │ │ │ ├── preceded.y │ │ │ ├── separated_list.y │ │ │ ├── separated_nonempty_list.y │ │ │ └── terminated.y │ │ └── user_defined │ │ │ ├── basic.y │ │ │ ├── multi_arguments.y │ │ │ ├── nested_rules.y │ │ │ ├── nested_rules_in_rhs.y │ │ │ ├── nested_rules_multi_arguments.y │ │ │ ├── nested_rules_symbols.y │ │ │ ├── nested_rules_with_tag.y │ │ │ ├── recursive.y │ │ │ ├── with_action.y │ │ │ ├── with_action_and_named_references.y │ │ │ └── with_tag.y │ └── states │ │ ├── includes_relation.y │ │ └── reads_relation.y ├── lrama │ ├── bitmap_spec.rb │ ├── command_spec.rb │ ├── context_spec.rb │ ├── counterexamples │ │ └── node_spec.rb │ ├── counterexamples_spec.rb │ ├── diagram_spec.rb │ ├── grammar │ │ ├── code_spec.rb │ │ ├── rule_builder_spec.rb │ │ ├── symbol_spec.rb │ │ └── symbols │ │ │ └── resolver_spec.rb │ ├── integration_spec.rb │ ├── lexer │ │ ├── location_spec.rb │ │ └── token │ │ │ └── user_code_spec.rb │ ├── lexer_spec.rb │ ├── option_parser_spec.rb │ ├── output_spec.rb │ ├── parser_spec.rb │ ├── states_spec.rb │ ├── trace │ │ ├── actions_spec.rb │ │ ├── closure_spec.rb │ │ ├── only_explicit_rules_spec.rb │ │ ├── rules_spec.rb │ │ └── state_spec.rb │ ├── warnings │ │ ├── conflicts_spec.rb │ │ ├── redefined_rules_spec.rb │ │ └── required_spec.rb │ └── warnings_spec.rb └── spec_helper.rb └── template ├── bison ├── _yacc.h ├── yacc.c └── yacc.h └── diagram └── diagram.html /.codespellignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruby/lrama/4cdf7a62558b6b72a368fe019ef6f66b966ed98f/.codespellignore -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'github-actions' 4 | directory: '/' 5 | schedule: 6 | interval: 'weekly' 7 | -------------------------------------------------------------------------------- /.github/workflows/codespell.yaml: -------------------------------------------------------------------------------- 1 | name: CodeSpell 2 | on: 3 | - pull_request 4 | jobs: 5 | codespell: 6 | name: CodeSpell 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - name: CodeSpell 11 | uses: codespell-project/actions-codespell@master 12 | with: 13 | check_filenames: true 14 | check_hidden: true 15 | ignore_words_file: .codespellignore 16 | exclude_file: lib/lrama/parser.rb 17 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Lrama documentation to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: ["master"] 6 | workflow_dispatch: 7 | 8 | permissions: 9 | contents: read 10 | pages: write 11 | id-token: write 12 | 13 | concurrency: 14 | group: "pages" 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-latest 20 | if: ${{ github.repository == 'ruby/lrama' && !startsWith(github.event_name, 'pull') }} 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | - name: Setup Ruby 25 | uses: ruby/setup-ruby@f26937343756480a8cb3ae1f623b9c8d89ed6984 # v1.196.0 26 | with: 27 | ruby-version: "3.4" 28 | bundler-cache: true 29 | - name: Setup Pages 30 | id: pages 31 | uses: actions/configure-pages@v5 32 | - name: Build with Lrama 33 | run: bundle exec rake rdoc 34 | - name: Upload artifact 35 | uses: actions/upload-pages-artifact@v3 36 | 37 | deploy: 38 | environment: 39 | name: github-pages 40 | url: ${{ steps.deployment.outputs.page_url }} 41 | runs-on: ubuntu-latest 42 | needs: build 43 | steps: 44 | - name: Deploy to GitHub Pages 45 | id: deployment 46 | uses: actions/deploy-pages@v4 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.DS_Store 2 | /.bundle/ 3 | /.gem_rbs_collection/ 4 | /.irbrc 5 | /.vscode/ 6 | /Gemfile.lock 7 | /coverage/ 8 | /parser.output 9 | /pkg/ 10 | /tmp/ 11 | /vendor/bundle 12 | /.idea/ 13 | _site/ 14 | -------------------------------------------------------------------------------- /.rdoc_options: -------------------------------------------------------------------------------- 1 | page_dir: doc 2 | warn_missing_rdoc_ref: true 3 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | gemspec 6 | 7 | gem "pry" 8 | gem "racc", "1.8.1" 9 | gem "rake" 10 | gem "rdoc" 11 | gem "rspec" 12 | gem "simplecov", require: false 13 | gem "stackprof", platforms: [:ruby] # stackprof doesn't support Windows 14 | gem "memory_profiler" 15 | gem "railroad_diagrams", "0.3.0" 16 | 17 | # Recent steep requires Ruby >= 3.0.0. 18 | # Then skip install on some CI jobs. 19 | if !ENV['GITHUB_ACTION'] || ENV['INSTALL_STEEP'] == 'true' 20 | gem "rbs", "3.9.4", require: false 21 | gem "rbs-inline", require: false 22 | gem "steep", "1.10.0", require: false 23 | end 24 | -------------------------------------------------------------------------------- /LEGAL.md: -------------------------------------------------------------------------------- 1 | # LEGAL NOTICE INFORMATION 2 | 3 | All the files in this distribution are covered under the MIT License except some files 4 | mentioned below. 5 | 6 | ## GNU General Public License version 3 7 | 8 | These files are licensed under the GNU General Public License version 3 or later. See these files for more information. 9 | 10 | * template/bison/_yacc.h 11 | * template/bison/yacc.c 12 | * template/bison/yacc.h 13 | -------------------------------------------------------------------------------- /MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Yuichiro Kaneko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | 5 | namespace "build" do 6 | desc "build parser from parser.y" 7 | task :parser do 8 | sh "bundle exec racc parser.y --embedded --frozen -o lib/lrama/parser.rb -t --log-file=parser.output" 9 | end 10 | end 11 | 12 | require 'rspec/core/rake_task' 13 | RSpec::Core::RakeTask.new(:spec) do |spec| 14 | spec.pattern = FileList['spec/**/*_spec.rb'] 15 | end 16 | task :spec => "build:parser" 17 | 18 | require "rdoc/task" 19 | RDoc::Task.new do |rdoc| 20 | rdoc.title = "Lrama Documentation" 21 | rdoc.main = "Index.md" 22 | rdoc.rdoc_dir = "_site" 23 | end 24 | 25 | desc "steep check" 26 | task :steep do 27 | sh "bundle exec steep check" 28 | end 29 | task :steep => :rbs_inline 30 | 31 | desc "Run rbs-inline" 32 | task :rbs_inline do 33 | sh "bundle exec rbs-inline --output lib/" 34 | end 35 | 36 | task default: %i[spec steep] 37 | -------------------------------------------------------------------------------- /Steepfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # D = Steep::Diagnostic 4 | # 5 | target :lib do 6 | repo_path '.gem_rbs_collection/' 7 | signature "sig" 8 | 9 | check "lib/lrama/counterexamples" 10 | check "lib/lrama/grammar" 11 | check "lib/lrama/lexer" 12 | check "lib/lrama/reporter" 13 | check "lib/lrama/state" 14 | check "lib/lrama/states" 15 | check "lib/lrama/tracer" 16 | check "lib/lrama/warnings" 17 | check "lib/lrama/bitmap.rb" 18 | check "lib/lrama/counterexamples.rb" 19 | check "lib/lrama/digraph.rb" 20 | check "lib/lrama/erb.rb" 21 | check "lib/lrama/grammar.rb" 22 | check "lib/lrama/lexer.rb" 23 | check "lib/lrama/logger.rb" 24 | check "lib/lrama/option_parser.rb" 25 | check "lib/lrama/options.rb" 26 | check "lib/lrama/reporter.rb" 27 | check "lib/lrama/tracer.rb" 28 | check "lib/lrama/version.rb" 29 | check "lib/lrama/warnings.rb" 30 | end 31 | -------------------------------------------------------------------------------- /doc/Index.md: -------------------------------------------------------------------------------- 1 | # Lrama 2 | 3 | [![Gem Version](https://badge.fury.io/rb/lrama.svg)](https://badge.fury.io/rb/lrama) 4 | [![build](https://github.com/ruby/lrama/actions/workflows/test.yaml/badge.svg)](https://github.com/ruby/lrama/actions/workflows/test.yaml) 5 | 6 | 7 | ## Overview 8 | 9 | Lrama is LALR (1) parser generator written by Ruby. The first goal of this project is providing error tolerant parser for CRuby with minimal changes on CRuby parse.y file. 10 | 11 | ## Installation 12 | 13 | Lrama's installation is simple. You can install it via RubyGems. 14 | 15 | ```shell 16 | $ gem install lrama 17 | ``` 18 | 19 | From source codes, you can install it as follows: 20 | 21 | ```shell 22 | $ cd "$(lrama root)" 23 | $ bundle install 24 | $ bundle exec rake install 25 | $ bundle exec lrama --version 26 | lrama 0.7.0 27 | ``` 28 | ## Usage 29 | 30 | Lrama is a command line tool. You can generate a parser from a grammar file by running `lrama` command. 31 | 32 | ```shell 33 | # "y.tab.c" and "y.tab.h" are generated 34 | $ lrama -d sample/parse.y 35 | ``` 36 | Specify the output file with `-o` option. The following example generates "calc.c" and "calc.h". 37 | 38 | ```shell 39 | # "calc", "calc.c", and "calc.h" are generated 40 | $ lrama -d sample/calc.y -o calc.c && gcc -Wall calc.c -o calc && ./calc 41 | Enter the formula: 42 | 1 43 | => 1 44 | 1+2*3 45 | => 7 46 | (1+2)*3 47 | => 9 48 | ``` 49 | 50 | ## Supported Ruby version 51 | 52 | Lrama is executed with BASERUBY when building ruby from source code. Therefore Lrama needs to support BASERUBY, currently 2.5, or later version. 53 | 54 | This also requires Lrama to be able to run with only default gems because BASERUBY runs with `--disable=gems` option. 55 | 56 | ## License 57 | 58 | See [LEGAL.md](https://github.com/ruby/lrama/blob/master/LEGAL.md) file. 59 | -------------------------------------------------------------------------------- /doc/development/compressed_state_table/parse.y: -------------------------------------------------------------------------------- 1 | %union { 2 | int val; 3 | } 4 | %token LF 5 | %token NUM 6 | %type expr 7 | %left '+' 8 | %left '*' 9 | 10 | %% 11 | 12 | program : /* empty */ 13 | | expr LF { printf("=> %d\n", $1); } 14 | ; 15 | 16 | expr : NUM 17 | | expr '+' expr { $$ = $1 + $3; } 18 | | expr '*' expr { $$ = $1 * $3; } 19 | | '(' expr ')' { $$ = $2; } 20 | ; 21 | 22 | %% 23 | -------------------------------------------------------------------------------- /exe/lrama: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | $LOAD_PATH << File.join(__dir__, "../lib") 5 | require "lrama" 6 | 7 | Lrama::Command.new(ARGV.dup).run 8 | -------------------------------------------------------------------------------- /lib/lrama.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lrama/bitmap" 4 | require_relative "lrama/command" 5 | require_relative "lrama/context" 6 | require_relative "lrama/counterexamples" 7 | require_relative "lrama/diagram" 8 | require_relative "lrama/digraph" 9 | require_relative "lrama/erb" 10 | require_relative "lrama/grammar" 11 | require_relative "lrama/lexer" 12 | require_relative "lrama/logger" 13 | require_relative "lrama/option_parser" 14 | require_relative "lrama/options" 15 | require_relative "lrama/output" 16 | require_relative "lrama/parser" 17 | require_relative "lrama/reporter" 18 | require_relative "lrama/state" 19 | require_relative "lrama/states" 20 | require_relative "lrama/tracer" 21 | require_relative "lrama/version" 22 | require_relative "lrama/warnings" 23 | -------------------------------------------------------------------------------- /lib/lrama/bitmap.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | module Bitmap 6 | # @rbs! 7 | # type bitmap = Integer 8 | 9 | # @rbs (Array[Integer] ary) -> bitmap 10 | def self.from_array(ary) 11 | bit = 0 12 | 13 | ary.each do |int| 14 | bit |= (1 << int) 15 | end 16 | 17 | bit 18 | end 19 | 20 | # @rbs (Integer int) -> bitmap 21 | def self.from_integer(int) 22 | 1 << int 23 | end 24 | 25 | # @rbs (bitmap int) -> Array[Integer] 26 | def self.to_array(int) 27 | a = [] #: Array[Integer] 28 | i = 0 29 | 30 | while int > 0 do 31 | if int & 1 == 1 32 | a << i 33 | end 34 | 35 | i += 1 36 | int >>= 1 37 | end 38 | 39 | a 40 | end 41 | 42 | # @rbs (bitmap int, Integer size) -> Array[bool] 43 | def self.to_bool_array(int, size) 44 | a = Array.new(size) #: Array[bool] 45 | 46 | size.times do |i| 47 | a[i] = int[i] == 1 48 | end 49 | 50 | a 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/lrama/counterexamples/node.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Counterexamples 6 | # @rbs generic E < Object -- Type of an element 7 | class Node 8 | attr_reader :elem #: E 9 | attr_reader :next_node #: Node[E]? 10 | 11 | # @rbs [E < Object] (Node[E] node) -> Array[E] 12 | def self.to_a(node) 13 | a = [] # steep:ignore UnannotatedEmptyCollection 14 | 15 | while (node) 16 | a << node.elem 17 | node = node.next_node 18 | end 19 | 20 | a 21 | end 22 | 23 | # @rbs (E elem, Node[E]? next_node) -> void 24 | def initialize(elem, next_node) 25 | @elem = elem 26 | @next_node = next_node 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/lrama/counterexamples/path.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Counterexamples 6 | class Path 7 | # @rbs! 8 | # @state_item: StateItem 9 | # @parent: Path? 10 | 11 | attr_reader :state_item #: StateItem 12 | attr_reader :parent #: Path? 13 | 14 | # @rbs (StateItem state_item, Path? parent) -> void 15 | def initialize(state_item, parent) 16 | @state_item = state_item 17 | @parent = parent 18 | end 19 | 20 | # @rbs () -> ::String 21 | def to_s 22 | "#" 23 | end 24 | alias :inspect :to_s 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/lrama/counterexamples/state_item.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Counterexamples 6 | class StateItem 7 | attr_reader :id #: Integer 8 | attr_reader :state #: State 9 | attr_reader :item #: States::Item 10 | 11 | # @rbs (Integer id, State state, States::Item item) -> void 12 | def initialize(id, state, item) 13 | @id = id 14 | @state = state 15 | @item = item 16 | end 17 | 18 | # @rbs () -> (:start | :transition | :production) 19 | def type 20 | case 21 | when item.start_item? 22 | :start 23 | when item.beginning_of_rule? 24 | :production 25 | else 26 | :transition 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/lrama/counterexamples/triple.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Counterexamples 6 | class Triple 7 | attr_reader :precise_lookahead_set #: Bitmap::bitmap 8 | 9 | alias :l :precise_lookahead_set 10 | 11 | # @rbs (StateItem state_item, Bitmap::bitmap precise_lookahead_set) -> void 12 | def initialize(state_item, precise_lookahead_set) 13 | @state_item = state_item 14 | @precise_lookahead_set = precise_lookahead_set 15 | end 16 | 17 | # @rbs () -> State 18 | def state 19 | @state_item.state 20 | end 21 | alias :s :state 22 | 23 | # @rbs () -> States::Item 24 | def item 25 | @state_item.item 26 | end 27 | alias :itm :item 28 | 29 | # @rbs () -> StateItem 30 | def state_item 31 | @state_item 32 | end 33 | 34 | # @rbs () -> ::String 35 | def inspect 36 | "#{state.inspect}. #{item.display_name}. #{l.to_s(2)}" 37 | end 38 | alias :to_s :inspect 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/lrama/erb.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | require "erb" 5 | 6 | module Lrama 7 | class ERB 8 | # @rbs (String file, **untyped kwargs) -> String 9 | def self.render(file, **kwargs) 10 | new(file).render(**kwargs) 11 | end 12 | 13 | # @rbs (String file) -> void 14 | def initialize(file) 15 | input = File.read(file) 16 | if ::ERB.instance_method(:initialize).parameters.last.first == :key 17 | @erb = ::ERB.new(input, trim_mode: '-') 18 | else 19 | @erb = ::ERB.new(input, nil, '-') # steep:ignore UnexpectedPositionalArgument 20 | end 21 | @erb.filename = file 22 | end 23 | 24 | # @rbs (**untyped kwargs) -> String 25 | def render(**kwargs) 26 | @erb.result_with_hash(kwargs) 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/lrama/grammar/auxiliary.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | # Grammar file information not used by States but by Output 7 | class Auxiliary < Struct.new(:prologue_first_lineno, :prologue, :epilogue_first_lineno, :epilogue, keyword_init: true) 8 | # @rbs! 9 | # attr_accessor prologue_first_lineno: Integer 10 | # attr_accessor prologue: String 11 | # attr_accessor epilogue_first_lineno: Integer 12 | # attr_accessor epilogue: String 13 | # 14 | # def initialize: (?prologue_first_lineno: Integer, ?prologue: String, ?epilogue_first_lineno: Integer, ?epilogue: String) -> void 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/lrama/grammar/code.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | require "forwardable" 5 | require_relative "code/destructor_code" 6 | require_relative "code/initial_action_code" 7 | require_relative "code/no_reference_code" 8 | require_relative "code/printer_code" 9 | require_relative "code/rule_action" 10 | 11 | module Lrama 12 | class Grammar 13 | class Code 14 | # @rbs! 15 | # 16 | # # delegated 17 | # def s_value: -> String 18 | # def line: -> Integer 19 | # def column: -> Integer 20 | # def references: -> Array[Lrama::Grammar::Reference] 21 | 22 | extend Forwardable 23 | 24 | def_delegators "token_code", :s_value, :line, :column, :references 25 | 26 | attr_reader :type #: ::Symbol 27 | attr_reader :token_code #: Lexer::Token::UserCode 28 | 29 | # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode) -> void 30 | def initialize(type:, token_code:) 31 | @type = type 32 | @token_code = token_code 33 | end 34 | 35 | # @rbs (Code other) -> bool 36 | def ==(other) 37 | self.class == other.class && 38 | self.type == other.type && 39 | self.token_code == other.token_code 40 | end 41 | 42 | # $$, $n, @$, @n are translated to C code 43 | # 44 | # @rbs () -> String 45 | def translated_code 46 | t_code = s_value.dup 47 | 48 | references.reverse_each do |ref| 49 | first_column = ref.first_column 50 | last_column = ref.last_column 51 | 52 | str = reference_to_c(ref) 53 | 54 | t_code[first_column...last_column] = str 55 | end 56 | 57 | return t_code 58 | end 59 | 60 | private 61 | 62 | # @rbs (Lrama::Grammar::Reference ref) -> bot 63 | def reference_to_c(ref) 64 | raise NotImplementedError.new("#reference_to_c is not implemented") 65 | end 66 | end 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /lib/lrama/grammar/code/destructor_code.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Code 7 | class DestructorCode < Code 8 | # TODO: rbs-inline 0.10.0 doesn't support instance variables. 9 | # Move these type declarations above instance variable definitions, once it's supported. 10 | # 11 | # @rbs! 12 | # @tag: Lexer::Token::Tag 13 | 14 | # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode, tag: Lexer::Token::Tag) -> void 15 | def initialize(type:, token_code:, tag:) 16 | super(type: type, token_code: token_code) 17 | @tag = tag 18 | end 19 | 20 | private 21 | 22 | # * ($$) *yyvaluep 23 | # * (@$) *yylocationp 24 | # * ($:$) error 25 | # * ($1) error 26 | # * (@1) error 27 | # * ($:1) error 28 | # 29 | # @rbs (Reference ref) -> (String | bot) 30 | def reference_to_c(ref) 31 | case 32 | when ref.type == :dollar && ref.name == "$" # $$ 33 | member = @tag.member 34 | "((*yyvaluep).#{member})" 35 | when ref.type == :at && ref.name == "$" # @$ 36 | "(*yylocationp)" 37 | when ref.type == :index && ref.name == "$" # $:$ 38 | raise "$:#{ref.value} can not be used in #{type}." 39 | when ref.type == :dollar # $n 40 | raise "$#{ref.value} can not be used in #{type}." 41 | when ref.type == :at # @n 42 | raise "@#{ref.value} can not be used in #{type}." 43 | when ref.type == :index # $:n 44 | raise "$:#{ref.value} can not be used in #{type}." 45 | else 46 | raise "Unexpected. #{self}, #{ref}" 47 | end 48 | end 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/lrama/grammar/code/initial_action_code.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Code 7 | class InitialActionCode < Code 8 | private 9 | 10 | # * ($$) yylval 11 | # * (@$) yylloc 12 | # * ($:$) error 13 | # * ($1) error 14 | # * (@1) error 15 | # * ($:1) error 16 | # 17 | # @rbs (Reference ref) -> (String | bot) 18 | def reference_to_c(ref) 19 | case 20 | when ref.type == :dollar && ref.name == "$" # $$ 21 | "yylval" 22 | when ref.type == :at && ref.name == "$" # @$ 23 | "yylloc" 24 | when ref.type == :index && ref.name == "$" # $:$ 25 | raise "$:#{ref.value} can not be used in initial_action." 26 | when ref.type == :dollar # $n 27 | raise "$#{ref.value} can not be used in initial_action." 28 | when ref.type == :at # @n 29 | raise "@#{ref.value} can not be used in initial_action." 30 | when ref.type == :index # $:n 31 | raise "$:#{ref.value} can not be used in initial_action." 32 | else 33 | raise "Unexpected. #{self}, #{ref}" 34 | end 35 | end 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/lrama/grammar/code/no_reference_code.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Code 7 | class NoReferenceCode < Code 8 | private 9 | 10 | # * ($$) error 11 | # * (@$) error 12 | # * ($:$) error 13 | # * ($1) error 14 | # * (@1) error 15 | # * ($:1) error 16 | # 17 | # @rbs (Reference ref) -> bot 18 | def reference_to_c(ref) 19 | case 20 | when ref.type == :dollar # $$, $n 21 | raise "$#{ref.value} can not be used in #{type}." 22 | when ref.type == :at # @$, @n 23 | raise "@#{ref.value} can not be used in #{type}." 24 | when ref.type == :index # $:$, $:n 25 | raise "$:#{ref.value} can not be used in #{type}." 26 | else 27 | raise "Unexpected. #{self}, #{ref}" 28 | end 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/lrama/grammar/code/printer_code.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Code 7 | class PrinterCode < Code 8 | # TODO: rbs-inline 0.10.0 doesn't support instance variables. 9 | # Move these type declarations above instance variable definitions, once it's supported. 10 | # 11 | # @rbs! 12 | # @tag: Lexer::Token::Tag 13 | 14 | # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode, tag: Lexer::Token::Tag) -> void 15 | def initialize(type:, token_code:, tag:) 16 | super(type: type, token_code: token_code) 17 | @tag = tag 18 | end 19 | 20 | private 21 | 22 | # * ($$) *yyvaluep 23 | # * (@$) *yylocationp 24 | # * ($:$) error 25 | # * ($1) error 26 | # * (@1) error 27 | # * ($:1) error 28 | # 29 | # @rbs (Reference ref) -> (String | bot) 30 | def reference_to_c(ref) 31 | case 32 | when ref.type == :dollar && ref.name == "$" # $$ 33 | member = @tag.member 34 | "((*yyvaluep).#{member})" 35 | when ref.type == :at && ref.name == "$" # @$ 36 | "(*yylocationp)" 37 | when ref.type == :index && ref.name == "$" # $:$ 38 | raise "$:#{ref.value} can not be used in #{type}." 39 | when ref.type == :dollar # $n 40 | raise "$#{ref.value} can not be used in #{type}." 41 | when ref.type == :at # @n 42 | raise "@#{ref.value} can not be used in #{type}." 43 | when ref.type == :index # $:n 44 | raise "$:#{ref.value} can not be used in #{type}." 45 | else 46 | raise "Unexpected. #{self}, #{ref}" 47 | end 48 | end 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/lrama/grammar/counter.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Counter 7 | # TODO: rbs-inline 0.10.0 doesn't support instance variables. 8 | # Move these type declarations above instance variable definitions, once it's supported. 9 | # 10 | # @rbs! 11 | # @number: Integer 12 | 13 | # @rbs (Integer number) -> void 14 | def initialize(number) 15 | @number = number 16 | end 17 | 18 | # @rbs () -> Integer 19 | def increment 20 | n = @number 21 | @number += 1 22 | n 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/lrama/grammar/destructor.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Destructor < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true) 7 | # @rbs! 8 | # attr_accessor ident_or_tags: Array[Lexer::Token::Ident|Lexer::Token::Tag] 9 | # attr_accessor token_code: Lexer::Token::UserCode 10 | # attr_accessor lineno: Integer 11 | # 12 | # def initialize: (?ident_or_tags: Array[Lexer::Token::Ident|Lexer::Token::Tag], ?token_code: Lexer::Token::UserCode, ?lineno: Integer) -> void 13 | 14 | # @rbs (Lexer::Token::Tag tag) -> String 15 | def translated_code(tag) 16 | Code::DestructorCode.new(type: :destructor, token_code: token_code, tag: tag).translated_code 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/lrama/grammar/error_token.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class ErrorToken < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true) 7 | # @rbs! 8 | # attr_accessor ident_or_tags: Array[Lexer::Token::Ident | Lexer::Token::Tag] 9 | # attr_accessor token_code: Lexer::Token::UserCode 10 | # attr_accessor lineno: Integer 11 | # 12 | # def initialize: (?ident_or_tags: Array[Lexer::Token::Ident|Lexer::Token::Tag], ?token_code: Lexer::Token::UserCode, ?lineno: Integer) -> void 13 | 14 | # @rbs (Lexer::Token::Tag tag) -> String 15 | def translated_code(tag) 16 | Code::PrinterCode.new(type: :error_token, token_code: token_code, tag: tag).translated_code 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/lrama/grammar/inline.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'inline/resolver' 4 | -------------------------------------------------------------------------------- /lib/lrama/grammar/parameterized.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'parameterized/resolver' 4 | require_relative 'parameterized/rhs' 5 | require_relative 'parameterized/rule' 6 | -------------------------------------------------------------------------------- /lib/lrama/grammar/parameterized/rhs.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Parameterized 7 | class Rhs 8 | attr_accessor :symbols #: Array[Lexer::Token] 9 | attr_accessor :user_code #: Lexer::Token::UserCode? 10 | attr_accessor :precedence_sym #: Grammar::Symbol? 11 | 12 | # @rbs () -> void 13 | def initialize 14 | @symbols = [] 15 | @user_code = nil 16 | @precedence_sym = nil 17 | end 18 | 19 | # @rbs (Grammar::Binding bindings) -> Lexer::Token::UserCode? 20 | def resolve_user_code(bindings) 21 | return unless user_code 22 | 23 | resolved = Lexer::Token::UserCode.new(s_value: user_code.s_value, location: user_code.location) 24 | var_to_arg = {} #: Hash[String, String] 25 | symbols.each do |sym| 26 | resolved_sym = bindings.resolve_symbol(sym) 27 | if resolved_sym != sym 28 | var_to_arg[sym.s_value] = resolved_sym.s_value 29 | end 30 | end 31 | 32 | var_to_arg.each do |var, arg| 33 | resolved.references.each do |ref| 34 | if ref.name == var 35 | ref.name = arg 36 | end 37 | end 38 | end 39 | 40 | return resolved 41 | end 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/lrama/grammar/parameterized/rule.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Parameterized 7 | class Rule 8 | attr_reader :name #: String 9 | attr_reader :parameters #: Array[Lexer::Token] 10 | attr_reader :rhs #: Array[Rhs] 11 | attr_reader :required_parameters_count #: Integer 12 | attr_reader :tag #: Lexer::Token::Tag? 13 | 14 | # @rbs (String name, Array[Lexer::Token] parameters, Array[Rhs] rhs, tag: Lexer::Token::Tag?, is_inline: bool) -> void 15 | def initialize(name, parameters, rhs, tag: nil, is_inline: false) 16 | @name = name 17 | @parameters = parameters 18 | @rhs = rhs 19 | @tag = tag 20 | @is_inline = is_inline 21 | @required_parameters_count = parameters.count 22 | end 23 | 24 | # @rbs () -> String 25 | def to_s 26 | "#{@name}(#{@parameters.map(&:s_value).join(', ')})" 27 | end 28 | 29 | # @rbs () -> bool 30 | def inline? 31 | @is_inline 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/lrama/grammar/percent_code.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class PercentCode 7 | # TODO: rbs-inline 0.10.0 doesn't support instance variables. 8 | # Move these type declarations above instance variable definitions, once it's supported. 9 | # 10 | # @rbs! 11 | # @name: String 12 | # @code: String 13 | 14 | attr_reader :name #: String 15 | attr_reader :code #: String 16 | 17 | # @rbs (String name, String code) -> void 18 | def initialize(name, code) 19 | @name = name 20 | @code = code 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/lrama/grammar/precedence.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Precedence < Struct.new(:type, :precedence, keyword_init: true) 7 | include Comparable 8 | # @rbs! 9 | # attr_accessor type: ::Symbol 10 | # attr_accessor precedence: Integer 11 | # 12 | # def initialize: (?type: ::Symbol, ?precedence: Integer) -> void 13 | 14 | # @rbs (Precedence other) -> Integer 15 | def <=>(other) 16 | self.precedence <=> other.precedence 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/lrama/grammar/printer.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Printer < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true) 7 | # @rbs! 8 | # attr_accessor ident_or_tags: Array[Lexer::Token::Ident|Lexer::Token::Tag] 9 | # attr_accessor token_code: Lexer::Token::UserCode 10 | # attr_accessor lineno: Integer 11 | # 12 | # def initialize: (?ident_or_tags: Array[Lexer::Token::Ident|Lexer::Token::Tag], ?token_code: Lexer::Token::UserCode, ?lineno: Integer) -> void 13 | 14 | # @rbs (Lexer::Token::Tag tag) -> String 15 | def translated_code(tag) 16 | Code::PrinterCode.new(type: :printer, token_code: token_code, tag: tag).translated_code 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/lrama/grammar/reference.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | # type: :dollar or :at 7 | # name: String (e.g. $$, $foo, $expr.right) 8 | # number: Integer (e.g. $1) 9 | # index: Integer 10 | # ex_tag: "$1" (Optional) 11 | class Reference < Struct.new(:type, :name, :number, :index, :ex_tag, :first_column, :last_column, keyword_init: true) 12 | # @rbs! 13 | # attr_accessor type: ::Symbol 14 | # attr_accessor name: String 15 | # attr_accessor number: Integer 16 | # attr_accessor index: Integer 17 | # attr_accessor ex_tag: Lexer::Token? 18 | # attr_accessor first_column: Integer 19 | # attr_accessor last_column: Integer 20 | # 21 | # def initialize: (type: ::Symbol, ?name: String, ?number: Integer, ?index: Integer, ?ex_tag: Lexer::Token?, first_column: Integer, last_column: Integer) -> void 22 | 23 | # @rbs () -> (String|Integer) 24 | def value 25 | name || number 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/lrama/grammar/symbols.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "symbols/resolver" 4 | -------------------------------------------------------------------------------- /lib/lrama/grammar/type.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Type 7 | # TODO: rbs-inline 0.10.0 doesn't support instance variables. 8 | # Move these type declarations above instance variable definitions, once it's supported. 9 | # 10 | # @rbs! 11 | # @id: Lexer::Token 12 | # @tag: Lexer::Token::Tag 13 | 14 | attr_reader :id #: Lexer::Token 15 | attr_reader :tag #: Lexer::Token::Tag 16 | 17 | # @rbs (id: Lexer::Token, tag: Lexer::Token::Tag) -> void 18 | def initialize(id:, tag:) 19 | @id = id 20 | @tag = tag 21 | end 22 | 23 | # @rbs (Grammar::Type other) -> bool 24 | def ==(other) 25 | self.class == other.class && 26 | self.id == other.id && 27 | self.tag == other.tag 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/lrama/grammar/union.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Grammar 6 | class Union < Struct.new(:code, :lineno, keyword_init: true) 7 | # @rbs! 8 | # attr_accessor code: Grammar::Code::NoReferenceCode 9 | # attr_accessor lineno: Integer 10 | # 11 | # def initialize: (?code: Grammar::Code::NoReferenceCode, ?lineno: Integer) -> void 12 | 13 | # @rbs () -> String 14 | def braces_less_code 15 | # Braces is already removed by lexer 16 | code.s_value 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/lrama/lexer/grammar_file.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Lexer 6 | class GrammarFile 7 | class Text < String 8 | # @rbs () -> String 9 | def inspect 10 | length <= 50 ? super : "#{self[0..47]}...".inspect 11 | end 12 | end 13 | 14 | attr_reader :path #: String 15 | attr_reader :text #: String 16 | 17 | # @rbs (String path, String text) -> void 18 | def initialize(path, text) 19 | @path = path 20 | @text = Text.new(text).freeze 21 | end 22 | 23 | # @rbs () -> String 24 | def inspect 25 | "<#{self.class}: @path=#{path}, @text=#{text.inspect}>" 26 | end 27 | 28 | # @rbs (GrammarFile other) -> bool 29 | def ==(other) 30 | self.class == other.class && 31 | self.path == other.path 32 | end 33 | 34 | # @rbs () -> Array[String] 35 | def lines 36 | @lines ||= text.split("\n") 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/lrama/lexer/token.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | require_relative 'token/char' 5 | require_relative 'token/ident' 6 | require_relative 'token/instantiate_rule' 7 | require_relative 'token/tag' 8 | require_relative 'token/user_code' 9 | 10 | module Lrama 11 | class Lexer 12 | class Token 13 | attr_reader :s_value #: String 14 | attr_reader :location #: Location 15 | attr_accessor :alias_name #: String 16 | attr_accessor :referred #: bool 17 | 18 | # @rbs (s_value: String, ?alias_name: String, ?location: Location) -> void 19 | def initialize(s_value:, alias_name: nil, location: nil) 20 | s_value.freeze 21 | @s_value = s_value 22 | @alias_name = alias_name 23 | @location = location 24 | end 25 | 26 | # @rbs () -> String 27 | def to_s 28 | "value: `#{s_value}`, location: #{location}" 29 | end 30 | 31 | # @rbs (String string) -> bool 32 | def referred_by?(string) 33 | [self.s_value, self.alias_name].compact.include?(string) 34 | end 35 | 36 | # @rbs (Token other) -> bool 37 | def ==(other) 38 | self.class == other.class && self.s_value == other.s_value 39 | end 40 | 41 | # @rbs () -> Integer 42 | def first_line 43 | location.first_line 44 | end 45 | alias :line :first_line 46 | 47 | # @rbs () -> Integer 48 | def first_column 49 | location.first_column 50 | end 51 | alias :column :first_column 52 | 53 | # @rbs () -> Integer 54 | def last_line 55 | location.last_line 56 | end 57 | 58 | # @rbs () -> Integer 59 | def last_column 60 | location.last_column 61 | end 62 | 63 | # @rbs (Lrama::Grammar::Reference ref, String message) -> bot 64 | def invalid_ref(ref, message) 65 | location = self.location.partial_location(ref.first_column, ref.last_column) 66 | raise location.generate_error_message(message) 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/lrama/lexer/token/char.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Lexer 6 | class Token 7 | class Char < Token 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/lrama/lexer/token/ident.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Lexer 6 | class Token 7 | class Ident < Token 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/lrama/lexer/token/instantiate_rule.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Lexer 6 | class Token 7 | class InstantiateRule < Token 8 | attr_reader :args #: Array[Lexer::Token] 9 | attr_reader :lhs_tag #: Lexer::Token::Tag? 10 | 11 | # @rbs (s_value: String, ?alias_name: String, ?location: Location, ?args: Array[Lexer::Token], ?lhs_tag: Lexer::Token::Tag?) -> void 12 | def initialize(s_value:, alias_name: nil, location: nil, args: [], lhs_tag: nil) 13 | super s_value: s_value, alias_name: alias_name, location: location 14 | @args = args 15 | @lhs_tag = lhs_tag 16 | end 17 | 18 | # @rbs () -> String 19 | def rule_name 20 | s_value 21 | end 22 | 23 | # @rbs () -> Integer 24 | def args_count 25 | args.count 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/lrama/lexer/token/tag.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Lexer 6 | class Token 7 | class Tag < Token 8 | # @rbs () -> String 9 | def member 10 | # Omit "<>" 11 | s_value[1..-2] or raise "Unexpected Tag format (#{s_value})" 12 | end 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/lrama/logger.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Logger 6 | # @rbs (IO out) -> void 7 | def initialize(out = STDERR) 8 | @out = out 9 | end 10 | 11 | # @rbs () -> void 12 | def line_break 13 | @out << "\n" 14 | end 15 | 16 | # @rbs (String message) -> void 17 | def trace(message) 18 | @out << message << "\n" 19 | end 20 | 21 | # @rbs (String message) -> void 22 | def warn(message) 23 | @out << message << "\n" 24 | end 25 | 26 | # @rbs (String message) -> void 27 | def error(message) 28 | @out << message << "\n" 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/lrama/options.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | # Command line options. 6 | class Options 7 | attr_accessor :skeleton #: String 8 | attr_accessor :header #: bool 9 | attr_accessor :header_file #: String? 10 | attr_accessor :report_file #: String? 11 | attr_accessor :outfile #: String 12 | attr_accessor :error_recovery #: bool 13 | attr_accessor :grammar_file #: String 14 | attr_accessor :trace_opts #: Hash[Symbol, bool]? 15 | attr_accessor :report_opts #: Hash[Symbol, bool]? 16 | attr_accessor :warnings #: bool 17 | attr_accessor :y #: IO 18 | attr_accessor :debug #: bool 19 | attr_accessor :define #: Hash[String, String] 20 | attr_accessor :diagram #: bool 21 | attr_accessor :diagram_file #: String 22 | attr_accessor :profile_opts #: Hash[Symbol, bool]? 23 | 24 | # @rbs () -> void 25 | def initialize 26 | @skeleton = "bison/yacc.c" 27 | @define = {} 28 | @header = false 29 | @header_file = nil 30 | @report_file = nil 31 | @outfile = "y.tab.c" 32 | @error_recovery = false 33 | @grammar_file = '' 34 | @trace_opts = nil 35 | @report_opts = nil 36 | @warnings = false 37 | @y = STDIN 38 | @debug = false 39 | @diagram = false 40 | @diagram_file = "diagram.html" 41 | @profile_opts = nil 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/lrama/reporter.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | require_relative 'reporter/conflicts' 5 | require_relative 'reporter/grammar' 6 | require_relative 'reporter/profile' 7 | require_relative 'reporter/rules' 8 | require_relative 'reporter/states' 9 | require_relative 'reporter/terms' 10 | 11 | module Lrama 12 | class Reporter 13 | include Lrama::Tracer::Duration 14 | 15 | # @rbs (**bool options) -> void 16 | def initialize(**options) 17 | @options = options 18 | @rules = Rules.new(**options) 19 | @terms = Terms.new(**options) 20 | @conflicts = Conflicts.new 21 | @grammar = Grammar.new(**options) 22 | @states = States.new(**options) 23 | end 24 | 25 | # @rbs (File io, Lrama::States states) -> void 26 | def report(io, states) 27 | report_duration(:report) do 28 | @rules.report(io, states) 29 | @terms.report(io, states) 30 | @conflicts.report(io, states) 31 | @grammar.report(io, states) 32 | @states.report(io, states) 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/lrama/reporter/conflicts.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Reporter 6 | class Conflicts 7 | # @rbs (IO io, Lrama::States states) -> void 8 | def report(io, states) 9 | report_conflicts(io, states) 10 | end 11 | 12 | private 13 | 14 | # @rbs (IO io, Lrama::States states) -> void 15 | def report_conflicts(io, states) 16 | has_conflict = false 17 | 18 | states.states.each do |state| 19 | messages = format_conflict_messages(state.conflicts) 20 | 21 | unless messages.empty? 22 | has_conflict = true 23 | io << "State #{state.id} conflicts: #{messages.join(', ')}\n" 24 | end 25 | end 26 | 27 | io << "\n\n" if has_conflict 28 | end 29 | 30 | # @rbs (Array[(Lrama::State::ShiftReduceConflict | Lrama::State::ReduceReduceConflict)] conflicts) -> Array[String] 31 | def format_conflict_messages(conflicts) 32 | conflict_types = { 33 | shift_reduce: "shift/reduce", 34 | reduce_reduce: "reduce/reduce" 35 | } 36 | 37 | conflict_types.keys.map do |type| 38 | type_conflicts = conflicts.select { |c| c.type == type } 39 | "#{type_conflicts.count} #{conflict_types[type]}" unless type_conflicts.empty? 40 | end.compact 41 | end 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/lrama/reporter/grammar.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Reporter 6 | class Grammar 7 | # @rbs (?grammar: bool, **bool _) -> void 8 | def initialize(grammar: false, **_) 9 | @grammar = grammar 10 | end 11 | 12 | # @rbs (IO io, Lrama::States states) -> void 13 | def report(io, states) 14 | return unless @grammar 15 | 16 | io << "Grammar\n" 17 | last_lhs = nil 18 | 19 | states.rules.each do |rule| 20 | if rule.empty_rule? 21 | r = "ε" 22 | else 23 | r = rule.rhs.map(&:display_name).join(" ") 24 | end 25 | 26 | if rule.lhs == last_lhs 27 | io << sprintf("%5d %s| %s", rule.id, " " * rule.lhs.display_name.length, r) << "\n" 28 | else 29 | io << "\n" 30 | io << sprintf("%5d %s: %s", rule.id, rule.lhs.display_name, r) << "\n" 31 | end 32 | 33 | last_lhs = rule.lhs 34 | end 35 | io << "\n\n" 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/lrama/reporter/profile.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'profile/call_stack' 4 | require_relative 'profile/memory' 5 | -------------------------------------------------------------------------------- /lib/lrama/reporter/profile/call_stack.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Reporter 6 | module Profile 7 | module CallStack 8 | # See "Call-stack Profiling Lrama" in README.md for how to use. 9 | # 10 | # @rbs enabled: bool 11 | # @rbs &: -> void 12 | # @rbs return: StackProf::result | void 13 | def self.report(enabled) 14 | if enabled && require_stackprof 15 | ex = nil #: Exception? 16 | 17 | StackProf.run(mode: :cpu, raw: true, out: 'tmp/stackprof-cpu-myapp.dump') do 18 | yield 19 | rescue Exception => e 20 | ex = e 21 | end 22 | 23 | if ex 24 | raise ex 25 | end 26 | else 27 | yield 28 | end 29 | end 30 | 31 | # @rbs return: bool 32 | def self.require_stackprof 33 | require "stackprof" 34 | true 35 | rescue LoadError 36 | warn "stackprof is not installed. Please run `bundle install`." 37 | false 38 | end 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/lrama/reporter/profile/memory.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Reporter 6 | module Profile 7 | module Memory 8 | # See "Memory Profiling Lrama" in README.md for how to use. 9 | # 10 | # @rbs enabled: bool 11 | # @rbs &: -> void 12 | # @rbs return: StackProf::result | void 13 | def self.report(enabled) 14 | if enabled && require_memory_profiler 15 | report = MemoryProfiler.report do # steep:ignore UnknownConstant 16 | yield 17 | end 18 | report.pretty_print(to_file: "tmp/memory_profiler.txt") 19 | else 20 | yield 21 | end 22 | end 23 | 24 | # @rbs return: bool 25 | def self.require_memory_profiler 26 | require "memory_profiler" 27 | true 28 | rescue LoadError 29 | warn "memory_profiler is not installed. Please run `bundle install`." 30 | false 31 | end 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/lrama/reporter/rules.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Reporter 6 | class Rules 7 | # @rbs (?rules: bool, **bool _) -> void 8 | def initialize(rules: false, **_) 9 | @rules = rules 10 | end 11 | 12 | # @rbs (IO io, Lrama::States states) -> void 13 | def report(io, states) 14 | return unless @rules 15 | 16 | used_rules = states.rules.flat_map(&:rhs) 17 | 18 | unless used_rules.empty? 19 | io << "Rule Usage Frequency\n\n" 20 | frequency_counts = used_rules.each_with_object(Hash.new(0)) { |rule, counts| counts[rule] += 1 } 21 | 22 | frequency_counts 23 | .select { |rule,| !rule.midrule? } 24 | .sort_by { |rule, count| [-count, rule.name] } 25 | .each_with_index { |(rule, count), i| io << sprintf("%5d %s (%d times)", i, rule.name, count) << "\n" } 26 | io << "\n\n" 27 | end 28 | 29 | unused_rules = states.rules.map(&:lhs).select do |rule| 30 | !used_rules.include?(rule) && rule.token_id != 0 31 | end 32 | 33 | unless unused_rules.empty? 34 | io << "#{unused_rules.count} Unused Rules\n\n" 35 | unused_rules.each_with_index do |rule, index| 36 | io << sprintf("%5d %s", index, rule.display_name) << "\n" 37 | end 38 | io << "\n\n" 39 | end 40 | end 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/lrama/reporter/terms.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Reporter 6 | class Terms 7 | # @rbs (?terms: bool, **bool _) -> void 8 | def initialize(terms: false, **_) 9 | @terms = terms 10 | end 11 | 12 | # @rbs (IO io, Lrama::States states) -> void 13 | def report(io, states) 14 | return unless @terms 15 | 16 | look_aheads = states.states.each do |state| 17 | state.reduces.flat_map do |reduce| 18 | reduce.look_ahead unless reduce.look_ahead.nil? 19 | end 20 | end 21 | 22 | next_terms = states.states.flat_map do |state| 23 | state.term_transitions.map {|shift| shift.next_sym } 24 | end 25 | 26 | unused_symbols = states.terms.reject do |term| 27 | (look_aheads + next_terms).include?(term) 28 | end 29 | 30 | io << states.terms.count << " Terms\n\n" 31 | 32 | io << states.nterms.count << " Non-Terminals\n\n" 33 | 34 | unless unused_symbols.empty? 35 | io << "#{unused_symbols.count} Unused Terms\n\n" 36 | unused_symbols.each_with_index do |term, index| 37 | io << sprintf("%5d %s", index, term.id.s_value) << "\n" 38 | end 39 | io << "\n\n" 40 | end 41 | end 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/lrama/state/action.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "action/goto" 4 | require_relative "action/reduce" 5 | require_relative "action/shift" 6 | -------------------------------------------------------------------------------- /lib/lrama/state/action/goto.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class State 6 | class Action 7 | class Goto 8 | # TODO: rbs-inline 0.10.0 doesn't support instance variables. 9 | # Move these type declarations above instance variable definitions, once it's supported. 10 | # 11 | # @rbs! 12 | # @from_state: State 13 | # @next_sym: Grammar::Symbol 14 | # @to_items: Array[States::Item] 15 | # @to_state: State 16 | 17 | attr_reader :from_state #: State 18 | attr_reader :next_sym #: Grammar::Symbol 19 | attr_reader :to_items #: Array[States::Item] 20 | attr_reader :to_state #: State 21 | 22 | # @rbs (State from_state, Grammar::Symbol next_sym, Array[States::Item] to_items, State to_state) -> void 23 | def initialize(from_state, next_sym, to_items, to_state) 24 | @from_state = from_state 25 | @next_sym = next_sym 26 | @to_items = to_items 27 | @to_state = to_state 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/lrama/state/action/reduce.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class State 6 | class Action 7 | class Reduce 8 | # TODO: rbs-inline 0.10.0 doesn't support instance variables. 9 | # Move these type declarations above instance variable definitions, once it's supported. 10 | # 11 | # @rbs! 12 | # @item: States::Item 13 | # @look_ahead: Array[Grammar::Symbol]? 14 | # @not_selected_symbols: Array[Grammar::Symbol] 15 | 16 | attr_reader :item #: States::Item 17 | attr_reader :look_ahead #: Array[Grammar::Symbol]? 18 | attr_reader :not_selected_symbols #: Array[Grammar::Symbol] 19 | 20 | # https://www.gnu.org/software/bison/manual/html_node/Default-Reductions.html 21 | attr_accessor :default_reduction #: bool 22 | 23 | # @rbs (States::Item item) -> void 24 | def initialize(item) 25 | @item = item 26 | @look_ahead = nil 27 | @not_selected_symbols = [] 28 | end 29 | 30 | # @rbs () -> Grammar::Rule 31 | def rule 32 | @item.rule 33 | end 34 | 35 | # @rbs (Array[Grammar::Symbol] look_ahead) -> Array[Grammar::Symbol] 36 | def look_ahead=(look_ahead) 37 | @look_ahead = look_ahead.freeze 38 | end 39 | 40 | # @rbs (Grammar::Symbol sym) -> Array[Grammar::Symbol] 41 | def add_not_selected_symbol(sym) 42 | @not_selected_symbols << sym 43 | end 44 | 45 | # @rbs () -> (::Array[Grammar::Symbol?]) 46 | def selected_look_ahead 47 | if look_ahead 48 | look_ahead - @not_selected_symbols 49 | else 50 | [] 51 | end 52 | end 53 | 54 | # @rbs () -> void 55 | def clear_conflicts 56 | @not_selected_symbols = [] 57 | @default_reduction = nil 58 | end 59 | end 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /lib/lrama/state/action/shift.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class State 6 | class Action 7 | class Shift 8 | # TODO: rbs-inline 0.10.0 doesn't support instance variables. 9 | # Move these type declarations above instance variable definitions, once it's supported. 10 | # 11 | # @rbs! 12 | # @from_state: State 13 | # @next_sym: Grammar::Symbol 14 | # @to_items: Array[States::Item] 15 | # @to_state: State 16 | 17 | attr_reader :from_state #: State 18 | attr_reader :next_sym #: Grammar::Symbol 19 | attr_reader :to_items #: Array[States::Item] 20 | attr_reader :to_state #: State 21 | attr_accessor :not_selected #: bool 22 | 23 | # @rbs (State from_state, Grammar::Symbol next_sym, Array[States::Item] to_items, State to_state) -> void 24 | def initialize(from_state, next_sym, to_items, to_state) 25 | @from_state = from_state 26 | @next_sym = next_sym 27 | @to_items = to_items 28 | @to_state = to_state 29 | end 30 | 31 | # @rbs () -> void 32 | def clear_conflicts 33 | @not_selected = nil 34 | end 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/lrama/state/reduce_reduce_conflict.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class State 6 | class ReduceReduceConflict < Struct.new(:symbols, :reduce1, :reduce2, keyword_init: true) 7 | # @rbs! 8 | # attr_accessor symbols: Array[Grammar::Symbol] 9 | # attr_accessor reduce1: State::Action::Reduce 10 | # attr_accessor reduce2: State::Action::Reduce 11 | # 12 | # def initialize: (?symbols: Array[Grammar::Symbol], ?reduce1: State::Action::Reduce, ?reduce2: State::Action::Reduce) -> void 13 | 14 | # @rbs () -> :reduce_reduce 15 | def type 16 | :reduce_reduce 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/lrama/state/resolved_conflict.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class State 6 | # * symbol: A symbol under discussion 7 | # * reduce: A reduce under discussion 8 | # * which: For which a conflict is resolved. :shift, :reduce or :error (for nonassociative) 9 | class ResolvedConflict < Struct.new(:symbol, :reduce, :which, :same_prec, keyword_init: true) 10 | # @rbs! 11 | # attr_accessor symbol: Grammar::Symbol 12 | # attr_accessor reduce: State::Action::Reduce 13 | # attr_accessor which: (:reduce | :shift | :error) 14 | # attr_accessor same_prec: bool 15 | # 16 | # def initialize: (?symbol: Grammar::Symbol, ?reduce: State::Action::Reduce, ?which: (:reduce | :shift | :error), ?same_prec: bool) -> void 17 | 18 | # @rbs () -> (::String | bot) 19 | def report_message 20 | s = symbol.display_name 21 | r = reduce.rule.precedence_sym&.display_name 22 | case 23 | when which == :shift && same_prec 24 | msg = "resolved as #{which} (%right #{s})" 25 | when which == :shift 26 | msg = "resolved as #{which} (#{r} < #{s})" 27 | when which == :reduce && same_prec 28 | msg = "resolved as #{which} (%left #{s})" 29 | when which == :reduce 30 | msg = "resolved as #{which} (#{s} < #{r})" 31 | when which == :error 32 | msg = "resolved as an #{which} (%nonassoc #{s})" 33 | else 34 | raise "Unknown direction. #{self}" 35 | end 36 | 37 | "Conflict between rule #{reduce.rule.id} and token #{s} #{msg}." 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/lrama/state/shift_reduce_conflict.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class State 6 | class ShiftReduceConflict < Struct.new(:symbols, :shift, :reduce, keyword_init: true) 7 | # @rbs! 8 | # attr_accessor symbols: Array[Grammar::Symbol] 9 | # attr_accessor shift: State::Action::Shift 10 | # attr_accessor reduce: State::Action::Reduce 11 | # 12 | # def initialize: (?symbols: Array[Grammar::Symbol], ?shift: State::Action::Shift, ?reduce: State::Action::Reduce) -> void 13 | 14 | # @rbs () -> :shift_reduce 15 | def type 16 | :shift_reduce 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/lrama/tracer.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | require_relative "tracer/actions" 5 | require_relative "tracer/closure" 6 | require_relative "tracer/duration" 7 | require_relative "tracer/only_explicit_rules" 8 | require_relative "tracer/rules" 9 | require_relative "tracer/state" 10 | 11 | module Lrama 12 | class Tracer 13 | # @rbs (IO io, **bool options) -> void 14 | def initialize(io, **options) 15 | @io = io 16 | @options = options 17 | @only_explicit_rules = OnlyExplicitRules.new(io, **options) 18 | @rules = Rules.new(io, **options) 19 | @actions = Actions.new(io, **options) 20 | @closure = Closure.new(io, **options) 21 | @state = State.new(io, **options) 22 | end 23 | 24 | # @rbs (Lrama::Grammar grammar) -> void 25 | def trace(grammar) 26 | @only_explicit_rules.trace(grammar) 27 | @rules.trace(grammar) 28 | @actions.trace(grammar) 29 | end 30 | 31 | # @rbs (Lrama::State state) -> void 32 | def trace_closure(state) 33 | @closure.trace(state) 34 | end 35 | 36 | # @rbs (Lrama::State state) -> void 37 | def trace_state(state) 38 | @state.trace(state) 39 | end 40 | 41 | # @rbs (Integer state_count, Lrama::State state) -> void 42 | def trace_state_list_append(state_count, state) 43 | @state.trace_list_append(state_count, state) 44 | end 45 | 46 | # @rbs () -> void 47 | def enable_duration 48 | Duration.enable if @options[:time] 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /lib/lrama/tracer/actions.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Tracer 6 | class Actions 7 | # @rbs (IO io, ?actions: bool, **bool options) -> void 8 | def initialize(io, actions: false, **options) 9 | @io = io 10 | @actions = actions 11 | end 12 | 13 | # @rbs (Lrama::Grammar grammar) -> void 14 | def trace(grammar) 15 | return unless @actions 16 | 17 | @io << "Grammar rules with actions:" << "\n" 18 | grammar.rules.each { |rule| @io << rule.with_actions << "\n" } 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/lrama/tracer/closure.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Tracer 6 | class Closure 7 | # @rbs (IO io, ?automaton: bool, ?closure: bool, **bool) -> void 8 | def initialize(io, automaton: false, closure: false, **_) 9 | @io = io 10 | @closure = automaton || closure 11 | end 12 | 13 | # @rbs (Lrama::State state) -> void 14 | def trace(state) 15 | return unless @closure 16 | 17 | @io << "Closure: input" << "\n" 18 | state.kernels.each do |item| 19 | @io << " #{item.display_rest}" << "\n" 20 | end 21 | @io << "\n\n" 22 | @io << "Closure: output" << "\n" 23 | state.items.each do |item| 24 | @io << " #{item.display_rest}" << "\n" 25 | end 26 | @io << "\n\n" 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/lrama/tracer/duration.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Tracer 6 | module Duration 7 | # TODO: rbs-inline 0.10.0 doesn't support instance variables. 8 | # Move these type declarations above instance variable definitions, once it's supported. 9 | # 10 | # @rbs! 11 | # @_report_duration_enabled: bool 12 | 13 | # @rbs () -> void 14 | def self.enable 15 | @_report_duration_enabled = true 16 | end 17 | 18 | # @rbs () -> bool 19 | def self.enabled? 20 | !!@_report_duration_enabled 21 | end 22 | 23 | # @rbs [T] (_ToS message) { -> T } -> T 24 | def report_duration(message) 25 | time1 = Time.now.to_f 26 | result = yield 27 | time2 = Time.now.to_f 28 | 29 | if Duration.enabled? 30 | STDERR.puts sprintf("%s %10.5f s", message, time2 - time1) 31 | end 32 | 33 | return result 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/lrama/tracer/only_explicit_rules.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Tracer 6 | class OnlyExplicitRules 7 | # @rbs (IO io, ?only_explicit: bool, **bool) -> void 8 | def initialize(io, only_explicit: false, **_) 9 | @io = io 10 | @only_explicit = only_explicit 11 | end 12 | 13 | # @rbs (Lrama::Grammar grammar) -> void 14 | def trace(grammar) 15 | return unless @only_explicit 16 | 17 | @io << "Grammar rules:" << "\n" 18 | grammar.rules.each do |rule| 19 | @io << rule.display_name_without_action << "\n" if rule.lhs.first_set.any? 20 | end 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/lrama/tracer/rules.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Tracer 6 | class Rules 7 | # @rbs (IO io, ?rules: bool, ?only_explicit: bool, **bool) -> void 8 | def initialize(io, rules: false, only_explicit: false, **_) 9 | @io = io 10 | @rules = rules 11 | @only_explicit = only_explicit 12 | end 13 | 14 | # @rbs (Lrama::Grammar grammar) -> void 15 | def trace(grammar) 16 | return if !@rules || @only_explicit 17 | 18 | @io << "Grammar rules:" << "\n" 19 | grammar.rules.each { |rule| @io << rule.display_name << "\n" } 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/lrama/tracer/state.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Tracer 6 | class State 7 | # @rbs (IO io, ?automaton: bool, ?closure: bool, **bool) -> void 8 | def initialize(io, automaton: false, closure: false, **_) 9 | @io = io 10 | @state = automaton || closure 11 | end 12 | 13 | # @rbs (Lrama::State state) -> void 14 | def trace(state) 15 | return unless @state 16 | 17 | # Bison 3.8.2 renders "(reached by "end-of-input")" for State 0 but 18 | # I think it is not correct... 19 | previous = state.kernels.first.previous_sym 20 | @io << "Processing state #{state.id} (reached by #{previous.display_name})" << "\n" 21 | end 22 | 23 | # @rbs (Integer state_count, Lrama::State state) -> void 24 | def trace_list_append(state_count, state) 25 | return unless @state 26 | 27 | previous = state.kernels.first.previous_sym 28 | @io << sprintf("state_list_append (state = %d, symbol = %d (%s))", 29 | state_count, previous.number, previous.display_name) << "\n" 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/lrama/version.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | VERSION = "0.7.0".freeze #: String 6 | end 7 | -------------------------------------------------------------------------------- /lib/lrama/warnings.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | require_relative 'warnings/conflicts' 5 | require_relative 'warnings/redefined_rules' 6 | require_relative 'warnings/required' 7 | 8 | module Lrama 9 | class Warnings 10 | # @rbs (Logger logger, bool warnings) -> void 11 | def initialize(logger, warnings) 12 | @conflicts = Conflicts.new(logger, warnings) 13 | @redefined_rules = RedefinedRules.new(logger, warnings) 14 | @required = Required.new(logger, warnings) 15 | end 16 | 17 | # @rbs (Lrama::Grammar grammar, Lrama::States states) -> void 18 | def warn(grammar, states) 19 | @conflicts.warn(states) 20 | @redefined_rules.warn(grammar) 21 | @required.warn(grammar) 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/lrama/warnings/conflicts.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Warnings 6 | class Conflicts 7 | # @rbs (Lrama::Logger logger, bool warnings) -> void 8 | def initialize(logger, warnings) 9 | @logger = logger 10 | @warnings = warnings 11 | end 12 | 13 | # @rbs (Lrama::States states) -> void 14 | def warn(states) 15 | return unless @warnings 16 | 17 | if states.sr_conflicts_count != 0 18 | @logger.warn("shift/reduce conflicts: #{states.sr_conflicts_count} found") 19 | end 20 | 21 | if states.rr_conflicts_count != 0 22 | @logger.warn("reduce/reduce conflicts: #{states.rr_conflicts_count} found") 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/lrama/warnings/redefined_rules.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Warnings 6 | class RedefinedRules 7 | # @rbs (Lrama::Logger logger, bool warnings) -> void 8 | def initialize(logger, warnings) 9 | @logger = logger 10 | @warnings = warnings 11 | end 12 | 13 | # @rbs (Lrama::Grammar grammar) -> void 14 | def warn(grammar) 15 | return unless @warnings 16 | 17 | grammar.parameterized_resolver.redefined_rules.each do |rule| 18 | @logger.warn("parameterized rule redefined: #{rule}") 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/lrama/warnings/required.rb: -------------------------------------------------------------------------------- 1 | # rbs_inline: enabled 2 | # frozen_string_literal: true 3 | 4 | module Lrama 5 | class Warnings 6 | class Required 7 | # @rbs (Lrama::Logger logger, bool warnings) -> void 8 | def initialize(logger, warnings = false, **_) 9 | @logger = logger 10 | @warnings = warnings 11 | end 12 | 13 | # @rbs (Lrama::Grammar grammar) -> void 14 | def warn(grammar) 15 | return unless @warnings 16 | 17 | if grammar.required 18 | @logger.warn("currently, %require is simply valid as a grammar but does nothing") 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lrama.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/lrama/version.rb" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "lrama" 7 | spec.version = Lrama::VERSION 8 | spec.authors = ["Yuichiro Kaneko"] 9 | spec.email = ["spiketeika@gmail.com"] 10 | 11 | spec.summary = "LALR (1) parser generator written by Ruby" 12 | spec.description = "LALR (1) parser generator written by Ruby" 13 | spec.homepage = "https://github.com/ruby/lrama" 14 | # See LEGAL.md file for detail 15 | spec.license = "GPL-3.0-or-later" 16 | spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0") 17 | 18 | spec.files = Dir.chdir(File.expand_path(__dir__)) do 19 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|sample)/}) } 20 | end 21 | 22 | spec.metadata["homepage_uri"] = spec.homepage 23 | spec.metadata["source_code_uri"] = spec.homepage 24 | spec.metadata["documentation_uri"] = "https://ruby.github.io/lrama/" 25 | spec.metadata["changelog_uri"] = "#{spec.homepage}/releases" 26 | spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues" 27 | 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | end 32 | -------------------------------------------------------------------------------- /rbs_collection.lock.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | path: ".gem_rbs_collection" 3 | gems: 4 | - name: diff-lcs 5 | version: '1.5' 6 | source: 7 | type: git 8 | name: ruby/gem_rbs_collection 9 | revision: 01f77ce44d0ac13c8ebfc3cfdd7104320021f991 10 | remote: https://github.com/ruby/gem_rbs_collection.git 11 | repo_dir: gems 12 | - name: erb 13 | version: '0' 14 | source: 15 | type: stdlib 16 | - name: fileutils 17 | version: '0' 18 | source: 19 | type: stdlib 20 | - name: forwardable 21 | version: '0' 22 | source: 23 | type: stdlib 24 | - name: optparse 25 | version: '0' 26 | source: 27 | type: stdlib 28 | - name: rake 29 | version: '13.0' 30 | source: 31 | type: git 32 | name: ruby/gem_rbs_collection 33 | revision: 01f77ce44d0ac13c8ebfc3cfdd7104320021f991 34 | remote: https://github.com/ruby/gem_rbs_collection.git 35 | repo_dir: gems 36 | - name: rdoc 37 | version: '0' 38 | source: 39 | type: stdlib 40 | - name: stackprof 41 | version: '0.2' 42 | source: 43 | type: git 44 | name: ruby/gem_rbs_collection 45 | revision: 01f77ce44d0ac13c8ebfc3cfdd7104320021f991 46 | remote: https://github.com/ruby/gem_rbs_collection.git 47 | repo_dir: gems 48 | - name: strscan 49 | version: '0' 50 | source: 51 | type: stdlib 52 | - name: timeout 53 | version: '0' 54 | source: 55 | type: stdlib 56 | gemfile_lock_path: Gemfile.lock 57 | -------------------------------------------------------------------------------- /rbs_collection.yaml: -------------------------------------------------------------------------------- 1 | # Download sources 2 | sources: 3 | - type: git 4 | name: ruby/gem_rbs_collection 5 | remote: https://github.com/ruby/gem_rbs_collection.git 6 | revision: main 7 | repo_dir: gems 8 | 9 | # You can specify local directories as sources also. 10 | # - type: local 11 | # path: path/to/your/local/repository 12 | 13 | # A directory to install the downloaded RBSs 14 | path: .gem_rbs_collection 15 | 16 | gems: 17 | - name: erb 18 | - name: strscan 19 | - name: timeout 20 | # Skip loading rbs gem's RBS. 21 | # It's unnecessary if you don't use rbs as a library. 22 | - name: rbs 23 | ignore: true 24 | - name: forwardable 25 | - name: optparse 26 | -------------------------------------------------------------------------------- /sample/parse.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | %} 8 | 9 | %code provides { 10 | 11 | static enum yytokentype yylex(YYSTYPE *lval); 12 | static void yyerror(YYLTYPE *yylloc, const char *msg); 13 | 14 | } 15 | 16 | %expect 0 17 | %define api.pure 18 | %define parse.error verbose 19 | 20 | %union { 21 | int i; 22 | } 23 | 24 | %token number 25 | 26 | %% 27 | 28 | program : expr 29 | ; 30 | 31 | expr : term '+' expr 32 | | term 33 | ; 34 | 35 | term : factor '*' term 36 | | factor 37 | ; 38 | 39 | factor : number 40 | ; 41 | 42 | %% 43 | 44 | // Epilogue 45 | 46 | static enum yytokentype 47 | yylex(YYSTYPE *lval) 48 | { 49 | return (enum yytokentype)0; 50 | } 51 | 52 | static void yyerror(YYLTYPE *yylloc, const char *msg) 53 | { 54 | (void) msg; 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | } 60 | -------------------------------------------------------------------------------- /sig/generated/lrama/bitmap.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/bitmap.rb with RBS::Inline 2 | 3 | module Lrama 4 | module Bitmap 5 | type bitmap = Integer 6 | 7 | # @rbs (Array[Integer] ary) -> bitmap 8 | def self.from_array: (Array[Integer] ary) -> bitmap 9 | 10 | # @rbs (Integer int) -> bitmap 11 | def self.from_integer: (Integer int) -> bitmap 12 | 13 | # @rbs (bitmap int) -> Array[Integer] 14 | def self.to_array: (bitmap int) -> Array[Integer] 15 | 16 | # @rbs (bitmap int, Integer size) -> Array[bool] 17 | def self.to_bool_array: (bitmap int, Integer size) -> Array[bool] 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /sig/generated/lrama/counterexamples/derivation.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/counterexamples/derivation.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Counterexamples 5 | class Derivation 6 | @item: States::Item 7 | 8 | @left: Derivation? 9 | 10 | attr_reader item: States::Item 11 | 12 | attr_reader left: Derivation? 13 | 14 | attr_accessor right: Derivation? 15 | 16 | # @rbs (States::Item item, Derivation? left) -> void 17 | def initialize: (States::Item item, Derivation? left) -> void 18 | 19 | # @rbs () -> ::String 20 | def to_s: () -> ::String 21 | 22 | alias inspect to_s 23 | 24 | # @rbs () -> Array[String] 25 | def render_strings_for_report: () -> Array[String] 26 | 27 | # @rbs () -> String 28 | def render_for_report: () -> String 29 | 30 | private 31 | 32 | # @rbs (Derivation derivation, Integer offset, Array[String] strings, Integer index) -> Integer 33 | def _render_for_report: (Derivation derivation, Integer offset, Array[String] strings, Integer index) -> Integer 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /sig/generated/lrama/counterexamples/example.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/counterexamples/example.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Counterexamples 5 | class Example 6 | @path1: ::Array[StateItem] 7 | 8 | @path2: ::Array[StateItem] 9 | 10 | @conflict: State::conflict 11 | 12 | @conflict_symbol: Grammar::Symbol 13 | 14 | @counterexamples: Counterexamples 15 | 16 | @derivations1: Derivation 17 | 18 | @derivations2: Derivation 19 | 20 | attr_reader path1: ::Array[StateItem] 21 | 22 | attr_reader path2: ::Array[StateItem] 23 | 24 | attr_reader conflict: State::conflict 25 | 26 | attr_reader conflict_symbol: Grammar::Symbol 27 | 28 | # path1 is shift conflict when S/R conflict 29 | # path2 is always reduce conflict 30 | # 31 | # @rbs (Array[StateItem]? path1, Array[StateItem]? path2, State::conflict conflict, Grammar::Symbol conflict_symbol, Counterexamples counterexamples) -> void 32 | def initialize: (Array[StateItem]? path1, Array[StateItem]? path2, State::conflict conflict, Grammar::Symbol conflict_symbol, Counterexamples counterexamples) -> void 33 | 34 | # @rbs () -> (:shift_reduce | :reduce_reduce) 35 | def type: () -> (:shift_reduce | :reduce_reduce) 36 | 37 | # @rbs () -> States::Item 38 | def path1_item: () -> States::Item 39 | 40 | # @rbs () -> States::Item 41 | def path2_item: () -> States::Item 42 | 43 | # @rbs () -> Derivation 44 | def derivations1: () -> Derivation 45 | 46 | # @rbs () -> Derivation 47 | def derivations2: () -> Derivation 48 | 49 | private 50 | 51 | # @rbs (Array[StateItem] state_items) -> Derivation 52 | def _derivations: (Array[StateItem] state_items) -> Derivation 53 | 54 | # @rbs (StateItem state_item, Grammar::Symbol sym) -> Derivation? 55 | def find_derivation_for_symbol: (StateItem state_item, Grammar::Symbol sym) -> Derivation? 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /sig/generated/lrama/counterexamples/node.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/counterexamples/node.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Counterexamples 5 | # @rbs generic E < Object -- Type of an element 6 | class Node[E < Object] 7 | attr_reader elem: E 8 | 9 | attr_reader next_node: Node[E]? 10 | 11 | # @rbs [E < Object] (Node[E] node) -> Array[E] 12 | def self.to_a: [E < Object] (Node[E] node) -> Array[E] 13 | 14 | # @rbs (E elem, Node[E]? next_node) -> void 15 | def initialize: (E elem, Node[E]? next_node) -> void 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/counterexamples/path.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/counterexamples/path.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Counterexamples 5 | class Path 6 | @state_item: StateItem 7 | 8 | @parent: Path? 9 | 10 | attr_reader state_item: StateItem 11 | 12 | attr_reader parent: Path? 13 | 14 | # @rbs (StateItem state_item, Path? parent) -> void 15 | def initialize: (StateItem state_item, Path? parent) -> void 16 | 17 | # @rbs () -> ::String 18 | def to_s: () -> ::String 19 | 20 | alias inspect to_s 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /sig/generated/lrama/counterexamples/state_item.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/counterexamples/state_item.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Counterexamples 5 | class StateItem 6 | attr_reader id: Integer 7 | 8 | attr_reader state: State 9 | 10 | attr_reader item: States::Item 11 | 12 | # @rbs (Integer id, State state, States::Item item) -> void 13 | def initialize: (Integer id, State state, States::Item item) -> void 14 | 15 | # @rbs () -> (:start | :transition | :production) 16 | def type: () -> (:start | :transition | :production) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /sig/generated/lrama/counterexamples/triple.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/counterexamples/triple.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Counterexamples 5 | class Triple 6 | attr_reader precise_lookahead_set: Bitmap::bitmap 7 | 8 | alias l precise_lookahead_set 9 | 10 | # @rbs (StateItem state_item, Bitmap::bitmap precise_lookahead_set) -> void 11 | def initialize: (StateItem state_item, Bitmap::bitmap precise_lookahead_set) -> void 12 | 13 | # @rbs () -> State 14 | def state: () -> State 15 | 16 | alias s state 17 | 18 | # @rbs () -> States::Item 19 | def item: () -> States::Item 20 | 21 | alias itm item 22 | 23 | # @rbs () -> StateItem 24 | def state_item: () -> StateItem 25 | 26 | # @rbs () -> ::String 27 | def inspect: () -> ::String 28 | 29 | alias to_s inspect 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /sig/generated/lrama/diagram.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/diagram.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Diagram 5 | # @rbs (IO out, Grammar grammar, String template_name) -> void 6 | def self.render: (IO out, Grammar grammar, String template_name) -> void 7 | 8 | # @rbs () -> bool 9 | def self.require_railroad_diagrams: () -> bool 10 | 11 | # @rbs (IO out, Grammar grammar, String template_name) -> void 12 | def initialize: (IO out, Grammar grammar, String template_name) -> void 13 | 14 | # @rbs () -> void 15 | def render: () -> void 16 | 17 | # @rbs () -> string 18 | def default_style: () -> string 19 | 20 | # @rbs () -> string 21 | def diagrams: () -> string 22 | 23 | private 24 | 25 | # @rbs () -> string 26 | def template_dir: () -> string 27 | 28 | # @rbs () -> string 29 | def template_file: () -> string 30 | 31 | # @rbs (String name, RailroadDiagrams::Diagram diagram, String result) -> void 32 | def add_diagram: (String name, RailroadDiagrams::Diagram diagram, String result) -> void 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /sig/generated/lrama/digraph.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/digraph.rb with RBS::Inline 2 | 3 | module Lrama 4 | # Digraph Algorithm of https://dl.acm.org/doi/pdf/10.1145/69622.357187 (P. 625) 5 | # 6 | # Digraph is an algorithm for graph data structure. 7 | # The algorithm efficiently traverses SCC (Strongly Connected Component) of graph 8 | # and merges nodes attributes within the same SCC. 9 | # 10 | # `compute_read_sets` and `compute_follow_sets` have the same structure. 11 | # Graph of gotos and attributes of gotos are given then compute propagated attributes for each node. 12 | # 13 | # In the case of `compute_read_sets`: 14 | # 15 | # * Set of gotos is nodes of graph 16 | # * `reads_relation` is edges of graph 17 | # * `direct_read_sets` is nodes attributes 18 | # 19 | # In the case of `compute_follow_sets`: 20 | # 21 | # * Set of gotos is nodes of graph 22 | # * `includes_relation` is edges of graph 23 | # * `read_sets` is nodes attributes 24 | # 25 | # 26 | # @rbs generic X < Object -- Type of a node 27 | # @rbs generic Y < _Or -- Type of attribute sets assigned to a node which should support merge operation (#| method) 28 | class Digraph[X < Object, Y < _Or] 29 | interface _Or 30 | def |: (self) -> self 31 | end 32 | 33 | @sets: Array[X] 34 | 35 | @relation: Hash[X, Array[X]] 36 | 37 | @base_function: Hash[X, Y] 38 | 39 | @stack: Array[X] 40 | 41 | @h: Hash[X, (Integer | Float)?] 42 | 43 | @result: Hash[X, Y] 44 | 45 | # @rbs sets: Array[X] -- Nodes of graph 46 | # @rbs relation: Hash[X, Array[X]] -- Edges of graph 47 | # @rbs base_function: Hash[X, Y] -- Attributes of nodes 48 | # @rbs return: void 49 | def initialize: (Array[X] sets, Hash[X, Array[X]] relation, Hash[X, Y] base_function) -> void 50 | 51 | # @rbs () -> Hash[X, Y] 52 | def compute: () -> Hash[X, Y] 53 | 54 | private 55 | 56 | # @rbs (X x) -> void 57 | def traverse: (X x) -> void 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /sig/generated/lrama/erb.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/erb.rb with RBS::Inline 2 | 3 | module Lrama 4 | class ERB 5 | # @rbs (String file, **untyped kwargs) -> String 6 | def self.render: (String file, **untyped kwargs) -> String 7 | 8 | # @rbs (String file) -> void 9 | def initialize: (String file) -> void 10 | 11 | # @rbs (**untyped kwargs) -> String 12 | def render: (**untyped kwargs) -> String 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/auxiliary.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/auxiliary.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | # Grammar file information not used by States but by Output 6 | class Auxiliary 7 | attr_accessor prologue_first_lineno: Integer 8 | 9 | attr_accessor prologue: String 10 | 11 | attr_accessor epilogue_first_lineno: Integer 12 | 13 | attr_accessor epilogue: String 14 | 15 | def initialize: (?prologue_first_lineno: Integer, ?prologue: String, ?epilogue_first_lineno: Integer, ?epilogue: String) -> void 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/binding.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/binding.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Binding 6 | @actual_args: Array[Lexer::Token] 7 | 8 | @param_to_arg: Hash[String, Lexer::Token] 9 | 10 | # @rbs (Array[Lexer::Token] params, Array[Lexer::Token] actual_args) -> void 11 | def initialize: (Array[Lexer::Token] params, Array[Lexer::Token] actual_args) -> void 12 | 13 | # @rbs (Lexer::Token sym) -> Lexer::Token 14 | def resolve_symbol: (Lexer::Token sym) -> Lexer::Token 15 | 16 | # @rbs (Lexer::Token::InstantiateRule token) -> String 17 | def concatenated_args_str: (Lexer::Token::InstantiateRule token) -> String 18 | 19 | private 20 | 21 | # @rbs (Array[Lexer::Token] params, Array[Lexer::Token] actual_args) -> Hash[String, Lexer::Token] 22 | def map_params_to_args: (Array[Lexer::Token] params, Array[Lexer::Token] actual_args) -> Hash[String, Lexer::Token] 23 | 24 | # @rbs (Lexer::Token::InstantiateRule sym) -> Array[Lexer::Token] 25 | def resolved_args: (Lexer::Token::InstantiateRule sym) -> Array[Lexer::Token] 26 | 27 | # @rbs (Lexer::Token sym) -> Lexer::Token 28 | def param_to_arg: (Lexer::Token sym) -> Lexer::Token 29 | 30 | # @rbs (Lexer::Token::InstantiateRule token) -> Array[String] 31 | def token_to_args_s_values: (Lexer::Token::InstantiateRule token) -> Array[String] 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/code.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/code.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Code 6 | # delegated 7 | def s_value: () -> String 8 | 9 | def line: () -> Integer 10 | 11 | def column: () -> Integer 12 | 13 | def references: () -> Array[Lrama::Grammar::Reference] 14 | 15 | extend Forwardable 16 | 17 | attr_reader type: ::Symbol 18 | 19 | attr_reader token_code: Lexer::Token::UserCode 20 | 21 | # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode) -> void 22 | def initialize: (type: ::Symbol, token_code: Lexer::Token::UserCode) -> void 23 | 24 | # @rbs (Code other) -> bool 25 | def ==: (Code other) -> bool 26 | 27 | # $$, $n, @$, @n are translated to C code 28 | # 29 | # @rbs () -> String 30 | def translated_code: () -> String 31 | 32 | private 33 | 34 | # @rbs (Lrama::Grammar::Reference ref) -> bot 35 | def reference_to_c: (Lrama::Grammar::Reference ref) -> bot 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/code/destructor_code.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/code/destructor_code.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Code 6 | class DestructorCode < Code 7 | @tag: Lexer::Token::Tag 8 | 9 | # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode, tag: Lexer::Token::Tag) -> void 10 | def initialize: (type: ::Symbol, token_code: Lexer::Token::UserCode, tag: Lexer::Token::Tag) -> void 11 | 12 | private 13 | 14 | # * ($$) *yyvaluep 15 | # * (@$) *yylocationp 16 | # * ($:$) error 17 | # * ($1) error 18 | # * (@1) error 19 | # * ($:1) error 20 | # 21 | # @rbs (Reference ref) -> (String | bot) 22 | def reference_to_c: (Reference ref) -> (String | bot) 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/code/initial_action_code.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/code/initial_action_code.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Code 6 | class InitialActionCode < Code 7 | private 8 | 9 | # * ($$) yylval 10 | # * (@$) yylloc 11 | # * ($:$) error 12 | # * ($1) error 13 | # * (@1) error 14 | # * ($:1) error 15 | # 16 | # @rbs (Reference ref) -> (String | bot) 17 | def reference_to_c: (Reference ref) -> (String | bot) 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/code/no_reference_code.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/code/no_reference_code.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Code 6 | class NoReferenceCode < Code 7 | private 8 | 9 | # * ($$) error 10 | # * (@$) error 11 | # * ($:$) error 12 | # * ($1) error 13 | # * (@1) error 14 | # * ($:1) error 15 | # 16 | # @rbs (Reference ref) -> bot 17 | def reference_to_c: (Reference ref) -> bot 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/code/printer_code.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/code/printer_code.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Code 6 | class PrinterCode < Code 7 | @tag: Lexer::Token::Tag 8 | 9 | # @rbs (type: ::Symbol, token_code: Lexer::Token::UserCode, tag: Lexer::Token::Tag) -> void 10 | def initialize: (type: ::Symbol, token_code: Lexer::Token::UserCode, tag: Lexer::Token::Tag) -> void 11 | 12 | private 13 | 14 | # * ($$) *yyvaluep 15 | # * (@$) *yylocationp 16 | # * ($:$) error 17 | # * ($1) error 18 | # * (@1) error 19 | # * ($:1) error 20 | # 21 | # @rbs (Reference ref) -> (String | bot) 22 | def reference_to_c: (Reference ref) -> (String | bot) 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/counter.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/counter.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Counter 6 | @number: Integer 7 | 8 | # @rbs (Integer number) -> void 9 | def initialize: (Integer number) -> void 10 | 11 | # @rbs () -> Integer 12 | def increment: () -> Integer 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/destructor.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/destructor.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Destructor 6 | attr_accessor ident_or_tags: Array[Lexer::Token::Ident | Lexer::Token::Tag] 7 | 8 | attr_accessor token_code: Lexer::Token::UserCode 9 | 10 | attr_accessor lineno: Integer 11 | 12 | def initialize: (?ident_or_tags: Array[Lexer::Token::Ident | Lexer::Token::Tag], ?token_code: Lexer::Token::UserCode, ?lineno: Integer) -> void 13 | 14 | # @rbs (Lexer::Token::Tag tag) -> String 15 | def translated_code: (Lexer::Token::Tag tag) -> String 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/error_token.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/error_token.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class ErrorToken 6 | attr_accessor ident_or_tags: Array[Lexer::Token::Ident | Lexer::Token::Tag] 7 | 8 | attr_accessor token_code: Lexer::Token::UserCode 9 | 10 | attr_accessor lineno: Integer 11 | 12 | def initialize: (?ident_or_tags: Array[Lexer::Token::Ident | Lexer::Token::Tag], ?token_code: Lexer::Token::UserCode, ?lineno: Integer) -> void 13 | 14 | # @rbs (Lexer::Token::Tag tag) -> String 15 | def translated_code: (Lexer::Token::Tag tag) -> String 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/inline/resolver.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/inline/resolver.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Inline 6 | class Resolver 7 | # @rbs (Lrama::Grammar::RuleBuilder rule_builder) -> void 8 | def initialize: (Lrama::Grammar::RuleBuilder rule_builder) -> void 9 | 10 | # @rbs () -> Array[Lrama::Grammar::RuleBuilder] 11 | def resolve: () -> Array[Lrama::Grammar::RuleBuilder] 12 | 13 | private 14 | 15 | # @rbs (Lrama::Grammar::Parameterized::Rhs rhs, Lrama::Lexer::Token token, Integer index, Lrama::Grammar::Parameterized::Rule rule) -> Lrama::Grammar::RuleBuilder 16 | def build_rule: (Lrama::Grammar::Parameterized::Rhs rhs, Lrama::Lexer::Token token, Integer index, Lrama::Grammar::Parameterized::Rule rule) -> Lrama::Grammar::RuleBuilder 17 | 18 | # @rbs (Lrama::Grammar::RuleBuilder builder, Lrama::Grammar::Parameterized::Rhs rhs, Integer index, Lrama::Lexer::Token token, Lrama::Grammar::Parameterized::Rule rule) -> void 19 | def resolve_rhs: (Lrama::Grammar::RuleBuilder builder, Lrama::Grammar::Parameterized::Rhs rhs, Integer index, Lrama::Lexer::Token token, Lrama::Grammar::Parameterized::Rule rule) -> void 20 | 21 | # @rbs (Lrama::Grammar::Parameterized::Rhs rhs, Integer index) -> Lrama::Lexer::Token::UserCode 22 | def replace_user_code: (Lrama::Grammar::Parameterized::Rhs rhs, Integer index) -> Lrama::Lexer::Token::UserCode 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/parameterized/resolver.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/parameterized/resolver.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Parameterized 6 | class Resolver 7 | attr_accessor rules: Array[Rule] 8 | 9 | attr_accessor created_lhs_list: Array[Lexer::Token] 10 | 11 | # @rbs () -> void 12 | def initialize: () -> void 13 | 14 | # @rbs (Rule rule) -> Array[Rule] 15 | def add_rule: (Rule rule) -> Array[Rule] 16 | 17 | # @rbs (Lexer::Token::InstantiateRule token) -> Rule? 18 | def find_rule: (Lexer::Token::InstantiateRule token) -> Rule? 19 | 20 | # @rbs (Lexer::Token token) -> Rule? 21 | def find_inline: (Lexer::Token token) -> Rule? 22 | 23 | # @rbs (String lhs_s_value) -> Lexer::Token? 24 | def created_lhs: (String lhs_s_value) -> Lexer::Token? 25 | 26 | # @rbs () -> Array[Rule] 27 | def redefined_rules: () -> Array[Rule] 28 | 29 | private 30 | 31 | # @rbs (Array[Rule] rules, Lexer::Token::InstantiateRule token) -> Array[Rule] 32 | def select_rules: (Array[Rule] rules, Lexer::Token::InstantiateRule token) -> Array[Rule] 33 | 34 | # @rbs (Array[Rule] rules) -> Array[Rule] 35 | def reject_inline_rules: (Array[Rule] rules) -> Array[Rule] 36 | 37 | # @rbs (Array[Rule] rules, String rule_name) -> Array[Rule] 38 | def select_rules_by_name: (Array[Rule] rules, String rule_name) -> Array[Rule] 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/parameterized/rhs.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/parameterized/rhs.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Parameterized 6 | class Rhs 7 | attr_accessor symbols: Array[Lexer::Token] 8 | 9 | attr_accessor user_code: Lexer::Token::UserCode? 10 | 11 | attr_accessor precedence_sym: Grammar::Symbol? 12 | 13 | # @rbs () -> void 14 | def initialize: () -> void 15 | 16 | # @rbs (Grammar::Binding bindings) -> Lexer::Token::UserCode? 17 | def resolve_user_code: (Grammar::Binding bindings) -> Lexer::Token::UserCode? 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/parameterized/rule.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/parameterized/rule.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Parameterized 6 | class Rule 7 | attr_reader name: String 8 | 9 | attr_reader parameters: Array[Lexer::Token] 10 | 11 | attr_reader rhs: Array[Rhs] 12 | 13 | attr_reader required_parameters_count: Integer 14 | 15 | attr_reader tag: Lexer::Token::Tag? 16 | 17 | # @rbs (String name, Array[Lexer::Token] parameters, Array[Rhs] rhs, tag: Lexer::Token::Tag?, is_inline: bool) -> void 18 | def initialize: (String name, Array[Lexer::Token] parameters, Array[Rhs] rhs, tag: Lexer::Token::Tag?, is_inline: bool) -> void 19 | 20 | # @rbs () -> String 21 | def to_s: () -> String 22 | 23 | # @rbs () -> bool 24 | def inline?: () -> bool 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/percent_code.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/percent_code.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class PercentCode 6 | @name: String 7 | 8 | @code: String 9 | 10 | attr_reader name: String 11 | 12 | attr_reader code: String 13 | 14 | # @rbs (String name, String code) -> void 15 | def initialize: (String name, String code) -> void 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/precedence.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/precedence.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Precedence 6 | include Comparable 7 | 8 | attr_accessor type: ::Symbol 9 | 10 | attr_accessor precedence: Integer 11 | 12 | def initialize: (?type: ::Symbol, ?precedence: Integer) -> void 13 | 14 | # @rbs (Precedence other) -> Integer 15 | def <=>: (Precedence other) -> Integer 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/printer.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/printer.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Printer 6 | attr_accessor ident_or_tags: Array[Lexer::Token::Ident | Lexer::Token::Tag] 7 | 8 | attr_accessor token_code: Lexer::Token::UserCode 9 | 10 | attr_accessor lineno: Integer 11 | 12 | def initialize: (?ident_or_tags: Array[Lexer::Token::Ident | Lexer::Token::Tag], ?token_code: Lexer::Token::UserCode, ?lineno: Integer) -> void 13 | 14 | # @rbs (Lexer::Token::Tag tag) -> String 15 | def translated_code: (Lexer::Token::Tag tag) -> String 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/reference.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/reference.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | # type: :dollar or :at 6 | # name: String (e.g. $$, $foo, $expr.right) 7 | # number: Integer (e.g. $1) 8 | # index: Integer 9 | # ex_tag: "$1" (Optional) 10 | class Reference 11 | attr_accessor type: ::Symbol 12 | 13 | attr_accessor name: String 14 | 15 | attr_accessor number: Integer 16 | 17 | attr_accessor index: Integer 18 | 19 | attr_accessor ex_tag: Lexer::Token? 20 | 21 | attr_accessor first_column: Integer 22 | 23 | attr_accessor last_column: Integer 24 | 25 | def initialize: (type: ::Symbol, first_column: Integer, last_column: Integer, ?name: String, ?number: Integer, ?index: Integer, ?ex_tag: Lexer::Token?) -> void 26 | 27 | # @rbs () -> (String|Integer) 28 | def value: () -> (String | Integer) 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/type.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/type.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Type 6 | @id: Lexer::Token 7 | 8 | @tag: Lexer::Token::Tag 9 | 10 | attr_reader id: Lexer::Token 11 | 12 | attr_reader tag: Lexer::Token::Tag 13 | 14 | # @rbs (id: Lexer::Token, tag: Lexer::Token::Tag) -> void 15 | def initialize: (id: Lexer::Token, tag: Lexer::Token::Tag) -> void 16 | 17 | # @rbs (Grammar::Type other) -> bool 18 | def ==: (Grammar::Type other) -> bool 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /sig/generated/lrama/grammar/union.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/grammar/union.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Grammar 5 | class Union 6 | attr_accessor code: Grammar::Code::NoReferenceCode 7 | 8 | attr_accessor lineno: Integer 9 | 10 | def initialize: (?code: Grammar::Code::NoReferenceCode, ?lineno: Integer) -> void 11 | 12 | # @rbs () -> String 13 | def braces_less_code: () -> String 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /sig/generated/lrama/lexer.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/lexer.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Lexer 5 | type token = lexer_token | c_token 6 | 7 | type lexer_token = [ String, String ] | [ ::Symbol, Token::Tag ] | [ ::Symbol, Token::Char ] | [ ::Symbol, String ] | [ ::Symbol, Integer ] | [ ::Symbol, Token::Ident ] 8 | 9 | type c_token = [ :C_DECLARATION, Token::UserCode ] 10 | 11 | attr_reader head_line: Integer 12 | 13 | attr_reader head_column: Integer 14 | 15 | attr_reader line: Integer 16 | 17 | attr_accessor status: :initial | :c_declaration 18 | 19 | attr_accessor end_symbol: String? 20 | 21 | SYMBOLS: Array[String] 22 | 23 | PERCENT_TOKENS: Array[String] 24 | 25 | # @rbs (GrammarFile grammar_file) -> void 26 | def initialize: (GrammarFile grammar_file) -> void 27 | 28 | # @rbs () -> token? 29 | def next_token: () -> token? 30 | 31 | # @rbs () -> Integer 32 | def column: () -> Integer 33 | 34 | # @rbs () -> Location 35 | def location: () -> Location 36 | 37 | # @rbs () -> lexer_token? 38 | def lex_token: () -> lexer_token? 39 | 40 | # @rbs () -> c_token 41 | def lex_c_code: () -> c_token 42 | 43 | private 44 | 45 | # @rbs () -> void 46 | def lex_comment: () -> void 47 | 48 | # @rbs () -> void 49 | def reset_first_position: () -> void 50 | 51 | # @rbs () -> void 52 | def newline: () -> void 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /sig/generated/lrama/lexer/grammar_file.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/lexer/grammar_file.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Lexer 5 | class GrammarFile 6 | class Text < String 7 | # @rbs () -> String 8 | def inspect: () -> String 9 | end 10 | 11 | attr_reader path: String 12 | 13 | attr_reader text: String 14 | 15 | # @rbs (String path, String text) -> void 16 | def initialize: (String path, String text) -> void 17 | 18 | # @rbs () -> String 19 | def inspect: () -> String 20 | 21 | # @rbs (GrammarFile other) -> bool 22 | def ==: (GrammarFile other) -> bool 23 | 24 | # @rbs () -> Array[String] 25 | def lines: () -> Array[String] 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /sig/generated/lrama/lexer/location.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/lexer/location.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Lexer 5 | class Location 6 | attr_reader grammar_file: GrammarFile 7 | 8 | attr_reader first_line: Integer 9 | 10 | attr_reader first_column: Integer 11 | 12 | attr_reader last_line: Integer 13 | 14 | attr_reader last_column: Integer 15 | 16 | # @rbs (grammar_file: GrammarFile, first_line: Integer, first_column: Integer, last_line: Integer, last_column: Integer) -> void 17 | def initialize: (grammar_file: GrammarFile, first_line: Integer, first_column: Integer, last_line: Integer, last_column: Integer) -> void 18 | 19 | # @rbs (Location other) -> bool 20 | def ==: (Location other) -> bool 21 | 22 | # @rbs (Integer left, Integer right) -> Location 23 | def partial_location: (Integer left, Integer right) -> Location 24 | 25 | # @rbs () -> String 26 | def to_s: () -> String 27 | 28 | # @rbs (String error_message) -> String 29 | def generate_error_message: (String error_message) -> String 30 | 31 | # @rbs () -> String 32 | def line_with_carets: () -> String 33 | 34 | private 35 | 36 | # @rbs () -> String 37 | def path: () -> String 38 | 39 | # @rbs () -> String 40 | def blanks: () -> String 41 | 42 | # @rbs () -> String 43 | def carets: () -> String 44 | 45 | # @rbs () -> String 46 | def text: () -> String 47 | 48 | # @rbs () -> Array[String] 49 | def _text: () -> Array[String] 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /sig/generated/lrama/lexer/token.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/lexer/token.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Lexer 5 | class Token 6 | attr_reader s_value: String 7 | 8 | attr_reader location: Location 9 | 10 | attr_accessor alias_name: String 11 | 12 | attr_accessor referred: bool 13 | 14 | # @rbs (s_value: String, ?alias_name: String, ?location: Location) -> void 15 | def initialize: (s_value: String, ?alias_name: String, ?location: Location) -> void 16 | 17 | # @rbs () -> String 18 | def to_s: () -> String 19 | 20 | # @rbs (String string) -> bool 21 | def referred_by?: (String string) -> bool 22 | 23 | # @rbs (Token other) -> bool 24 | def ==: (Token other) -> bool 25 | 26 | # @rbs () -> Integer 27 | def first_line: () -> Integer 28 | 29 | alias line first_line 30 | 31 | # @rbs () -> Integer 32 | def first_column: () -> Integer 33 | 34 | alias column first_column 35 | 36 | # @rbs () -> Integer 37 | def last_line: () -> Integer 38 | 39 | # @rbs () -> Integer 40 | def last_column: () -> Integer 41 | 42 | # @rbs (Lrama::Grammar::Reference ref, String message) -> bot 43 | def invalid_ref: (Lrama::Grammar::Reference ref, String message) -> bot 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /sig/generated/lrama/lexer/token/char.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/lexer/token/char.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Lexer 5 | class Token 6 | class Char < Token 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /sig/generated/lrama/lexer/token/ident.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/lexer/token/ident.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Lexer 5 | class Token 6 | class Ident < Token 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /sig/generated/lrama/lexer/token/instantiate_rule.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/lexer/token/instantiate_rule.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Lexer 5 | class Token 6 | class InstantiateRule < Token 7 | attr_reader args: Array[Lexer::Token] 8 | 9 | attr_reader lhs_tag: Lexer::Token::Tag? 10 | 11 | # @rbs (s_value: String, ?alias_name: String, ?location: Location, ?args: Array[Lexer::Token], ?lhs_tag: Lexer::Token::Tag?) -> void 12 | def initialize: (s_value: String, ?alias_name: String, ?location: Location, ?args: Array[Lexer::Token], ?lhs_tag: Lexer::Token::Tag?) -> void 13 | 14 | # @rbs () -> String 15 | def rule_name: () -> String 16 | 17 | # @rbs () -> Integer 18 | def args_count: () -> Integer 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /sig/generated/lrama/lexer/token/tag.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/lexer/token/tag.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Lexer 5 | class Token 6 | class Tag < Token 7 | # @rbs () -> String 8 | def member: () -> String 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /sig/generated/lrama/lexer/token/user_code.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/lexer/token/user_code.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Lexer 5 | class Token 6 | class UserCode < Token 7 | attr_accessor tag: Lexer::Token::Tag 8 | 9 | # @rbs () -> Array[Lrama::Grammar::Reference] 10 | def references: () -> Array[Lrama::Grammar::Reference] 11 | 12 | private 13 | 14 | # @rbs () -> Array[Lrama::Grammar::Reference] 15 | def _references: () -> Array[Lrama::Grammar::Reference] 16 | 17 | # @rbs (StringScanner scanner) -> Lrama::Grammar::Reference? 18 | def scan_reference: (StringScanner scanner) -> Lrama::Grammar::Reference? 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /sig/generated/lrama/logger.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/logger.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Logger 5 | # @rbs (IO out) -> void 6 | def initialize: (IO out) -> void 7 | 8 | # @rbs () -> void 9 | def line_break: () -> void 10 | 11 | # @rbs (String message) -> void 12 | def trace: (String message) -> void 13 | 14 | # @rbs (String message) -> void 15 | def warn: (String message) -> void 16 | 17 | # @rbs (String message) -> void 18 | def error: (String message) -> void 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /sig/generated/lrama/option_parser.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/option_parser.rb with RBS::Inline 2 | 3 | module Lrama 4 | # Handle option parsing for the command line interface. 5 | class OptionParser 6 | @options: Lrama::Options 7 | 8 | @trace: Array[String] 9 | 10 | @report: Array[String] 11 | 12 | @profile: Array[String] 13 | 14 | # @rbs (Array[String]) -> Lrama::Options 15 | def self.parse: (Array[String]) -> Lrama::Options 16 | 17 | # @rbs () -> void 18 | def initialize: () -> void 19 | 20 | # @rbs (Array[String]) -> Lrama::Options 21 | def parse: (Array[String]) -> Lrama::Options 22 | 23 | private 24 | 25 | # @rbs (Array[String]) -> void 26 | def parse_by_option_parser: (Array[String]) -> void 27 | 28 | ALIASED_REPORTS: Hash[Symbol, Symbol] 29 | 30 | VALID_REPORTS: Array[Symbol] 31 | 32 | # @rbs (Array[String]) -> Hash[Symbol, bool] 33 | def validate_report: (Array[String]) -> Hash[Symbol, bool] 34 | 35 | # @rbs (String) -> Symbol 36 | def aliased_report_option: (String) -> Symbol 37 | 38 | VALID_TRACES: Array[String] 39 | 40 | NOT_SUPPORTED_TRACES: Array[String] 41 | 42 | SUPPORTED_TRACES: Array[String] 43 | 44 | # @rbs (Array[String]) -> Hash[Symbol, bool] 45 | def validate_trace: (Array[String]) -> Hash[Symbol, bool] 46 | 47 | VALID_PROFILES: Array[String] 48 | 49 | # @rbs (Array[String]) -> Hash[Symbol, bool] 50 | def validate_profile: (Array[String]) -> Hash[Symbol, bool] 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /sig/generated/lrama/options.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/options.rb with RBS::Inline 2 | 3 | module Lrama 4 | # Command line options. 5 | class Options 6 | attr_accessor skeleton: String 7 | 8 | attr_accessor header: bool 9 | 10 | attr_accessor header_file: String? 11 | 12 | attr_accessor report_file: String? 13 | 14 | attr_accessor outfile: String 15 | 16 | attr_accessor error_recovery: bool 17 | 18 | attr_accessor grammar_file: String 19 | 20 | attr_accessor trace_opts: Hash[Symbol, bool]? 21 | 22 | attr_accessor report_opts: Hash[Symbol, bool]? 23 | 24 | attr_accessor warnings: bool 25 | 26 | attr_accessor y: IO 27 | 28 | attr_accessor debug: bool 29 | 30 | attr_accessor define: Hash[String, String] 31 | 32 | attr_accessor diagram: bool 33 | 34 | attr_accessor diagram_file: String 35 | 36 | attr_accessor profile_opts: Hash[Symbol, bool]? 37 | 38 | # @rbs () -> void 39 | def initialize: () -> void 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /sig/generated/lrama/reporter.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/reporter.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Reporter 5 | include Lrama::Tracer::Duration 6 | 7 | # @rbs (**bool options) -> void 8 | def initialize: (**bool options) -> void 9 | 10 | # @rbs (File io, Lrama::States states) -> void 11 | def report: (File io, Lrama::States states) -> void 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/reporter/conflicts.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/reporter/conflicts.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Reporter 5 | class Conflicts 6 | # @rbs (IO io, Lrama::States states) -> void 7 | def report: (IO io, Lrama::States states) -> void 8 | 9 | private 10 | 11 | # @rbs (IO io, Lrama::States states) -> void 12 | def report_conflicts: (IO io, Lrama::States states) -> void 13 | 14 | # @rbs (Array[(Lrama::State::ShiftReduceConflict | Lrama::State::ReduceReduceConflict)] conflicts) -> Array[String] 15 | def format_conflict_messages: (Array[Lrama::State::ShiftReduceConflict | Lrama::State::ReduceReduceConflict] conflicts) -> Array[String] 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/reporter/grammar.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/reporter/grammar.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Reporter 5 | class Grammar 6 | # @rbs (?grammar: bool, **bool _) -> void 7 | def initialize: (?grammar: bool, **bool _) -> void 8 | 9 | # @rbs (IO io, Lrama::States states) -> void 10 | def report: (IO io, Lrama::States states) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/reporter/profile/call_stack.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/reporter/profile/call_stack.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Reporter 5 | module Profile 6 | module CallStack 7 | # See "Call-stack Profiling Lrama" in README.md for how to use. 8 | # 9 | # @rbs enabled: bool 10 | # @rbs &: -> void 11 | # @rbs return: StackProf::result | void 12 | def self.report: (bool enabled) { () -> void } -> (StackProf::result | void) 13 | 14 | # @rbs return: bool 15 | def self.require_stackprof: () -> bool 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /sig/generated/lrama/reporter/profile/memory.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/reporter/profile/memory.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Reporter 5 | module Profile 6 | module Memory 7 | # See "Memory Profiling Lrama" in README.md for how to use. 8 | # 9 | # @rbs enabled: bool 10 | # @rbs &: -> void 11 | # @rbs return: StackProf::result | void 12 | def self.report: (bool enabled) { () -> void } -> (StackProf::result | void) 13 | 14 | # @rbs return: bool 15 | def self.require_memory_profiler: () -> bool 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /sig/generated/lrama/reporter/rules.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/reporter/rules.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Reporter 5 | class Rules 6 | # @rbs (?rules: bool, **bool _) -> void 7 | def initialize: (?rules: bool, **bool _) -> void 8 | 9 | # @rbs (IO io, Lrama::States states) -> void 10 | def report: (IO io, Lrama::States states) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/reporter/terms.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/reporter/terms.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Reporter 5 | class Terms 6 | # @rbs (?terms: bool, **bool _) -> void 7 | def initialize: (?terms: bool, **bool _) -> void 8 | 9 | # @rbs (IO io, Lrama::States states) -> void 10 | def report: (IO io, Lrama::States states) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/state/action/goto.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/state/action/goto.rb with RBS::Inline 2 | 3 | module Lrama 4 | class State 5 | class Action 6 | class Goto 7 | @from_state: State 8 | 9 | @next_sym: Grammar::Symbol 10 | 11 | @to_items: Array[States::Item] 12 | 13 | @to_state: State 14 | 15 | attr_reader from_state: State 16 | 17 | attr_reader next_sym: Grammar::Symbol 18 | 19 | attr_reader to_items: Array[States::Item] 20 | 21 | attr_reader to_state: State 22 | 23 | # @rbs (State from_state, Grammar::Symbol next_sym, Array[States::Item] to_items, State to_state) -> void 24 | def initialize: (State from_state, Grammar::Symbol next_sym, Array[States::Item] to_items, State to_state) -> void 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /sig/generated/lrama/state/action/reduce.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/state/action/reduce.rb with RBS::Inline 2 | 3 | module Lrama 4 | class State 5 | class Action 6 | class Reduce 7 | @item: States::Item 8 | 9 | @look_ahead: Array[Grammar::Symbol]? 10 | 11 | @not_selected_symbols: Array[Grammar::Symbol] 12 | 13 | attr_reader item: States::Item 14 | 15 | attr_reader look_ahead: Array[Grammar::Symbol]? 16 | 17 | attr_reader not_selected_symbols: Array[Grammar::Symbol] 18 | 19 | # https://www.gnu.org/software/bison/manual/html_node/Default-Reductions.html 20 | attr_accessor default_reduction: bool 21 | 22 | # @rbs (States::Item item) -> void 23 | def initialize: (States::Item item) -> void 24 | 25 | # @rbs () -> Grammar::Rule 26 | def rule: () -> Grammar::Rule 27 | 28 | # @rbs (Array[Grammar::Symbol] look_ahead) -> Array[Grammar::Symbol] 29 | def look_ahead=: (Array[Grammar::Symbol] look_ahead) -> Array[Grammar::Symbol] 30 | 31 | # @rbs (Grammar::Symbol sym) -> Array[Grammar::Symbol] 32 | def add_not_selected_symbol: (Grammar::Symbol sym) -> Array[Grammar::Symbol] 33 | 34 | # @rbs () -> (::Array[Grammar::Symbol?]) 35 | def selected_look_ahead: () -> ::Array[Grammar::Symbol?] 36 | 37 | # @rbs () -> void 38 | def clear_conflicts: () -> void 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /sig/generated/lrama/state/action/shift.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/state/action/shift.rb with RBS::Inline 2 | 3 | module Lrama 4 | class State 5 | class Action 6 | class Shift 7 | @from_state: State 8 | 9 | @next_sym: Grammar::Symbol 10 | 11 | @to_items: Array[States::Item] 12 | 13 | @to_state: State 14 | 15 | attr_reader from_state: State 16 | 17 | attr_reader next_sym: Grammar::Symbol 18 | 19 | attr_reader to_items: Array[States::Item] 20 | 21 | attr_reader to_state: State 22 | 23 | attr_accessor not_selected: bool 24 | 25 | # @rbs (State from_state, Grammar::Symbol next_sym, Array[States::Item] to_items, State to_state) -> void 26 | def initialize: (State from_state, Grammar::Symbol next_sym, Array[States::Item] to_items, State to_state) -> void 27 | 28 | # @rbs () -> void 29 | def clear_conflicts: () -> void 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /sig/generated/lrama/state/inadequacy_annotation.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/state/inadequacy_annotation.rb with RBS::Inline 2 | 3 | module Lrama 4 | class State 5 | class InadequacyAnnotation 6 | type action = Action::Shift | Action::Goto | Action::Reduce 7 | 8 | attr_accessor state: State 9 | 10 | attr_accessor token: Grammar::Symbol 11 | 12 | attr_accessor actions: Array[Action::Shift | Action::Reduce] 13 | 14 | attr_accessor contribution_matrix: Hash[Action::Shift | Action::Reduce, Hash[States::Item, bool]] 15 | 16 | # @rbs (State state, Grammar::Symbol token, Array[Action::Shift | Action::Reduce] actions, Hash[Action::Shift | Action::Reduce, Hash[States::Item, bool]] contribution_matrix) -> void 17 | def initialize: (State state, Grammar::Symbol token, Array[Action::Shift | Action::Reduce] actions, Hash[Action::Shift | Action::Reduce, Hash[States::Item, bool]] contribution_matrix) -> void 18 | 19 | # @rbs (States::Item item) -> bool 20 | def contributed?: (States::Item item) -> bool 21 | 22 | # @rbs (Array[Hash[Action::Shift | Action::Reduce, Hash[States::Item, bool]]] another_matrixes) -> void 23 | def merge_matrix: (Array[Hash[Action::Shift | Action::Reduce, Hash[States::Item, bool]]] another_matrixes) -> void 24 | 25 | # Definition 3.42 (dominant_contribution) 26 | # 27 | # @rbs (State::lookahead_set lookaheads) -> Array[Action::Shift | Action::Reduce]? 28 | def dominant_contribution: (State::lookahead_set lookaheads) -> Array[Action::Shift | Action::Reduce]? 29 | 30 | # @rbs (Array[Action::Shift | Action::Reduce] actions) -> Array[Action::Shift | Action::Reduce] 31 | def resolve_conflict: (Array[Action::Shift | Action::Reduce] actions) -> Array[Action::Shift | Action::Reduce] 32 | 33 | # @rbs () -> String 34 | def to_s: () -> String 35 | 36 | private 37 | 38 | # @rbs () -> String 39 | def actions_to_s: () -> String 40 | 41 | # @rbs () -> String 42 | def contribution_matrix_to_s: () -> String 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /sig/generated/lrama/state/reduce_reduce_conflict.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/state/reduce_reduce_conflict.rb with RBS::Inline 2 | 3 | module Lrama 4 | class State 5 | class ReduceReduceConflict 6 | attr_accessor symbols: Array[Grammar::Symbol] 7 | 8 | attr_accessor reduce1: State::Action::Reduce 9 | 10 | attr_accessor reduce2: State::Action::Reduce 11 | 12 | def initialize: (?symbols: Array[Grammar::Symbol], ?reduce1: State::Action::Reduce, ?reduce2: State::Action::Reduce) -> void 13 | 14 | # @rbs () -> :reduce_reduce 15 | def type: () -> :reduce_reduce 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/state/resolved_conflict.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/state/resolved_conflict.rb with RBS::Inline 2 | 3 | module Lrama 4 | class State 5 | # * symbol: A symbol under discussion 6 | # * reduce: A reduce under discussion 7 | # * which: For which a conflict is resolved. :shift, :reduce or :error (for nonassociative) 8 | class ResolvedConflict 9 | attr_accessor symbol: Grammar::Symbol 10 | 11 | attr_accessor reduce: State::Action::Reduce 12 | 13 | attr_accessor which: :reduce | :shift | :error 14 | 15 | attr_accessor same_prec: bool 16 | 17 | def initialize: (?symbol: Grammar::Symbol, ?reduce: State::Action::Reduce, ?which: :reduce | :shift | :error, ?same_prec: bool) -> void 18 | 19 | # @rbs () -> (::String | bot) 20 | def report_message: () -> (::String | bot) 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /sig/generated/lrama/state/shift_reduce_conflict.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/state/shift_reduce_conflict.rb with RBS::Inline 2 | 3 | module Lrama 4 | class State 5 | class ShiftReduceConflict 6 | attr_accessor symbols: Array[Grammar::Symbol] 7 | 8 | attr_accessor shift: State::Action::Shift 9 | 10 | attr_accessor reduce: State::Action::Reduce 11 | 12 | def initialize: (?symbols: Array[Grammar::Symbol], ?shift: State::Action::Shift, ?reduce: State::Action::Reduce) -> void 13 | 14 | # @rbs () -> :shift_reduce 15 | def type: () -> :shift_reduce 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/states/item.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/states/item.rb with RBS::Inline 2 | 3 | module Lrama 4 | class States 5 | class Item 6 | include Grammar::Rule::_DelegatedMethods 7 | 8 | attr_accessor rule: Grammar::Rule 9 | 10 | attr_accessor position: Integer 11 | 12 | def initialize: (?rule: Grammar::Rule, ?position: Integer) -> void 13 | 14 | extend Forwardable 15 | 16 | # Optimization for States#setup_state 17 | # 18 | # @rbs () -> Integer 19 | def hash: () -> Integer 20 | 21 | # @rbs () -> Integer 22 | def rule_id: () -> Integer 23 | 24 | # @rbs () -> bool 25 | def empty_rule?: () -> bool 26 | 27 | # @rbs () -> Integer 28 | def number_of_rest_symbols: () -> Integer 29 | 30 | # @rbs () -> Grammar::Symbol 31 | def next_sym: () -> Grammar::Symbol 32 | 33 | # @rbs () -> Grammar::Symbol 34 | def next_next_sym: () -> Grammar::Symbol 35 | 36 | # @rbs () -> Grammar::Symbol 37 | def previous_sym: () -> Grammar::Symbol 38 | 39 | # @rbs () -> bool 40 | def end_of_rule?: () -> bool 41 | 42 | # @rbs () -> bool 43 | def beginning_of_rule?: () -> bool 44 | 45 | # @rbs () -> bool 46 | def start_item?: () -> bool 47 | 48 | # @rbs () -> States::Item 49 | def new_by_next_position: () -> States::Item 50 | 51 | # @rbs () -> Array[Grammar::Symbol] 52 | def symbols_before_dot: () -> Array[Grammar::Symbol] 53 | 54 | # @rbs () -> Array[Grammar::Symbol] 55 | def symbols_after_dot: () -> Array[Grammar::Symbol] 56 | 57 | # @rbs () -> Array[Grammar::Symbol] 58 | def symbols_after_transition: () -> Array[Grammar::Symbol] 59 | 60 | # @rbs () -> ::String 61 | def to_s: () -> ::String 62 | 63 | # @rbs () -> ::String 64 | def display_name: () -> ::String 65 | 66 | # Right after position 67 | # 68 | # @rbs () -> ::String 69 | def display_rest: () -> ::String 70 | 71 | # @rbs (States::Item other_item) -> bool 72 | def predecessor_item_of?: (States::Item other_item) -> bool 73 | end 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /sig/generated/lrama/tracer.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/tracer.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Tracer 5 | # @rbs (IO io, **bool options) -> void 6 | def initialize: (IO io, **bool options) -> void 7 | 8 | # @rbs (Lrama::Grammar grammar) -> void 9 | def trace: (Lrama::Grammar grammar) -> void 10 | 11 | # @rbs (Lrama::State state) -> void 12 | def trace_closure: (Lrama::State state) -> void 13 | 14 | # @rbs (Lrama::State state) -> void 15 | def trace_state: (Lrama::State state) -> void 16 | 17 | # @rbs (Integer state_count, Lrama::State state) -> void 18 | def trace_state_list_append: (Integer state_count, Lrama::State state) -> void 19 | 20 | # @rbs () -> void 21 | def enable_duration: () -> void 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /sig/generated/lrama/tracer/actions.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/tracer/actions.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Tracer 5 | class Actions 6 | # @rbs (IO io, ?actions: bool, **bool options) -> void 7 | def initialize: (IO io, ?actions: bool, **bool options) -> void 8 | 9 | # @rbs (Lrama::Grammar grammar) -> void 10 | def trace: (Lrama::Grammar grammar) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/tracer/closure.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/tracer/closure.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Tracer 5 | class Closure 6 | # @rbs (IO io, ?automaton: bool, ?closure: bool, **bool) -> void 7 | def initialize: (IO io, ?automaton: bool, ?closure: bool, **bool) -> void 8 | 9 | # @rbs (Lrama::State state) -> void 10 | def trace: (Lrama::State state) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/tracer/duration.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/tracer/duration.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Tracer 5 | module Duration 6 | @_report_duration_enabled: bool 7 | 8 | # @rbs () -> void 9 | def self.enable: () -> void 10 | 11 | # @rbs () -> bool 12 | def self.enabled?: () -> bool 13 | 14 | # @rbs [T] (_ToS message) { -> T } -> T 15 | def report_duration: [T] (_ToS message) { () -> T } -> T 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /sig/generated/lrama/tracer/only_explicit_rules.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/tracer/only_explicit_rules.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Tracer 5 | class OnlyExplicitRules 6 | # @rbs (IO io, ?only_explicit: bool, **bool) -> void 7 | def initialize: (IO io, ?only_explicit: bool, **bool) -> void 8 | 9 | # @rbs (Lrama::Grammar grammar) -> void 10 | def trace: (Lrama::Grammar grammar) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/tracer/rules.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/tracer/rules.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Tracer 5 | class Rules 6 | # @rbs (IO io, ?rules: bool, ?only_explicit: bool, **bool) -> void 7 | def initialize: (IO io, ?rules: bool, ?only_explicit: bool, **bool) -> void 8 | 9 | # @rbs (Lrama::Grammar grammar) -> void 10 | def trace: (Lrama::Grammar grammar) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/tracer/state.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/tracer/state.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Tracer 5 | class State 6 | # @rbs (IO io, ?automaton: bool, ?closure: bool, **bool) -> void 7 | def initialize: (IO io, ?automaton: bool, ?closure: bool, **bool) -> void 8 | 9 | # @rbs (Lrama::State state) -> void 10 | def trace: (Lrama::State state) -> void 11 | 12 | # @rbs (Integer state_count, Lrama::State state) -> void 13 | def trace_list_append: (Integer state_count, Lrama::State state) -> void 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /sig/generated/lrama/version.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/version.rb with RBS::Inline 2 | 3 | module Lrama 4 | VERSION: String 5 | end 6 | -------------------------------------------------------------------------------- /sig/generated/lrama/warnings.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/warnings.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Warnings 5 | # @rbs (Logger logger, bool warnings) -> void 6 | def initialize: (Logger logger, bool warnings) -> void 7 | 8 | # @rbs (Lrama::Grammar grammar, Lrama::States states) -> void 9 | def warn: (Lrama::Grammar grammar, Lrama::States states) -> void 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /sig/generated/lrama/warnings/conflicts.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/warnings/conflicts.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Warnings 5 | class Conflicts 6 | # @rbs (Lrama::Logger logger, bool warnings) -> void 7 | def initialize: (Lrama::Logger logger, bool warnings) -> void 8 | 9 | # @rbs (Lrama::States states) -> void 10 | def warn: (Lrama::States states) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/warnings/redefined_rules.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/warnings/redefined_rules.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Warnings 5 | class RedefinedRules 6 | # @rbs (Lrama::Logger logger, bool warnings) -> void 7 | def initialize: (Lrama::Logger logger, bool warnings) -> void 8 | 9 | # @rbs (Lrama::Grammar grammar) -> void 10 | def warn: (Lrama::Grammar grammar) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/generated/lrama/warnings/required.rbs: -------------------------------------------------------------------------------- 1 | # Generated from lib/lrama/warnings/required.rb with RBS::Inline 2 | 3 | module Lrama 4 | class Warnings 5 | class Required 6 | # @rbs (Lrama::Logger logger, bool warnings) -> void 7 | def initialize: (Lrama::Logger logger, bool warnings) -> void 8 | 9 | # @rbs (Lrama::Grammar grammar) -> void 10 | def warn: (Lrama::Grammar grammar) -> void 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /sig/railroad_diagrams/railroad_diagrams.rbs: -------------------------------------------------------------------------------- 1 | module RailroadDiagrams 2 | class Terminal 3 | def initialize: (*untyped) -> void 4 | end 5 | class NonTerminal 6 | def initialize: (*untyped) -> void 7 | end 8 | class Sequence 9 | def initialize: (*untyped) -> void 10 | end 11 | class Skip 12 | def initialize: (*untyped) -> void 13 | end 14 | class Diagram 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /sig/stdlib/strscan/string_scanner.rbs: -------------------------------------------------------------------------------- 1 | class StringScanner 2 | # TODO: Is it better to define `StringScanner#fetch` whose type '(Integer) -> String' ? 3 | def []: (Integer) -> String 4 | | ... 5 | end 6 | -------------------------------------------------------------------------------- /spec/fixtures/command/basic.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a valid sample grammar file. 3 | * It works as simple calculator. 4 | */ 5 | 6 | %{ 7 | #include 8 | #include 9 | #include 10 | 11 | #include "calc.h" 12 | 13 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 14 | static int yyerror(YYLTYPE *loc, const char *str); 15 | %} 16 | 17 | %union { 18 | int val; 19 | } 20 | %token LF 21 | %token NUM 22 | %type expr 23 | %left '+' '-' 24 | %left '*' '/' 25 | 26 | %% 27 | 28 | list : /* empty */ 29 | | list LF 30 | | list expr LF { printf("=> %d\n", $2); } 31 | ; 32 | expr : NUM 33 | | expr '+' expr { $$ = $1 + $3; } 34 | | expr '-' expr { $$ = $1 - $3; } 35 | | expr '*' expr { $$ = $1 * $3; } 36 | | expr '/' expr { $$ = $1 / $3; } 37 | | '(' expr ')' { $$ = $2; } 38 | ; 39 | 40 | %% 41 | 42 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) { 43 | int c = getchar(); 44 | int val; 45 | 46 | switch (c) { 47 | case ' ': case '\t': 48 | return yylex(yylval, loc); 49 | 50 | case '0': case '1': case '2': case '3': case '4': 51 | case '5': case '6': case '7': case '8': case '9': 52 | val = c - '0'; 53 | while (1) { 54 | c = getchar(); 55 | if (isdigit(c)) { 56 | val = val * 10 + (c - '0'); 57 | } 58 | else { 59 | ungetc(c, stdin); 60 | break; 61 | } 62 | } 63 | yylval->val = val; 64 | return NUM; 65 | 66 | case '\n': 67 | return LF; 68 | 69 | case '+': case '-': case '*': case '/': case '(': case ')': 70 | return c; 71 | 72 | case EOF: 73 | exit(0); 74 | 75 | default: 76 | fprintf(stderr, "unknown character: %c\n", c); 77 | exit(1); 78 | } 79 | } 80 | 81 | static int yyerror(YYLTYPE *loc, const char *str) { 82 | fprintf(stderr, "parse error: %s\n", str); 83 | return 0; 84 | } 85 | 86 | int main() { 87 | printf("Enter the formula:\n"); 88 | yyparse(); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /spec/fixtures/common/basic.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %require "3.0" 6 | 7 | %{ 8 | // Prologue 9 | %} 10 | 11 | %expect 0 12 | %define api.pure 13 | %define parse.error verbose 14 | %define api.prefix {prefix} 15 | 16 | %printer { 17 | print_int(); 18 | } 19 | %printer { 20 | print_token(); 21 | } tNUMBER tSTRING 22 | 23 | %lex-param {struct lex_params *p} 24 | %parse-param {struct parse_params *p} 25 | 26 | %initial-action 27 | { 28 | initial_action_func(@$); 29 | };; // intentional multiple semicolons 30 | 31 | %union { 32 | int i; 33 | long l; 34 | char *str; 35 | } 36 | 37 | %token EOI 0 "EOI" 38 | %token '\\' "backslash" 39 | %token '\13' "escaped vertical tab" 40 | %token keyword_class 41 | %token keyword_class2 42 | %token tNUMBER 43 | %token tSTRING 44 | %token keyword_end "end" 45 | %token tPLUS "+" 46 | %token tMINUS "-" 47 | %token tEQ "=" 48 | %token tEQEQ "==" 49 | 50 | %type class /* comment for class */ // line-comment for class 51 | 52 | %nonassoc tEQEQ 53 | %left tPLUS tMINUS '>' 54 | %right tEQ 55 | 56 | %% 57 | 58 | program: class 59 | | '+' strings_1 60 | | '-' strings_2 61 | ; 62 | 63 | class : keyword_class tSTRING keyword_end %prec tPLUS 64 | { code 1 } 65 | | keyword_class { code 2 } tSTRING '!' keyword_end { code 3 } %prec "=" 66 | | keyword_class { code 4 } tSTRING '?' keyword_end { code 5 } %prec '>' 67 | ;; // intentional multiple semicolons 68 | 69 | strings_1: string_1 70 | ; 71 | 72 | strings_2: string_1 73 | | string_2 74 | ; 75 | 76 | string_1: string 77 | ; 78 | 79 | string_2: string '+' 80 | ; 81 | 82 | string: tSTRING 83 | ; 84 | 85 | unused: tNUMBER 86 | ; 87 | 88 | %% 89 | 90 | // Epilogue 91 | -------------------------------------------------------------------------------- /spec/fixtures/common/nullable.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %require "3.0" 6 | 7 | %{ 8 | // Prologue 9 | %} 10 | 11 | %token tNUMBER 12 | 13 | %% 14 | 15 | program: stmt ; 16 | 17 | stmt: expr opt_semicolon 18 | | opt_expr opt_colon 19 | | %empty 20 | ; 21 | 22 | expr: tNUMBER; 23 | 24 | opt_expr: /* empty */ 25 | | expr 26 | ; 27 | 28 | opt_semicolon: /* empty */ 29 | | ';' 30 | ; 31 | 32 | opt_colon: %empty 33 | | '.' 34 | ; 35 | 36 | %% 37 | 38 | // Epilogue 39 | -------------------------------------------------------------------------------- /spec/fixtures/common/unexpected_token.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | @invalid 6 | -------------------------------------------------------------------------------- /spec/fixtures/context/basic.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %require "3.0" 6 | 7 | %{ 8 | // Prologue 9 | %} 10 | 11 | %expect 0 12 | %define api.pure 13 | %define parse.error verbose 14 | 15 | %printer { 16 | print_int(); 17 | } 18 | %printer { 19 | print_token(); 20 | } tNUMBER tSTRING 21 | %destructor { 22 | printf("destructor for i: %d\n", $$); 23 | printf("line for i: %d\n", __LINE__); 24 | } 25 | %error-token { 26 | $$ = 100; 27 | } tNUMBER 28 | 29 | %lex-param {struct lex_params *p} 30 | %parse-param {struct parse_params *p} 31 | 32 | %initial-action 33 | { 34 | initial_action_func(@$); 35 | }; 36 | 37 | %union { 38 | int i; 39 | long l; 40 | char *str; 41 | } 42 | 43 | %token EOI 0 "EOI" 44 | %token '\\' "backslash" 45 | %token '\13' "escaped vertical tab" 46 | %token keyword_class 47 | %token keyword_class2 48 | %token tNUMBER 49 | %token tSTRING 50 | %token keyword_end "end" 51 | %token tPLUS "+" 52 | %token tMINUS "-" 53 | %token tEQ "=" 54 | %token tEQEQ "==" 55 | 56 | %type class /* comment for class */ 57 | 58 | %nonassoc tEQEQ 59 | %left tPLUS tMINUS '>' 60 | %right tEQ 61 | 62 | %% 63 | 64 | program: class { code $1; } 65 | | '+' strings_1 66 | | '-' strings_2 67 | ; 68 | 69 | class : keyword_class tSTRING keyword_end %prec tPLUS 70 | { code $1; code $2; code $$; } 71 | | keyword_class tSTRING '!' { code @1; code @$; } keyword_end %prec "=" 72 | ; 73 | 74 | strings_1: string_1 75 | ; 76 | 77 | strings_2: string_1 78 | | string_2 79 | ; 80 | 81 | string_1: string 82 | ; 83 | 84 | string_2: string '+' 85 | ; 86 | 87 | string: tSTRING 88 | ; 89 | 90 | %% 91 | 92 | // Epilogue 93 | -------------------------------------------------------------------------------- /spec/fixtures/inlining/basic.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token NUM 16 | %type expression 17 | 18 | %rule %inline op : '+' { + } 19 | | '-' { - } 20 | | '*' { * } 21 | | '/' { / } 22 | ; 23 | 24 | %% 25 | 26 | expression : NUM 27 | | expression op expression { $$ = $1 $2 $3; } 28 | | expression other_op expression { $$ = $1 $2 $3; } 29 | ; 30 | 31 | 32 | %rule %inline other_op : '%' { + 1 + } 33 | | '&' { - 1 - } 34 | ; 35 | 36 | %% 37 | 38 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 39 | { 40 | return 0; 41 | } 42 | 43 | static int yyerror(YYLTYPE *loc, const char *str) 44 | { 45 | return 0; 46 | } 47 | 48 | int main(int argc, char *argv[]) 49 | { 50 | } 51 | -------------------------------------------------------------------------------- /spec/fixtures/inlining/resolve_index.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token NUM 16 | %type expression 17 | 18 | %rule %inline op : '+' { + } 19 | | '+' '=' { += } 20 | ; 21 | 22 | %% 23 | 24 | expression : NUM 25 | | expression op expression { $$ = $1 $2 $3; } 26 | ; 27 | 28 | %% 29 | 30 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 31 | { 32 | return 0; 33 | } 34 | 35 | static int yyerror(YYLTYPE *loc, const char *str) 36 | { 37 | return 0; 38 | } 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /spec/fixtures/inlining/resolve_index_at.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token NUM 16 | %type expression 17 | 18 | %rule %inline op : '+' { + } 19 | | '+' '=' { += } 20 | ; 21 | 22 | %% 23 | 24 | expression : NUM 25 | | expression op expression { $$ = @1 $2 @3; } 26 | ; 27 | 28 | %% 29 | 30 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 31 | { 32 | return 0; 33 | } 34 | 35 | static int yyerror(YYLTYPE *loc, const char *str) 36 | { 37 | return 0; 38 | } 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /spec/fixtures/inlining/resolve_index_reverse.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token NUM 16 | %type expression 17 | 18 | %rule %inline op : '+' { + } 19 | | '+' '=' { += } 20 | ; 21 | 22 | %% 23 | 24 | expression : NUM 25 | | expression op expression { $$ = $3 $2 $1; } 26 | ; 27 | 28 | %% 29 | 30 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 31 | { 32 | return 0; 33 | } 34 | 35 | static int yyerror(YYLTYPE *loc, const char *str) 36 | { 37 | return 0; 38 | } 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /spec/fixtures/inlining/rhs_include_parameterized.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token NUM 16 | %type expression 17 | 18 | %rule %inline op : '+' { + } 19 | | option('-') '-' { - } 20 | ; 21 | 22 | %% 23 | 24 | expression : NUM 25 | | expression op expression { $$ = $1 $2 $3; } 26 | ; 27 | 28 | %% 29 | 30 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 31 | { 32 | return 0; 33 | } 34 | 35 | static int yyerror(YYLTYPE *loc, const char *str) 36 | { 37 | return 0; 38 | } 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /spec/fixtures/inlining/with_parameters.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token NUM 16 | %type expression 17 | 18 | %rule %inline op(p, m) : p { + } 19 | | m { - } 20 | ; 21 | 22 | %% 23 | 24 | expression : NUM 25 | | expression op('+', '-') expression { $$ = $1 $2 $3; } 26 | ; 27 | 28 | %% 29 | 30 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 31 | { 32 | return 0; 33 | } 34 | 35 | static int yyerror(YYLTYPE *loc, const char *str) 36 | { 37 | return 0; 38 | } 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /spec/fixtures/integration/after_shift.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "after_shift.h" 8 | 9 | %} 10 | 11 | NUMBER [0-9]+ 12 | 13 | %% 14 | 15 | {NUMBER} { 16 | ((void) yylloc); 17 | yylval->val = atoi(yytext); 18 | return NUM; 19 | } 20 | 21 | [+\-\*\/\(\)] { 22 | return yytext[0]; 23 | } 24 | 25 | [\n|\r\n] { 26 | return(YYEOF); 27 | } 28 | 29 | [[:space:]] {} 30 | 31 | <> { 32 | return(YYEOF); 33 | } 34 | 35 | . { 36 | fprintf(stderr, "Illegal character '%s'\n", yytext); 37 | return(YYEOF); 38 | } 39 | 40 | %% 41 | -------------------------------------------------------------------------------- /spec/fixtures/integration/calculator.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "calculator.h" 8 | 9 | %} 10 | 11 | NUMBER [0-9]+ 12 | 13 | %% 14 | 15 | {NUMBER} { 16 | ((void) yylloc); 17 | yylval->val = atoi(yytext); 18 | return NUM; 19 | } 20 | 21 | [+\-\*\/\(\)] { 22 | return yytext[0]; 23 | } 24 | 25 | [\n|\r\n] { 26 | return(YYEOF); 27 | } 28 | 29 | [[:space:]] {} 30 | 31 | <> { 32 | return(YYEOF); 33 | } 34 | 35 | . { 36 | fprintf(stderr, "Illegal character '%s'\n", yytext); 37 | return(YYEOF); 38 | } 39 | 40 | %% 41 | -------------------------------------------------------------------------------- /spec/fixtures/integration/calculator.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | #include "calculator.h" 5 | #include "calculator-lexer.h" 6 | 7 | static int yyerror(YYLTYPE *loc, const char *str); 8 | 9 | %} 10 | 11 | %union { 12 | int val; 13 | } 14 | 15 | %token NUM 16 | %type expr 17 | %left '+' '-' 18 | %left '*' '/' 19 | 20 | %locations 21 | 22 | %% 23 | 24 | program : /* empty */ 25 | | expr { printf("=> %d", $1); } 26 | ; 27 | expr : NUM 28 | | expr '+' expr { $$ = $1 + $3; } 29 | | expr '-' expr { $$ = $1 - $3; } 30 | | expr '*' expr { $$ = $1 * $3; } 31 | | expr '/' expr { $$ = $1 / $3; } 32 | | '(' expr ')' { $$ = $2; } 33 | ; 34 | 35 | %% 36 | 37 | static int yyerror(YYLTYPE *loc, const char *str) { 38 | fprintf(stderr, "parse error: %s\n", str); 39 | return 0; 40 | } 41 | 42 | int main(int argc, char *argv[]) { 43 | if (argc == 2) { 44 | yy_scan_string(argv[1]); 45 | } 46 | 47 | if (yyparse()) { 48 | fprintf(stderr, "syntax error\n"); 49 | return 1; 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /spec/fixtures/integration/contains_at_reference.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "prologue_epilogue_optional.h" 8 | 9 | %} 10 | 11 | NUMBER [0-9]+ 12 | 13 | %% 14 | 15 | {NUMBER} { 16 | ((void) yylloc); 17 | yylval->val = atoi(yytext); 18 | return 1; 19 | } 20 | 21 | [+\-\*\/\(\)] { 22 | return yytext[0]; 23 | } 24 | 25 | [\n|\r\n] { 26 | return(YYEOF); 27 | } 28 | 29 | [[:space:]] {} 30 | 31 | <> { 32 | return(YYEOF); 33 | } 34 | 35 | . { 36 | fprintf(stderr, "Illegal character '%s'\n", yytext); 37 | return(YYEOF); 38 | } 39 | 40 | %% 41 | -------------------------------------------------------------------------------- /spec/fixtures/integration/contains_at_reference.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | #include "contains_at_reference.h" 5 | #include "contains_at_reference-lexer.h" 6 | 7 | static int yyerror(YYLTYPE *loc, const char *str); 8 | 9 | %} 10 | 11 | %union { 12 | int val; 13 | } 14 | 15 | %% 16 | 17 | program : /* empty */ { (void)@1; } 18 | ; 19 | 20 | %% 21 | 22 | static int yyerror(YYLTYPE *loc, const char *str) { 23 | fprintf(stderr, "parse error: %s\n", str); 24 | return 0; 25 | } 26 | 27 | int main(int argc, char *argv[]) { 28 | if (argc == 2) { 29 | yy_scan_string(argv[1]); 30 | } 31 | 32 | if (yyparse()) { 33 | fprintf(stderr, "syntax error\n"); 34 | return 1; 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /spec/fixtures/integration/destructors.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "destructors.h" 8 | 9 | int yycolumn = 0; 10 | 11 | #define YY_USER_ACTION \ 12 | yylloc->first_line = yylloc->last_line = yylineno; \ 13 | yylloc->first_column = yycolumn; \ 14 | yylloc->last_column = yycolumn + yyleng; \ 15 | yycolumn += yyleng; \ 16 | 17 | %} 18 | 19 | NUMBER [0-9]+ 20 | 21 | %% 22 | 23 | {NUMBER} { 24 | yylval->val1 = atoi(yytext); 25 | return NUM; 26 | } 27 | 28 | [+\-\*\/\(\)] { 29 | return yytext[0]; 30 | } 31 | 32 | [\n|\r\n] { 33 | return(YYEOF); 34 | } 35 | 36 | [[:space:]] {} 37 | 38 | <> { 39 | return(YYEOF); 40 | } 41 | 42 | . { 43 | fprintf(stderr, "Illegal character '%s'\n", yytext); 44 | return(YYEOF); 45 | } 46 | 47 | %% 48 | -------------------------------------------------------------------------------- /spec/fixtures/integration/destructors.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #define YYDEBUG 1 4 | 5 | #include 6 | #include "destructors.h" 7 | #include "destructors-lexer.h" 8 | 9 | static int yyerror(YYLTYPE *loc, const char *str); 10 | 11 | %} 12 | 13 | %union { 14 | int val1; 15 | int val2; 16 | int val3; 17 | int val4; 18 | } 19 | 20 | %token NUM 21 | %type expr2 22 | %type expr 23 | %left '+' '-' 24 | %left '*' '/' 25 | 26 | %locations 27 | 28 | %destructor { 29 | printf("destructor for val1: %d\n", $$); 30 | printf("line for val1: %d\n", __LINE__); 31 | } // printer for TAG 32 | 33 | %destructor { 34 | printf("destructor for val2: %d\n", $$); 35 | printf("line for val2: %d\n", __LINE__); 36 | } 37 | 38 | %destructor { 39 | printf("destructor for val4: %d\n", $$); 40 | printf("line for val4: %d\n", __LINE__); 41 | } 42 | 43 | %destructor { 44 | printf("destructor for expr: %d\n", $$); 45 | printf("line for expr: %d\n", __LINE__); 46 | } expr // printer for symbol 47 | 48 | %% 49 | 50 | program : /* empty */ 51 | | expr { printf("=> %d\n", $1); } 52 | | expr2 '+' 53 | ; 54 | 55 | expr2: '+' NUM { $$ = $2; } 56 | ; 57 | 58 | expr : NUM 59 | | expr '+' expr { $$ = $1 + $3; } 60 | | expr '-' expr { $$ = $1 - $3; } 61 | | expr '*' { $$ = 10; } expr { $$ = $1 * $4; } 62 | | expr '/' expr { $$ = $1 / $3; } 63 | | '(' expr ')' { $$ = $2; } 64 | ; 65 | 66 | %% 67 | 68 | static int yyerror(YYLTYPE *loc, const char *str) { 69 | fprintf(stderr, "parse error: %s\n", str); 70 | return 0; 71 | } 72 | 73 | int main(int argc, char *argv[]) { 74 | yydebug = 1; 75 | 76 | if (argc == 2) { 77 | yy_scan_string(argv[1]); 78 | } 79 | 80 | if (yyparse()) { 81 | fprintf(stderr, "syntax error\n"); 82 | return 1; 83 | } 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /spec/fixtures/integration/error_recovery.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "error_recovery.h" 8 | 9 | %} 10 | 11 | NUMBER [0-9]+ 12 | 13 | %% 14 | 15 | {NUMBER} { 16 | ((void) yylloc); 17 | yylval->val = atoi(yytext); 18 | return NUM; 19 | } 20 | 21 | [+\-\*\/\(\)] { 22 | return yytext[0]; 23 | } 24 | 25 | [\n|\r\n] { 26 | return(YYEOF); 27 | } 28 | 29 | [[:space:]] {} 30 | 31 | <> { 32 | return(YYEOF); 33 | } 34 | 35 | . { 36 | fprintf(stderr, "Illegal character '%s'\n", yytext); 37 | return(YYEOF); 38 | } 39 | 40 | %% 41 | -------------------------------------------------------------------------------- /spec/fixtures/integration/error_recovery.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | #include "error_recovery.h" 5 | #include "error_recovery-lexer.h" 6 | 7 | static int yyerror(YYLTYPE *loc, const char *str); 8 | 9 | %} 10 | 11 | %union { 12 | int val; 13 | } 14 | 15 | %token NUM 16 | %type expr 17 | %left '+' '-' 18 | %left '*' '/' 19 | 20 | %locations 21 | 22 | %error-token { 23 | $$ = 100; 24 | } NUM 25 | 26 | %% 27 | 28 | program : /* empty */ 29 | | expr { printf("=> %d", $1); } 30 | ; 31 | expr : NUM 32 | | expr '+' expr { $$ = $1 + $3; } 33 | | expr '-' expr { $$ = $1 - $3; } 34 | | expr '*' expr { $$ = $1 * $3; } 35 | | expr '/' expr { $$ = $1 / $3; } 36 | | '(' expr ')' { $$ = $2; } 37 | ; 38 | 39 | %% 40 | 41 | static int yyerror(YYLTYPE *loc, const char *str) { 42 | fprintf(stderr, "parse error: %s\n", str); 43 | return 0; 44 | } 45 | 46 | int main(int argc, char *argv[]) { 47 | if (argc == 2) { 48 | yy_scan_string(argv[1]); 49 | } 50 | 51 | if (yyparse()) { 52 | fprintf(stderr, "syntax error\n"); 53 | return 1; 54 | } 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /spec/fixtures/integration/ielr.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "bison-generated.h" 8 | #include "bison-generated-lexer.h" 9 | 10 | %} 11 | 12 | %% 13 | 14 | 15 | [abc] { 16 | return yytext[0]; 17 | } 18 | 19 | [\n|\r\n] { 20 | return(YYEOF); 21 | } 22 | 23 | [[:space:]] {} 24 | 25 | <> { 26 | return(YYEOF); 27 | } 28 | 29 | . { 30 | fprintf(stderr, "Illegal character '%s'\n", yytext); 31 | return(YYEOF); 32 | } 33 | 34 | %% 35 | -------------------------------------------------------------------------------- /spec/fixtures/integration/ielr.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This grammar comes from "The IELR(1) algorithm for generating minimal LR(1) parser tables for 3 | non-LR(1) grammars with conflict resolution" Fig. 5. (P. 955) 4 | */ 5 | 6 | %{ 7 | #include 8 | #include 9 | #include "y.tab.h" 10 | #define YYDEBUG 1 11 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 12 | static int yyerror(YYLTYPE *loc, const char *str); 13 | %} 14 | 15 | %union { 16 | int val; 17 | } 18 | 19 | %token a 20 | %token b 21 | %token c 22 | %define lr.type ielr 23 | 24 | %precedence tLOWEST 25 | %precedence a 26 | %precedence tHIGHEST 27 | 28 | %% 29 | 30 | S: a A B a 31 | | b A B b 32 | ; 33 | 34 | A: a C D E 35 | ; 36 | 37 | B: c 38 | | // empty 39 | ; 40 | 41 | C: D 42 | ; 43 | 44 | D: a 45 | ; 46 | 47 | E: a 48 | | %prec tHIGHEST // empty 49 | ; 50 | 51 | %% 52 | 53 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) { 54 | int c = getchar(); 55 | printf("%c\n", c); 56 | int val; 57 | 58 | switch (c) { 59 | case ' ': case '\t': 60 | return yylex(yylval, loc); 61 | 62 | case 'a': case 'b': case 'c': 63 | return c; 64 | 65 | case '\n': 66 | exit(0); 67 | 68 | default: 69 | fprintf(stderr, "unknown character: %c\n", c); 70 | exit(1); 71 | } 72 | } 73 | 74 | static int yyerror(YYLTYPE *loc, const char *str) { 75 | fprintf(stderr, "parse error: %s\n", str); 76 | return 0; 77 | } 78 | 79 | int main() { 80 | printf("Enter the formula:\n"); 81 | yyparse(); 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /spec/fixtures/integration/line_number.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "line_number.h" 8 | 9 | int yycolumn = 0; 10 | 11 | #define YY_USER_ACTION \ 12 | yylloc->first_line = yylloc->last_line = yylineno; \ 13 | yylloc->first_column = yycolumn; \ 14 | yylloc->last_column = yycolumn + yyleng; \ 15 | yycolumn += yyleng; \ 16 | 17 | %} 18 | 19 | NUMBER [0-9]+ 20 | 21 | %% 22 | 23 | {NUMBER} { 24 | yylval->i = atoi(yytext); 25 | return NUM; 26 | } 27 | 28 | [+\-\*\/\(\)] { 29 | return yytext[0]; 30 | } 31 | 32 | [\n|\r\n] {} 33 | 34 | [[:space:]] {} 35 | 36 | <> { 37 | return(YYEOF); 38 | } 39 | 40 | . { 41 | fprintf(stderr, "Illegal character '%s'\n", yytext); 42 | return(YYEOF); 43 | } 44 | 45 | %% 46 | -------------------------------------------------------------------------------- /spec/fixtures/integration/line_number.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #define YYDEBUG 1 4 | 5 | #include 6 | #include "line_number.h" 7 | #include "line_number-lexer.h" 8 | 9 | static int yyerror(YYLTYPE *loc, const char *str); 10 | static void line_2(void); 11 | 12 | static void 13 | line_1(void) 14 | { 15 | printf("line_1: %d\n", __LINE__); 16 | } 17 | 18 | %} 19 | 20 | %union { 21 | int i; 22 | } 23 | 24 | %expect 0 25 | 26 | %token NUM 27 | 28 | %locations 29 | 30 | %% 31 | 32 | program : { 33 | printf("line_pre_program: %d\n", __LINE__); 34 | line_1(); 35 | line_2(); 36 | } 37 | expr 38 | { 39 | printf("line_post_program: %d\n", __LINE__); 40 | } 41 | ; 42 | 43 | expr : NUM 44 | ; 45 | 46 | %% 47 | 48 | static int 49 | yyerror(YYLTYPE *loc, const char *str) { 50 | fprintf(stderr, "parse error: %s\\n", str); 51 | return 0; 52 | } 53 | 54 | static void 55 | line_2(void) 56 | { 57 | printf("line_2: %d\n", __LINE__); 58 | } 59 | 60 | int 61 | main(int argc, char *argv[]) { 62 | yydebug = 1; 63 | 64 | if (argc == 2) { 65 | yy_scan_string(argv[1]); 66 | } 67 | 68 | yyparse(); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /spec/fixtures/integration/named_references.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "named_references.h" 8 | 9 | int yycolumn = 0; 10 | 11 | #define YY_USER_ACTION \ 12 | yylloc->first_line = yylloc->last_line = yylineno; \ 13 | yylloc->first_column = yycolumn; \ 14 | yylloc->last_column = yycolumn + yyleng; \ 15 | yycolumn += yyleng; \ 16 | 17 | %} 18 | 19 | NUMBER [0-9]+ 20 | 21 | %% 22 | 23 | {NUMBER} { 24 | yylval->val = atoi(yytext); 25 | return NUM; 26 | } 27 | 28 | [+\-\*\/\(\)] { 29 | return yytext[0]; 30 | } 31 | 32 | [\n|\r\n] { 33 | return(YYEOF); 34 | } 35 | 36 | [[:space:]] {} 37 | 38 | <> { 39 | return(YYEOF); 40 | } 41 | 42 | . { 43 | fprintf(stderr, "Illegal character '%s'\n", yytext); 44 | return(YYEOF); 45 | } 46 | 47 | %% 48 | -------------------------------------------------------------------------------- /spec/fixtures/integration/parameterized.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "parameterized.h" 8 | 9 | int yycolumn = 0; 10 | 11 | #define YY_USER_ACTION \ 12 | yylloc->first_line = yylloc->last_line = yylineno; \ 13 | yylloc->first_column = yycolumn; \ 14 | yylloc->last_column = yycolumn + yyleng; \ 15 | yycolumn += yyleng; \ 16 | 17 | %} 18 | 19 | ODD [13579] 20 | EVEN [02468] 21 | 22 | %% 23 | 24 | {ODD} { 25 | yylval->num = atoi(yytext); 26 | return ODD; 27 | } 28 | 29 | {EVEN} { 30 | yylval->num = atoi(yytext); 31 | return EVEN; 32 | } 33 | 34 | [;|\n|\r\n] { 35 | return yytext[0]; 36 | } 37 | 38 | [[:space:]] {} 39 | 40 | <> { 41 | return(YYEOF); 42 | } 43 | 44 | . { 45 | fprintf(stderr, "Illegal character '%s'\n", yytext); 46 | return(YYEOF); 47 | } 48 | 49 | %% 50 | -------------------------------------------------------------------------------- /spec/fixtures/integration/parameterized.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #define YYDEBUG 1 4 | 5 | #include 6 | 7 | #include "parameterized.h" 8 | #include "parameterized-lexer.h" 9 | 10 | static int yyerror(YYLTYPE *loc, const char *str); 11 | 12 | %} 13 | 14 | %expect 0 15 | 16 | %union { 17 | int num; 18 | char* str; 19 | } 20 | 21 | %token ODD EVEN 22 | 23 | %type stmt 24 | %type opt_nl 25 | 26 | %locations 27 | 28 | %% 29 | 30 | program: stmts 31 | ; 32 | 33 | stmts: stmt+ 34 | ; 35 | 36 | stmt: ODD opt_nl { printf("odd: %d\n", $1); } 37 | | EVEN opt_semicolon { printf("even: %d\n", $1); } 38 | ; 39 | 40 | opt_nl: '\n'?[nl] { $$ = $nl; } 41 | ; 42 | 43 | opt_semicolon: semicolon? 44 | ; 45 | 46 | semicolon: ';' 47 | ; 48 | 49 | %% 50 | 51 | static int yyerror(YYLTYPE *loc, const char *str) { 52 | fprintf(stderr, "parse error: %s\\n", str); 53 | return 0; 54 | } 55 | 56 | int main(int argc, char *argv[]) { 57 | yydebug = 1; 58 | 59 | if (argc == 2) { 60 | yy_scan_string(argv[1]); 61 | } 62 | 63 | if (yyparse()) { 64 | fprintf(stderr, "syntax error\n"); 65 | return 1; 66 | } 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /spec/fixtures/integration/params.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "params.h" 8 | 9 | #define YY_DECL int yylex (YYSTYPE *yylval, YYLTYPE *yylloc, int parser_params) 10 | 11 | int yycolumn = 0; 12 | 13 | #define YY_USER_ACTION \ 14 | yylloc->first_line = yylloc->last_line = yylineno; \ 15 | yylloc->first_column = yycolumn; \ 16 | yylloc->last_column = yycolumn + yyleng; \ 17 | yycolumn += yyleng; \ 18 | 19 | %} 20 | 21 | NUMBER [0-9]+ 22 | 23 | %% 24 | 25 | {NUMBER} { 26 | yylval->val = atoi(yytext); 27 | return NUM; 28 | } 29 | 30 | [+\-\*\/\(\)] { 31 | return yytext[0]; 32 | } 33 | 34 | [\n|\r\n] { 35 | return(YYEOF); 36 | } 37 | 38 | [[:space:]] {} 39 | 40 | <> { 41 | return(YYEOF); 42 | } 43 | 44 | . { 45 | fprintf(stderr, "Illegal character '%s'\n", yytext); 46 | return(YYEOF); 47 | } 48 | 49 | %% 50 | -------------------------------------------------------------------------------- /spec/fixtures/integration/params.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #define YYDEBUG 1 3 | #include 4 | 5 | #define YY_LOCATION_PRINT(File, loc, p) ((void) 0) 6 | 7 | #define YY_DECL yylex (YYSTYPE *lval, YYLTYPE *yylloc, int parser_params) 8 | 9 | #include "params.h" 10 | #include "params-lexer.h" 11 | 12 | extern int yylex(YYSTYPE *lval, YYLTYPE *yylloc, int parser_params); 13 | static int yyerror(YYLTYPE *loc, int parse_param, const char *str); 14 | 15 | %} 16 | 17 | %lex-param {int parse_param} 18 | %parse-param {int parse_param} 19 | 20 | %union { 21 | int val; 22 | } 23 | 24 | %token NUM 25 | %type expr 26 | %left '+' '-' 27 | %left '*' '/' 28 | 29 | %locations 30 | 31 | %% 32 | 33 | program : /* empty */ 34 | | expr { printf("=> %d", $1); } 35 | ; 36 | expr : NUM 37 | | expr '+' expr { $$ = $1 + $3; } 38 | | expr '-' expr { $$ = $1 - $3; } 39 | | expr '*' expr { $$ = $1 * $3; } 40 | | expr '/' expr { $$ = $1 / $3; } 41 | | '(' expr ')' { $$ = $2; } 42 | ; 43 | 44 | %% 45 | 46 | static int yyerror(YYLTYPE *loc, int parse_param, const char *str) { 47 | fprintf(stderr, "parse error: %s\\n", str); 48 | return 0; 49 | } 50 | 51 | int main(int argc, char *argv[]) { 52 | if (argc == 2) { 53 | yy_scan_string(argv[1]); 54 | } 55 | 56 | if (yyparse(0)) { 57 | fprintf(stderr, "syntax error\n"); 58 | return 1; 59 | } 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /spec/fixtures/integration/printers.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "printers.h" 8 | 9 | int yycolumn = 0; 10 | 11 | #define YY_USER_ACTION \ 12 | yylloc->first_line = yylloc->last_line = yylineno; \ 13 | yylloc->first_column = yycolumn; \ 14 | yylloc->last_column = yycolumn + yyleng; \ 15 | yycolumn += yyleng; \ 16 | 17 | %} 18 | 19 | NUMBER [0-9]+ 20 | 21 | %% 22 | 23 | {NUMBER} { 24 | yylval->val1 = atoi(yytext); 25 | return NUM; 26 | } 27 | 28 | [+\-\*\/\(\)] { 29 | return yytext[0]; 30 | } 31 | 32 | [\n|\r\n] { 33 | return(YYEOF); 34 | } 35 | 36 | [[:space:]] {} 37 | 38 | <> { 39 | return(YYEOF); 40 | } 41 | 42 | . { 43 | fprintf(stderr, "Illegal character '%s'\n", yytext); 44 | return(YYEOF); 45 | } 46 | 47 | %% 48 | -------------------------------------------------------------------------------- /spec/fixtures/integration/printers.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #define YYDEBUG 1 4 | 5 | #include 6 | #include "printers.h" 7 | #include "printers-lexer.h" 8 | 9 | static int yyerror(YYLTYPE *loc, const char *str); 10 | 11 | %} 12 | 13 | %union { 14 | int val1; 15 | int val2; 16 | int val3; 17 | } 18 | 19 | %token NUM 20 | %type add 21 | %type expr 22 | %left '+' '-' 23 | %left '*' '/' 24 | 25 | %printer { 26 | printf("val1: %d\n", $$); 27 | } // printer for TAG 28 | 29 | %printer { 30 | printf("val2: %d\n", $$); 31 | } 32 | 33 | %printer { 34 | printf("expr: %d\n", $$); 35 | } expr // printer for symbol 36 | 37 | %locations 38 | 39 | %% 40 | 41 | program : /* empty */ 42 | | expr { printf("=> %d", $1); } 43 | ; 44 | 45 | add : expr '+' expr { $$ = $1 + $3; } 46 | 47 | expr : NUM 48 | | add 49 | | expr '-' expr { $$ = $1 - $3; } 50 | | expr '*' expr { $$ = $1 * $3; } 51 | | expr '/' expr { $$ = $1 / $3; } 52 | | '(' expr ')' { $$ = $2; } 53 | ; 54 | 55 | %% 56 | 57 | static int yyerror(YYLTYPE *loc, const char *str) { 58 | fprintf(stderr, "parse error: %s\n", str); 59 | return 0; 60 | } 61 | 62 | int main(int argc, char *argv[]) { 63 | yydebug = 1; 64 | 65 | if (argc == 2) { 66 | yy_scan_string(argv[1]); 67 | } 68 | 69 | if (yyparse()) { 70 | fprintf(stderr, "syntax error\n"); 71 | return 1; 72 | } 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /spec/fixtures/integration/prologue_epilogue_optional.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "prologue_epilogue_optional.h" 8 | 9 | %} 10 | 11 | NUMBER [0-9]+ 12 | 13 | %% 14 | 15 | {NUMBER} { 16 | ((void) yylloc); 17 | yylval->val = atoi(yytext); 18 | return 1; 19 | } 20 | 21 | [+\-\*\/\(\)] { 22 | return yytext[0]; 23 | } 24 | 25 | [\n|\r\n] { 26 | return(YYEOF); 27 | } 28 | 29 | [[:space:]] {} 30 | 31 | <> { 32 | return(YYEOF); 33 | } 34 | 35 | . { 36 | fprintf(stderr, "Illegal character '%s'\n", yytext); 37 | return(YYEOF); 38 | } 39 | 40 | %% 41 | -------------------------------------------------------------------------------- /spec/fixtures/integration/prologue_epilogue_optional.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | #include "prologue_epilogue_optional.h" 5 | #include "prologue_epilogue_optional-lexer.h" 6 | 7 | static int yyerror(YYLTYPE *loc, const char *str); 8 | 9 | %} 10 | 11 | %union { 12 | int val; 13 | } 14 | 15 | %locations 16 | 17 | %% 18 | 19 | program : /* empty */ 20 | ; 21 | 22 | %% 23 | 24 | static int yyerror(YYLTYPE *loc, const char *str) { 25 | fprintf(stderr, "parse error: %s\n", str); 26 | return 0; 27 | } 28 | 29 | int main(int argc, char *argv[]) { 30 | if (argc == 2) { 31 | yy_scan_string(argv[1]); 32 | } 33 | 34 | if (yyparse()) { 35 | fprintf(stderr, "syntax error\n"); 36 | return 1; 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /spec/fixtures/integration/typed_midrule_actions.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "typed_midrule_actions.h" 8 | 9 | int yycolumn = 0; 10 | 11 | #define YY_USER_ACTION \ 12 | yylloc->first_line = yylloc->last_line = yylineno; \ 13 | yylloc->first_column = yycolumn; \ 14 | yylloc->last_column = yycolumn + yyleng; \ 15 | yycolumn += yyleng; \ 16 | 17 | %} 18 | 19 | NUMBER [0-9]+ 20 | 21 | %% 22 | 23 | {NUMBER} { 24 | yylval->val = atoi(yytext); 25 | return NUM; 26 | } 27 | 28 | [+\-\*\/\(\)] { 29 | return yytext[0]; 30 | } 31 | 32 | [\n|\r\n] { 33 | return(YYEOF); 34 | } 35 | 36 | [[:space:]] {} 37 | 38 | <> { 39 | return(YYEOF); 40 | } 41 | 42 | . { 43 | fprintf(stderr, "Illegal character '%s'\n", yytext); 44 | return(YYEOF); 45 | } 46 | 47 | %% 48 | -------------------------------------------------------------------------------- /spec/fixtures/integration/typed_midrule_actions.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | 4 | #define YYLLOC_DEFAULT(Current, Rhs, N) \ 5 | do \ 6 | if (N) \ 7 | { \ 8 | (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ 9 | (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ 10 | (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ 11 | (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ 12 | } \ 13 | else \ 14 | { \ 15 | (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ 16 | (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \ 17 | (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \ 18 | (Current).last_column = YYRHSLOC(Rhs, 0).last_column; \ 19 | } \ 20 | while (0) 21 | 22 | #include "typed_midrule_actions.h" 23 | #include "typed_midrule_actions-lexer.h" 24 | 25 | static int yyerror(YYLTYPE *loc, const char *str); 26 | 27 | %} 28 | 29 | %union { 30 | int val; 31 | } 32 | %token NUM 33 | %type expr 34 | 35 | %locations 36 | 37 | %% 38 | 39 | line: expr 40 | { 41 | printf("=> %d", $expr); 42 | } 43 | ; 44 | 45 | expr: NUM 46 | | expr expr { $$ = 1; } '+' 47 | { 48 | $$ = $1 + $2 + $3; 49 | } 50 | ; 51 | 52 | %% 53 | 54 | static int yyerror(YYLTYPE *loc, const char *str) { 55 | fprintf(stderr, "parse error: %s\\n", str); 56 | return 0; 57 | } 58 | 59 | int main(int argc, char *argv[]) { 60 | if (argc == 2) { 61 | yy_scan_string(argv[1]); 62 | } 63 | 64 | if (yyparse()) { 65 | fprintf(stderr, "syntax error\n"); 66 | return 1; 67 | } 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /spec/fixtures/integration/user_defined_parameterized.l: -------------------------------------------------------------------------------- 1 | %option noinput nounput noyywrap never-interactive yylineno bison-bridge bison-locations 2 | 3 | %{ 4 | 5 | #include 6 | #include 7 | #include "user_defined_parameterized.h" 8 | 9 | int yycolumn = 0; 10 | 11 | #define YY_USER_ACTION \ 12 | yylloc->first_line = yylloc->last_line = yylineno; \ 13 | yylloc->first_column = yycolumn; \ 14 | yylloc->last_column = yycolumn + yyleng; \ 15 | yycolumn += yyleng; \ 16 | 17 | %} 18 | 19 | ODD [13579] 20 | EVEN [02468] 21 | 22 | %% 23 | 24 | {ODD} { 25 | yylval->num = atoi(yytext); 26 | return ODD; 27 | } 28 | 29 | {EVEN} { 30 | yylval->num = atoi(yytext); 31 | return EVEN; 32 | } 33 | 34 | [;] { 35 | return yytext[0]; 36 | } 37 | 38 | [\n|\r\n] { 39 | return(YYEOF); 40 | } 41 | 42 | [[:space:]] {} 43 | 44 | <> { 45 | return(YYEOF); 46 | } 47 | 48 | . { 49 | fprintf(stderr, "Illegal character '%s'\n", yytext); 50 | return(YYEOF); 51 | } 52 | 53 | %% 54 | -------------------------------------------------------------------------------- /spec/fixtures/integration/user_defined_parameterized.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #define YYDEBUG 1 4 | 5 | #include 6 | 7 | #include "user_defined_parameterized.h" 8 | #include "user_defined_parameterized-lexer.h" 9 | 10 | static int yyerror(YYLTYPE *loc, const char *str); 11 | 12 | %} 13 | 14 | %expect 0 15 | 16 | %union { 17 | int num; 18 | } 19 | 20 | %token ODD EVEN 21 | 22 | %type stmt 23 | 24 | %rule pair(X, Y): X Y 25 | { 26 | $$ = $1 + $2; 27 | printf("(%d, %d)\n", $1, $2); 28 | printf("(%d, %d)\n", $X, $2); 29 | printf("(%d, %d)\n", $:1, $:2); 30 | } 31 | ; 32 | 33 | %locations 34 | 35 | %% 36 | 37 | program: stmts 38 | ; 39 | 40 | stmts: separated_list(';', stmt) 41 | ; 42 | 43 | stmt: pair(ODD, EVEN) { printf("pair odd even: %d\n", $1); } 44 | | pair(EVEN, ODD)[result] { printf("pair even odd: %d\n", $result); } 45 | ; 46 | 47 | %% 48 | 49 | static int yyerror(YYLTYPE *loc, const char *str) { 50 | fprintf(stderr, "parse error: %s\\n", str); 51 | return 0; 52 | } 53 | 54 | int main(int argc, char *argv[]) { 55 | yydebug = 1; 56 | 57 | if (argc == 2) { 58 | yy_scan_string(argv[1]); 59 | } 60 | 61 | if (yyparse()) { 62 | fprintf(stderr, "syntax error\n"); 63 | return 1; 64 | } 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /spec/fixtures/lexer/location.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a valid sample grammar file. 3 | * It works as simple calculator. 4 | */ 5 | 6 | %{ 7 | #include 8 | #include 9 | #include 10 | 11 | #include "calc.h" 12 | 13 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 14 | static int yyerror(YYLTYPE *loc, const char *str); 15 | %} 16 | 17 | %union { 18 | int val; 19 | } 20 | %token LF 21 | %token NUM 22 | %type expr 23 | %left '+' '-' 24 | %left '*' '/' 25 | 26 | %% 27 | 28 | list : /* empty */ 29 | | list LF 30 | | list expr LF { printf("=> %d\n", $2); } 31 | ; 32 | expr : NUM 33 | | expr '+' expr { $$ = $1 + $3; } 34 | | expr '-' expr { $$ = $1 - $3; } 35 | | expr '*' expr { $$ = $1 * $3; } 36 | | expr '/' expr { $$ = $1 / $3; } 37 | | '(' expr ')' 38 | { 39 | printf("debug %d\n", $1); 40 | $$ = $2; 41 | printf("debug %d\n", $3); 42 | } 43 | ; 44 | 45 | %% 46 | 47 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) { 48 | int c = getchar(); 49 | int val; 50 | 51 | switch (c) { 52 | case ' ': case '\t': 53 | return yylex(yylval, loc); 54 | 55 | case '0': case '1': case '2': case '3': case '4': 56 | case '5': case '6': case '7': case '8': case '9': 57 | val = c - '0'; 58 | while (1) { 59 | c = getchar(); 60 | if (isdigit(c)) { 61 | val = val * 10 + (c - '0'); 62 | } 63 | else { 64 | ungetc(c, stdin); 65 | break; 66 | } 67 | } 68 | yylval->val = val; 69 | return NUM; 70 | 71 | case '\n': 72 | return LF; 73 | 74 | case '+': case '-': case '*': case '/': case '(': case ')': 75 | return c; 76 | 77 | case EOF: 78 | exit(0); 79 | 80 | default: 81 | fprintf(stderr, "unknown character: %c\n", c); 82 | exit(1); 83 | } 84 | } 85 | 86 | static int yyerror(YYLTYPE *loc, const char *str) { 87 | fprintf(stderr, "parse error: %s\n", str); 88 | return 0; 89 | } 90 | 91 | int main() { 92 | printf("Enter the formula:\n"); 93 | yyparse(); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/error/invalid_argument_number.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token num1 16 | %token num2 17 | 18 | %% 19 | 20 | program : list(num1, num2) 21 | ; 22 | 23 | %% 24 | 25 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 26 | { 27 | return 0; 28 | } 29 | 30 | static int yyerror(YYLTYPE *loc, const char *str) 31 | { 32 | return 0; 33 | } 34 | 35 | int main(int argc, char *argv[]) 36 | { 37 | } 38 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/error/invalid_rule_name.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token num 16 | 17 | %% 18 | 19 | program : invalid(num) 20 | ; 21 | 22 | %% 23 | 24 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 25 | { 26 | return 0; 27 | } 28 | 29 | static int yyerror(YYLTYPE *loc, const char *str) 30 | { 31 | return 0; 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | } 37 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/delimited.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %% 18 | 19 | program : delimited('(', number, ')') 20 | ; 21 | 22 | %% 23 | 24 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 25 | { 26 | return 0; 27 | } 28 | 29 | static int yyerror(YYLTYPE *loc, const char *str) 30 | { 31 | return 0; 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | } 37 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/ioption.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %% 18 | 19 | program : ioption(number) 20 | ; 21 | 22 | %% 23 | 24 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 25 | { 26 | return 0; 27 | } 28 | 29 | static int yyerror(YYLTYPE *loc, const char *str) 30 | { 31 | return 0; 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | } 37 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/list.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | %token number_alias 17 | 18 | %% 19 | 20 | program : list(number) 21 | ; 22 | 23 | alias : number_alias* 24 | ; 25 | 26 | %% 27 | 28 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 29 | { 30 | return 0; 31 | } 32 | 33 | static int yyerror(YYLTYPE *loc, const char *str) 34 | { 35 | return 0; 36 | } 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/nonempty_list.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | %token number_alias 17 | 18 | %% 19 | 20 | program : nonempty_list(number) 21 | ; 22 | 23 | alias : number_alias+ 24 | ; 25 | 26 | %% 27 | 28 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 29 | { 30 | return 0; 31 | } 32 | 33 | static int yyerror(YYLTYPE *loc, const char *str) 34 | { 35 | return 0; 36 | } 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/option.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | %token number_alias 17 | 18 | %% 19 | 20 | program : option(number) 21 | ; 22 | 23 | alias : number_alias? 24 | ; 25 | 26 | %% 27 | 28 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 29 | { 30 | return 0; 31 | } 32 | 33 | static int yyerror(YYLTYPE *loc, const char *str) 34 | { 35 | return 0; 36 | } 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/option_between_rhs.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token foo 16 | %token bar 17 | %token baz 18 | 19 | %% 20 | 21 | program : foo option(bar) baz 22 | ; 23 | 24 | %% 25 | 26 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 27 | { 28 | return 0; 29 | } 30 | 31 | static int yyerror(YYLTYPE *loc, const char *str) 32 | { 33 | return 0; 34 | } 35 | 36 | int main(int argc, char *argv[]) 37 | { 38 | } 39 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/option_with_tag.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | %token number_alias 17 | 18 | %% 19 | 20 | program : option(number) 21 | ; 22 | 23 | alias : number_alias? 24 | ; 25 | 26 | %% 27 | 28 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 29 | { 30 | return 0; 31 | } 32 | 33 | static int yyerror(YYLTYPE *loc, const char *str) 34 | { 35 | return 0; 36 | } 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/preceded.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %% 18 | 19 | program : preceded('(', number) 20 | ; 21 | 22 | %% 23 | 24 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 25 | { 26 | return 0; 27 | } 28 | 29 | static int yyerror(YYLTYPE *loc, const char *str) 30 | { 31 | return 0; 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | } 37 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/separated_list.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %% 18 | 19 | program : separated_list(',', number) 20 | ; 21 | 22 | %% 23 | 24 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 25 | { 26 | return 0; 27 | } 28 | 29 | static int yyerror(YYLTYPE *loc, const char *str) 30 | { 31 | return 0; 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | } 37 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/separated_nonempty_list.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %% 18 | 19 | program : separated_nonempty_list(',', number) 20 | ; 21 | 22 | %% 23 | 24 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 25 | { 26 | return 0; 27 | } 28 | 29 | static int yyerror(YYLTYPE *loc, const char *str) 30 | { 31 | return 0; 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | } 37 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/stdlib/terminated.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %% 18 | 19 | program : terminated(number, ')') 20 | ; 21 | 22 | %% 23 | 24 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 25 | { 26 | return 0; 27 | } 28 | 29 | static int yyerror(YYLTYPE *loc, const char *str) 30 | { 31 | return 0; 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | } 37 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/basic.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %rule defined_option(X): /* empty */ 18 | | X 19 | ; 20 | 21 | %% 22 | 23 | program : defined_option(number) 24 | | defined_list(number) 25 | ; 26 | 27 | %rule defined_list(X): /* empty */ 28 | | defined_list(X) number 29 | ; 30 | 31 | %% 32 | 33 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 34 | { 35 | return 0; 36 | } 37 | 38 | static int yyerror(YYLTYPE *loc, const char *str) 39 | { 40 | return 0; 41 | } 42 | 43 | int main(int argc, char *argv[]) 44 | { 45 | } 46 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/multi_arguments.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | char *s; 14 | } 15 | 16 | %token number 17 | %token string 18 | 19 | %rule pair(X, Y): X 20 | | Y 21 | ; 22 | 23 | %% 24 | 25 | program : pair(number, string) 26 | | pair(number, number) 27 | ; 28 | 29 | %% 30 | 31 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 32 | { 33 | return 0; 34 | } 35 | 36 | static int yyerror(YYLTYPE *loc, const char *str) 37 | { 38 | return 0; 39 | } 40 | 41 | int main(int argc, char *argv[]) 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/nested_rules.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %rule nested_nested_option(X): /* empty */ 18 | | X 19 | ; 20 | 21 | %rule nested_option(X): /* empty */ 22 | | nested_nested_option(X) 23 | ; 24 | 25 | %rule option(Y): /* empty */ 26 | | nested_option(Y) 27 | ; 28 | 29 | %% 30 | 31 | program : option(number) 32 | ; 33 | 34 | %% 35 | 36 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 37 | { 38 | return 0; 39 | } 40 | 41 | static int yyerror(YYLTYPE *loc, const char *str) 42 | { 43 | return 0; 44 | } 45 | 46 | int main(int argc, char *argv[]) 47 | { 48 | } 49 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/nested_rules_in_rhs.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 7 | static int yyerror(YYLTYPE *loc, const char *str); 8 | %} 9 | 10 | %union { 11 | int i; 12 | } 13 | 14 | %token number 15 | 16 | %rule constant(X) : X 17 | ; 18 | 19 | %rule option(Y) : /* empty */ 20 | | Y 21 | ; 22 | 23 | %% 24 | 25 | program : option(constant(number)) 26 | ; 27 | 28 | %% 29 | 30 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 31 | { 32 | return 0; 33 | } 34 | 35 | static int yyerror(YYLTYPE *loc, const char *str) 36 | { 37 | return 0; 38 | } 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/nested_rules_multi_arguments.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | char* s; 14 | } 15 | 16 | %token number 17 | %token string 18 | 19 | %rule nested_multi_option(X): /* empty */ 20 | | X 21 | ; 22 | 23 | %rule multi_option(X, Y): /* empty */ 24 | | nested_multi_option(X) 25 | | nested_multi_option(Y) X 26 | ; 27 | 28 | %% 29 | 30 | program : multi_option(number, string) 31 | ; 32 | 33 | %% 34 | 35 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 36 | { 37 | return 0; 38 | } 39 | 40 | static int yyerror(YYLTYPE *loc, const char *str) 41 | { 42 | return 0; 43 | } 44 | 45 | int main(int argc, char *argv[]) 46 | { 47 | } 48 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/nested_rules_symbols.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | char* s; 13 | } 14 | 15 | %token string 16 | 17 | %rule with_word_seps(X): /* empty */ 18 | | X ' '+ 19 | ; 20 | 21 | %% 22 | 23 | program : with_word_seps(string) 24 | ; 25 | 26 | %% 27 | 28 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 29 | { 30 | return 0; 31 | } 32 | 33 | static int yyerror(YYLTYPE *loc, const char *str) 34 | { 35 | return 0; 36 | } 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/nested_rules_with_tag.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %rule nested_nested_option(X): /* empty */ 18 | | X 19 | ; 20 | 21 | %rule nested_option(X): /* empty */ 22 | | nested_nested_option(X) 23 | ; 24 | 25 | %rule option(Y): /* empty */ 26 | | nested_option(Y) 27 | ; 28 | 29 | %% 30 | 31 | program : option(number) 32 | ; 33 | 34 | %% 35 | 36 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 37 | { 38 | return 0; 39 | } 40 | 41 | static int yyerror(YYLTYPE *loc, const char *str) 42 | { 43 | return 0; 44 | } 45 | 46 | int main(int argc, char *argv[]) 47 | { 48 | } 49 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/recursive.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %rule list(X): /* empty */ 18 | | X 19 | | list(X) 20 | ; 21 | 22 | %% 23 | 24 | program : list(number) 25 | ; 26 | 27 | %% 28 | 29 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 30 | { 31 | return 0; 32 | } 33 | 34 | static int yyerror(YYLTYPE *loc, const char *str) 35 | { 36 | return 0; 37 | } 38 | 39 | int main(int argc, char *argv[]) 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/with_action.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | char *s; 14 | } 15 | 16 | %token number 17 | %token string 18 | 19 | %rule pair(X, Y): X ',' Y { printf("(%d, %d)\n", $1, $2); } 20 | ; 21 | 22 | %% 23 | 24 | program : pair(number, string) { printf("pair odd even\n"); } 25 | ; 26 | 27 | %% 28 | 29 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 30 | { 31 | return 0; 32 | } 33 | 34 | static int yyerror(YYLTYPE *loc, const char *str) 35 | { 36 | return 0; 37 | } 38 | 39 | int main(int argc, char *argv[]) 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/with_action_and_named_references.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | } 14 | 15 | %token number 16 | 17 | %rule sum(X, Y) : X[summand] '+' Y[addend] { $$ = $summand + $addend; } 18 | ; 19 | 20 | %% 21 | 22 | program : sum(number, number) { printf("sum number\n"); } 23 | ; 24 | 25 | %% 26 | 27 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 28 | { 29 | return 0; 30 | } 31 | 32 | static int yyerror(YYLTYPE *loc, const char *str) 33 | { 34 | return 0; 35 | } 36 | 37 | int main(int argc, char *argv[]) 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /spec/fixtures/parameterized/user_defined/with_tag.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | */ 4 | 5 | %{ 6 | // Prologue 7 | static int yylex(YYSTYPE *val, YYLTYPE *loc); 8 | static int yyerror(YYLTYPE *loc, const char *str); 9 | %} 10 | 11 | %union { 12 | int i; 13 | char *s; 14 | } 15 | 16 | %token number 17 | %token string 18 | 19 | %rule with_tag(X) : X { $$ = $1; } 20 | ; 21 | 22 | %% 23 | 24 | program : with_tag(number) 25 | | with_tag(string) 26 | ; 27 | 28 | %% 29 | 30 | static int yylex(YYSTYPE *yylval, YYLTYPE *loc) 31 | { 32 | return 0; 33 | } 34 | 35 | static int yyerror(YYLTYPE *loc, const char *str) 36 | { 37 | return 0; 38 | } 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /spec/fixtures/states/includes_relation.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | * This grammar comes from https://dl.acm.org/doi/pdf/10.1145/69622.357187 (P. 628) 4 | */ 5 | 6 | %{ 7 | // Prologue 8 | %} 9 | 10 | %token a b c d 11 | 12 | %% 13 | 14 | program: A ; 15 | 16 | A: b B 17 | | a 18 | ; 19 | 20 | B: c C; 21 | 22 | C: d A; 23 | 24 | %% 25 | 26 | // Epilogue 27 | -------------------------------------------------------------------------------- /spec/fixtures/states/reads_relation.y: -------------------------------------------------------------------------------- 1 | /* 2 | * This is comment for this file. 3 | * This grammar comes from https://dl.acm.org/doi/pdf/10.1145/69622.357187 (P. 629) 4 | */ 5 | 6 | %{ 7 | // Prologue 8 | %} 9 | 10 | %token a 11 | 12 | %% 13 | 14 | program: A ; 15 | 16 | A: B C D A 17 | | a 18 | ; 19 | 20 | B: /* empty */ ; 21 | 22 | C: /* empty */ ; 23 | 24 | D: /* empty */ ; 25 | 26 | %% 27 | 28 | // Epilogue 29 | -------------------------------------------------------------------------------- /spec/lrama/bitmap_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe Lrama::Bitmap do 4 | describe ".from_array" do 5 | it "converts array of integer into bitmap integer" do 6 | expect(Lrama::Bitmap.from_array([])).to eq(0b0) 7 | expect(Lrama::Bitmap.from_array([0])).to eq(0b1) 8 | expect(Lrama::Bitmap.from_array([1])).to eq(0b10) 9 | expect(Lrama::Bitmap.from_array([2, 3])).to eq(0b1100) 10 | expect(Lrama::Bitmap.from_array([6, 4])).to eq(0b1010000) 11 | end 12 | end 13 | 14 | describe ".from_integer" do 15 | it "converts integer into bitmap integer" do 16 | expect(Lrama::Bitmap.from_integer(0)).to eq(0b1) 17 | expect(Lrama::Bitmap.from_integer(1)).to eq(0b10) 18 | expect(Lrama::Bitmap.from_integer(2)).to eq(0b100) 19 | expect(Lrama::Bitmap.from_integer(3)).to eq(0b1000) 20 | expect(Lrama::Bitmap.from_integer(4)).to eq(0b10000) 21 | expect(Lrama::Bitmap.from_integer(5)).to eq(0b100000) 22 | expect(Lrama::Bitmap.from_integer(6)).to eq(0b1000000) 23 | end 24 | end 25 | 26 | describe ".to_array" do 27 | it "converts bitmap integer into array of integer" do 28 | expect(Lrama::Bitmap.to_array(0b0)).to eq([]) 29 | expect(Lrama::Bitmap.to_array(0b1)).to eq([0]) 30 | expect(Lrama::Bitmap.to_array(0b10)).to eq([1]) 31 | expect(Lrama::Bitmap.to_array(0b1100)).to eq([2, 3]) 32 | expect(Lrama::Bitmap.to_array(0b1010000)).to eq([4, 6]) 33 | end 34 | end 35 | 36 | describe '.to_bool_array' do 37 | it 'converts bitmap integer into array of boolean' do 38 | expect(Lrama::Bitmap.to_bool_array(0b0, 1)).to eq([false]) 39 | expect(Lrama::Bitmap.to_bool_array(0b1, 1)).to eq([true]) 40 | expect(Lrama::Bitmap.to_bool_array(0b1, 2)).to eq([true, false]) 41 | expect(Lrama::Bitmap.to_bool_array(0b10, 2)).to eq([false, true]) 42 | expect(Lrama::Bitmap.to_bool_array(0b1100, 4)).to eq([false, false, true, true]) 43 | expect(Lrama::Bitmap.to_bool_array(0b1100, 7)).to eq([false, false, true, true, false, false, false]) 44 | expect(Lrama::Bitmap.to_bool_array(0b1010000, 7)).to eq([false, false, false, false, true, false, true]) 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /spec/lrama/counterexamples/node_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe Lrama::Counterexamples::Node do 4 | describe ".to_a" do 5 | it "returns an array whose elements are same with the node" do 6 | node = Lrama::Counterexamples::Node.new(0, nil) 7 | node = Lrama::Counterexamples::Node.new(1, node) 8 | expect(Lrama::Counterexamples::Node.to_a(node)).to eq([1, 0]) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/lrama/lexer/location_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe Lrama::Lexer::Location do 4 | describe "#to_s" do 5 | it "returns location information" do 6 | grammar_file = Lrama::Lexer::GrammarFile.new("test.y", "") 7 | location = Lrama::Lexer::Location.new(grammar_file: grammar_file, first_line: 1, first_column: 0, last_line: 1, last_column: 4) 8 | expect(location.to_s).to eq "test.y (1,0)-(1,4)" 9 | end 10 | end 11 | 12 | describe "#partial_location" do 13 | it "creates new partial location" do 14 | path = fixture_path("lexer/location.y") 15 | grammar_file = Lrama::Lexer::GrammarFile.new(path, File.read(path)) 16 | location = Lrama::Lexer::Location.new(grammar_file: grammar_file, first_line: 38, first_column: 10, last_line: 42, last_column: 9) 17 | 18 | expect(location.partial_location(49, 57)).to eq Lrama::Lexer::Location.new(grammar_file: grammar_file, first_line: 40, first_column: 11, last_line: 40, last_column: 19) 19 | end 20 | end 21 | 22 | describe "#generate_error_message" do 23 | it "returns decorated error message" do 24 | path = fixture_path("lexer/location.y") 25 | grammar_file = Lrama::Lexer::GrammarFile.new(path, File.read(path)) 26 | location = Lrama::Lexer::Location.new(grammar_file: grammar_file, first_line: 33, first_column: 12, last_line: 33, last_column: 15) 27 | expected = <<~TEXT 28 | #{path}:33:12: ERROR 29 | | expr '+' expr { $$ = $1 + $3; } 30 | ^^^ 31 | TEXT 32 | 33 | expect(location.generate_error_message("ERROR")).to eq expected 34 | end 35 | end 36 | 37 | describe "#line_with_carets" do 38 | it "returns line text with carets" do 39 | path = fixture_path("lexer/location.y") 40 | grammar_file = Lrama::Lexer::GrammarFile.new(path, File.read(path)) 41 | location = Lrama::Lexer::Location.new(grammar_file: grammar_file, first_line: 33, first_column: 12, last_line: 33, last_column: 15) 42 | expected = <<-TEXT 43 | | expr '+' expr { $$ = $1 + $3; } 44 | ^^^ 45 | TEXT 46 | 47 | expect(location.line_with_carets).to eq expected 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /spec/lrama/trace/actions_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe Lrama::Tracer::Actions do 4 | describe "#trace" do 5 | let(:path) { "common/basic.y" } 6 | let(:y) { File.read(fixture_path(path)) } 7 | let(:grammar) do 8 | grammar = Lrama::Parser.new(y, path).parse 9 | grammar.prepare 10 | grammar.validate! 11 | grammar 12 | end 13 | 14 | context "when actions: true" do 15 | it "prints the actions" do 16 | expect do 17 | described_class.new(STDERR, actions: true).trace(grammar) 18 | end.to output(<<~RULES).to_stderr_from_any_process 19 | Grammar rules with actions: 20 | $accept -> program EOI {} 21 | program -> class {} 22 | program -> '+' strings_1 {} 23 | program -> '-' strings_2 {} 24 | class -> keyword_class tSTRING keyword_end { code 1 } 25 | $@1 -> ε { code 2 } 26 | $@2 -> ε { code 3 } 27 | class -> keyword_class $@1 tSTRING '!' keyword_end $@2 {} 28 | $@3 -> ε { code 4 } 29 | $@4 -> ε { code 5 } 30 | class -> keyword_class $@3 tSTRING '?' keyword_end $@4 {} 31 | strings_1 -> string_1 {} 32 | strings_2 -> string_1 {} 33 | strings_2 -> string_2 {} 34 | string_1 -> string {} 35 | string_2 -> string '+' {} 36 | string -> tSTRING {} 37 | unused -> tNUMBER {} 38 | RULES 39 | end 40 | end 41 | 42 | context "when actions: false" do 43 | it 'does not print anything' do 44 | expect do 45 | described_class.new(STDERR, actions: false).trace(grammar) 46 | end.to_not output.to_stderr_from_any_process 47 | end 48 | end 49 | 50 | context 'when empty options' do 51 | it 'does not print anything' do 52 | expect do 53 | described_class.new(STDERR).trace(grammar) 54 | end.to_not output.to_stderr_from_any_process 55 | end 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /spec/lrama/warnings/redefined_rules_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe Lrama::Warnings::RedefinedRules do 4 | describe "#warn" do 5 | let(:y) do 6 | <<~STR 7 | %{ 8 | // Prologue 9 | %} 10 | %union { 11 | int i; 12 | } 13 | %token tNUMBER 14 | %rule foo(X) : X 15 | ; 16 | %rule foo(Y) : Y 17 | ; 18 | %% 19 | program: foo(tNUMBER) 20 | ; 21 | STR 22 | end 23 | 24 | context "when warnings true" do 25 | it "has warns for parameterized rule redefined" do 26 | grammar = Lrama::Parser.new(y, "states/parameterized_rule_redefined.y").parse 27 | grammar.prepare 28 | grammar.validate! 29 | states = Lrama::States.new(grammar, Lrama::Tracer.new(Lrama::Logger.new)) 30 | states.compute 31 | logger = Lrama::Logger.new 32 | allow(logger).to receive(:warn) 33 | Lrama::Warnings.new(logger, true).warn(grammar, states) 34 | expect(logger).to have_received(:warn).with("parameterized rule redefined: foo(X)") 35 | expect(logger).to have_received(:warn).with("parameterized rule redefined: foo(Y)") 36 | end 37 | end 38 | 39 | context "when warnings false" do 40 | it "has not warns for parameterized rule redefined" do 41 | grammar = Lrama::Parser.new(y, "states/parameterized_rule_redefined.y").parse 42 | grammar.prepare 43 | grammar.validate! 44 | states = Lrama::States.new(grammar, Lrama::Tracer.new(Lrama::Logger.new)) 45 | states.compute 46 | logger = Lrama::Logger.new 47 | allow(logger).to receive(:warn) 48 | Lrama::Warnings.new(logger, false).warn(grammar, states) 49 | expect(logger).not_to have_received(:warn).with("parameterized rule redefined: foo(X)") 50 | expect(logger).not_to have_received(:warn).with("parameterized rule redefined: foo(Y)") 51 | end 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /spec/lrama/warnings/required_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe Lrama::Warnings::Required do 4 | describe "#warn" do 5 | let(:y) do 6 | <<~STR 7 | %require "3.0" 8 | %{ 9 | // Prologue 10 | %} 11 | %union { 12 | int i; 13 | } 14 | %token tNUMBER 15 | %% 16 | program: tNUMBER 17 | ; 18 | STR 19 | end 20 | 21 | context "when warnings true" do 22 | it "has warns for require is provided for compatibility with bison" do 23 | grammar = Lrama::Parser.new(y, "states/required.y").parse 24 | grammar.prepare 25 | grammar.validate! 26 | states = Lrama::States.new(grammar, Lrama::Tracer.new(Lrama::Logger.new)) 27 | states.compute 28 | logger = Lrama::Logger.new 29 | allow(logger).to receive(:warn) 30 | Lrama::Warnings.new(logger, true).warn(grammar, states) 31 | expect(logger).to have_received(:warn).with("currently, %require is simply valid as a grammar but does nothing") 32 | end 33 | end 34 | 35 | context "when warnings false" do 36 | it "has not warns for require is provided for compatibility with bison" do 37 | grammar = Lrama::Parser.new(y, "states/required.y").parse 38 | grammar.prepare 39 | grammar.validate! 40 | states = Lrama::States.new(grammar, Lrama::Tracer.new(Lrama::Logger.new)) 41 | states.compute 42 | logger = Lrama::Logger.new 43 | allow(logger).to receive(:warn) 44 | Lrama::Warnings.new(logger, false).warn(grammar, states) 45 | expect(logger).not_to have_received(:warn) 46 | end 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /template/bison/_yacc.h: -------------------------------------------------------------------------------- 1 | <%# b4_shared_declarations -%> 2 | <%-# b4_cpp_guard_open([b4_spec_mapped_header_file]) -%> 3 | <%- if output.spec_mapped_header_file -%> 4 | #ifndef <%= output.b4_cpp_guard__b4_spec_mapped_header_file %> 5 | # define <%= output.b4_cpp_guard__b4_spec_mapped_header_file %> 6 | <%- end -%> 7 | <%-# b4_declare_yydebug & b4_YYDEBUG_define -%> 8 | /* Debug traces. */ 9 | #ifndef YYDEBUG 10 | # define YYDEBUG 0 11 | #endif 12 | #if YYDEBUG && !defined(yydebug) 13 | extern int yydebug; 14 | #endif 15 | <%= output.percent_code("requires") %> 16 | 17 | <%-# b4_token_enums_defines -%> 18 | /* Token kinds. */ 19 | #ifndef YYTOKENTYPE 20 | # define YYTOKENTYPE 21 | enum yytokentype 22 | { 23 | <%= output.token_enums -%> 24 | }; 25 | typedef enum yytokentype yytoken_kind_t; 26 | #endif 27 | 28 | <%-# b4_declare_yylstype -%> 29 | <%-# b4_value_type_define -%> 30 | /* Value type. */ 31 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 32 | union YYSTYPE 33 | { 34 | #line <%= output.grammar.union.lineno %> "<%= output.grammar_file_path %>" 35 | <%= output.grammar.union.braces_less_code %> 36 | #line [@oline@] [@ofile@] 37 | 38 | }; 39 | typedef union YYSTYPE YYSTYPE; 40 | # define YYSTYPE_IS_TRIVIAL 1 41 | # define YYSTYPE_IS_DECLARED 1 42 | #endif 43 | 44 | <%-# b4_location_type_define -%> 45 | /* Location type. */ 46 | #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED 47 | typedef struct YYLTYPE YYLTYPE; 48 | struct YYLTYPE 49 | { 50 | int first_line; 51 | int first_column; 52 | int last_line; 53 | int last_column; 54 | }; 55 | # define YYLTYPE_IS_DECLARED 1 56 | # define YYLTYPE_IS_TRIVIAL 1 57 | #endif 58 | 59 | 60 | 61 | 62 | <%-# b4_declare_yyerror_and_yylex. Not supported -%> 63 | <%-# b4_declare_yyparse -%> 64 | int yyparse (<%= output.parse_param %>); 65 | 66 | 67 | <%= output.percent_code("provides") %> 68 | <%-# b4_cpp_guard_close([b4_spec_mapped_header_file]) -%> 69 | <%- if output.spec_mapped_header_file -%> 70 | #endif /* !<%= output.b4_cpp_guard__b4_spec_mapped_header_file %> */ 71 | <%- end -%> 72 | -------------------------------------------------------------------------------- /template/bison/yacc.h: -------------------------------------------------------------------------------- 1 | <%# b4_generated_by -%> 2 | /* A Bison parser, made by Lrama <%= Lrama::VERSION %>. */ 3 | 4 | <%# b4_copyright -%> 5 | /* Bison interface for Yacc-like parsers in C 6 | 7 | Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, 8 | Inc. 9 | 10 | This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | You should have received a copy of the GNU General Public License 21 | along with this program. If not, see . */ 22 | 23 | /* As a special exception, you may create a larger work that contains 24 | part or all of the Bison parser skeleton and distribute that work 25 | under terms of your choice, so long as that work isn't itself a 26 | parser generator using the skeleton or a modified version thereof 27 | as a parser skeleton. Alternatively, if you modify or redistribute 28 | the parser skeleton itself, you may (at your option) remove this 29 | special exception, which will cause the skeleton and the resulting 30 | Bison output files to be licensed under the GNU General Public 31 | License without this special exception. 32 | 33 | This special exception was added by the Free Software Foundation in 34 | version 2.2 of Bison. */ 35 | 36 | <%# b4_disclaimer -%> 37 | /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, 38 | especially those whose name start with YY_ or yy_. They are 39 | private implementation details that can be changed or removed. */ 40 | <%= output.render_partial("bison/_yacc.h") %> 41 | --------------------------------------------------------------------------------