Skip to content

Instantly share code, notes, and snippets.

@aoitaku
Last active August 29, 2015 14:27
Show Gist options
  • Save aoitaku/8ed49cb4b95bfb096519 to your computer and use it in GitHub Desktop.
Save aoitaku/8ed49cb4b95bfb096519 to your computer and use it in GitHub Desktop.
TsukasaParser
# TsukasaParser
#
# Usage:
# gem install parslet するか、
# bundler で Gemfile に gem 'parslet' を書いて
# bundle install して bundle exec で利用してください
require 'parslet'
class TsukasaParser < Parslet::Parser
attr_accessor :script_prefix, :comment_str
attr_accessor :inline_command_open, :inline_command_close
attr_reader :indent_mode, :indent_width
def initialize(
indent_mode: :spaces, indent_width: 2,
script_prefix: "@", comment_str: "//",
inline_command_open: "[", inline_command_close: "]"
)
super()
@indent_mode = indent_mode
@indent_width = indent_width
@script_prefix = script_prefix
@comment_str = comment_str
@inline_command_open = inline_command_open
@inline_command_close = inline_command_close
end
def indent_mode=(indent_mode)
@indent_mode = indent_mode
@indent_char = nil
end
def indent_width=(indent_width)
@indent_width = indent_width
@indent_char = nil
end
def indent_char
@indent_char ||= case @indent_mode
when :tab
"\t"
when :spaces
" " * @indent_width
end
end
rule(:indent) { str(indent_char) }
rule(:newline) { str("\n") }
rule(:command) {
(str(script_prefix) | indent) >>
match['^\n'].repeat(1).as(:command) >>
newline.maybe
}
rule(:printable) {
(
(inline_command | text).repeat(1).as(:printable) >>
newline.maybe.as(:linefeed) >>
blankline.repeat.as(:blanklines)
)
}
rule(:text) { match['^\[\n'].repeat(1).as(:text) }
rule(:inline_command) {
str(inline_command_open) >>
(str('\\') >> any | str(inline_command_close).absent? >> any).repeat.as(:inline_command) >>
str(inline_command_close)
}
rule(:comment) {
str(comment_str) >> match[' \t'].repeat >> match['^\n'].repeat.as(:comment)
}
rule(:blankline) { (match[' \t'].repeat >> newline) }
rule(:node) { blankline.maybe >> (comment | command | printable) }
rule(:document) { (blankline | node).repeat }
root :document
class Replacer < Parslet::Transform
rule(:comment => simple(:comment)) { [] }
rule(:text => simple(:string)) { %Q'text "#{string}"' }
rule(:command => simple(:command)) { [command.to_s] }
rule(:inline_command => simple(:command)) { command.to_s }
rule(
:printable => sequence(:commands),
:linefeed => nil,
:blanklines => []
) { commands }
rule(
:printable => sequence(:commands),
:linefeed => simple(:linefeed),
:blanklines => []
) { commands + ["linefeed"] }
rule(
:printable => sequence(:commands),
:linefeed => simple(:linefeed),
:blanklines => simple(:blanklines)
) { commands + ["linefeed", "pause"] }
end
end
require_relative "tsukasa/parser.rb"
parser = TsukasaParser.new
replacer = TsukasaParser::Replacer.new
output = parser.parse <<-EOF
@test 3
@ test 5,5
テスト文字列
テスト文字列[pause]テスト文字列[pause]
テスト文字列
EOF
puts replacer.apply(output).flatten.join("\n").encode("Windows-31J")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment