Last active
November 22, 2020 08:49
-
-
Save ysakasin/e2b6f3f6d93ee8b0c9dc1a071adf4cda to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# シンタックスハイライトのために .rb にしていますが、このままでは動きません。raccを通す必要があります。 | |
class AddDice | |
token NUMBER D K H L U R PLUS MINUS ASTERISK SLASH PARENL PARENR LESS GREATER EQUAL NOT | |
rule | |
expr: add | |
| add cmp_op add | |
{ result = val } | |
cmp_op: LESS EQUAL | |
{ result = :<= } | |
| LESS | |
{ result = :< } | |
| GREATER | |
{ result = :> } | |
| GREATER EQUAL | |
{ result = :>= } | |
| NOT EQUAL | |
{ result = :!= } | |
| LESS GREATER | |
{ result = :!= } | |
| EQUAL | |
{ result = :== } | |
| EQUAL EQUAL | |
{ result = :== } | |
add: add PLUS mul | |
{ result = val } | |
| add MINUS mul | |
{ result = val } | |
| mul | |
mul: mul ASTERISK unary | |
{ result = val } | |
| mul SLASH unary | |
{ result = val } | |
| mul SLASH unary U | |
{ result = val } | |
| mul SLASH unary R | |
{ result = val } | |
| unary | |
unary: PLUS unary | |
{ result = val } | |
| MINUS unary | |
{ result = val } | |
| dice | |
dice: term D term | |
{ result = val } | |
| term D term filter_type term | |
{ result = val } | |
| term | |
filter_type: K H | |
{ result = :KH } | |
| K L | |
{ result = :KL } | |
| D H | |
{ result = :DH } | |
| D L | |
{ result = :DL } | |
term: PARENL add PARENR | |
{ result = val[1] } | |
| NUMBER | |
end | |
---- inner | |
def parse(source) | |
@tokens = tokenize(source) | |
do_parse() | |
end | |
def tokenize(source) | |
tokens = source.gsub(%r{[\+\-\*/DKHLUR()<>!=]}) { |e| " #{e} " }.split(" ") | |
tokens = tokens.map do |t| | |
type = token_type(t) | |
t = t.to_i if type == :NUMBER | |
[type, t] | |
end | |
tokens.push([false, '$']) | |
end | |
def token_type(t) | |
case t | |
when '+' | |
:PLUS | |
when '-' | |
:MINUS | |
when '*' | |
:ASTERISK | |
when '/' | |
:SLASH | |
when '(' | |
:PARENL | |
when ')' | |
:PARENR | |
when '<' | |
:LESS | |
when '>' | |
:GREATER | |
when '=' | |
:EQUAL | |
when '!' | |
:NOT | |
when /\A\d+\z/ | |
:NUMBER | |
else | |
t.to_sym | |
end | |
end | |
def next_token | |
@tokens.shift | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RerollDice | |
token NUMBER R U C F PLUS MINUS ASTERISK SLASH PARENL PARENR BRACKETL BRACKETR LESS GREATER EQUAL NOT AT | |
rule | |
expr: notation bracket target at | |
{ result = val } | |
target: /* none */ | |
| cmp_op term | |
{ result = val } | |
bracket: /* none */ | |
| BRACKETL add BRACKETR | |
{ result = val } | |
| BRACKETL cmp_op add BRACKETR | |
{ result = val } | |
at: /* none */ | |
| AT add | |
{ result = val } | |
| AT cmp_op add | |
{ result = val } | |
cmp_op: LESS EQUAL | |
{ result = :<= } | |
| LESS | |
{ result = :< } | |
| GREATER | |
{ result = :> } | |
| GREATER EQUAL | |
{ result = :>= } | |
| NOT EQUAL | |
{ result = :!= } | |
| LESS GREATER | |
{ result = :!= } | |
| EQUAL | |
{ result = :== } | |
| EQUAL EQUAL | |
{ result = :== } | |
notation: notation PLUS dice | |
{ result = val } | |
| dice | |
dice: term R term | |
{ result = val } | |
add: add PLUS mul | |
{ result = val } | |
| add MINUS mul | |
{ result = val } | |
| mul | |
mul: mul ASTERISK unary | |
{ result = val } | |
| mul SLASH unary round_type | |
{ result = val } | |
| unary | |
round_type: /* none */ | |
| U | |
{ result = :ceil } | |
| C | |
{ result = :ceil } | |
| R | |
{ result = :round } | |
| F | |
{ result = :floor } | |
unary: PLUS unary | |
{ result = val } | |
| MINUS unary | |
{ result = val } | |
| term | |
term: PARENL add PARENR | |
{ result = val[1] } | |
| NUMBER | |
end | |
---- inner | |
def parse(source) | |
@tokens = tokenize(source) | |
do_parse() | |
end | |
def tokenize(source) | |
tokens = source.gsub(%r{[\+\-\*/()\[\]RUCF<>!=]}) { |e| " #{e} " }.split(" ") | |
tokens = tokens.map do |t| | |
type = token_type(t) | |
t = t.to_i if type == :NUMBER | |
[type, t] | |
end | |
tokens.push([false, '$']) | |
end | |
def token_type(t) | |
case t | |
when '+' | |
:PLUS | |
when '-' | |
:MINUS | |
when '*' | |
:ASTERISK | |
when '/' | |
:SLASH | |
when '(' | |
:PARENL | |
when ')' | |
:PARENR | |
when '[' | |
:BRACKETL | |
when ']' | |
:BRACKETR | |
when '<' | |
:LESS | |
when '>' | |
:GREATER | |
when '=' | |
:EQUAL | |
when '!' | |
:NOT | |
when /\A\d+\z/ | |
:NUMBER | |
else | |
t.to_sym | |
end | |
end | |
def next_token | |
@tokens.shift | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment