Permalink
Browse files

More operator chaining tests.

  • Loading branch information...
1 parent 8f875b7 commit 88a56745f3654753ce56ab9e55d08ae142da2bed @vic committed Aug 24, 2011
Showing with 83 additions and 219 deletions.
  1. +2 −14 lib/akin/grammar.kpeg
  2. +4 −100 lib/akin/grammar.rb
  3. +24 −12 lib/akin/parser.rb
  4. +53 −93 spec/grammar_spec.rb
View
@@ -114,24 +114,12 @@ ph_comma(h) = expr(h):a w "," - ph_comma(h):b { b.unshift a ; b }
expr(h) = value(h):e &{ e.pos.column > h.column } {e}
-chain(h) = chain(h):a w "." - chain(h):b ~n(a.pos, :chain, a, b)
+chain(h) = chain(h):a w "." - chain(h):b ~chain_cont(a, b)
| operator:a !&brace o w chain(h):b
~n(a.pos, :chain, a, *Array(b.name == :chain && b.args || b))
- | chain_cont(h)
- | chain_val(h):a sp* chain(a.pos):b
- ~n(a.pos, :chain, a, *Array(b.name == :chain && b.args || b))
+ | chain_val(h):a sp* chain(a.pos):b ~chain_cont(a, b)
| chain_val(h)
-chain_cont(h) = chain_val(h):a {(h | a.pos || h()).incr}:i sp*
- (comma(h) | (nl|sheebang) - block(i)):c
- {
- if a.name == :act
- a.args.push *Array(c); a
- else
- n(a.pos, :act, a, nil, *Array(c))
- end
- }
-
chain_val(h) = cons(h) | expr(h)
block(h) = chain(h):a sp* t - block(h):b
View
@@ -3302,7 +3302,7 @@ def _expr(h)
return _tmp
end
- # chain = (chain(h):a w "." - chain(h):b {n(a.pos, :chain, a, b)} | operator:a !(&brace) o w chain(h):b {n(a.pos, :chain, a, *Array(b.name == :chain && b.args || b))} | chain_cont(h) | chain_val(h):a sp* chain(a.pos):b {n(a.pos, :chain, a, *Array(b.name == :chain && b.args || b))} | chain_val(h))
+ # chain = (chain(h):a w "." - chain(h):b {chain_cont(a, b)} | operator:a !(&brace) o w chain(h):b {n(a.pos, :chain, a, *Array(b.name == :chain && b.args || b))} | chain_val(h):a sp* chain(a.pos):b {chain_cont(a, b)} | chain_val(h))
def _chain(h)
_save = self.pos
@@ -3337,7 +3337,7 @@ def _chain(h)
self.pos = _save1
break
end
- @result = begin; n(a.pos, :chain, a, b); end
+ @result = begin; chain_cont(a, b); end
_tmp = true
unless _tmp
self.pos = _save1
@@ -3392,9 +3392,6 @@ def _chain(h)
break if _tmp
self.pos = _save
- _tmp = apply_with_args(:_chain_cont, h)
- break if _tmp
- self.pos = _save
_save5 = self.pos
while true # sequence
@@ -3419,7 +3416,7 @@ def _chain(h)
self.pos = _save5
break
end
- @result = begin; n(a.pos, :chain, a, *Array(b.name == :chain && b.args || b)); end
+ @result = begin; chain_cont(a, b); end
_tmp = true
unless _tmp
self.pos = _save5
@@ -3439,98 +3436,6 @@ def _chain(h)
return _tmp
end
- # chain_cont = chain_val(h):a {(h | a.pos || h()).incr}:i sp* (comma(h) | (nl | sheebang) - block(i)):c { if a.name == :act a.args.push *Array(c); a else n(a.pos, :act, a, nil, *Array(c)) end }
- def _chain_cont(h)
-
- _save = self.pos
- while true # sequence
- _tmp = apply_with_args(:_chain_val, h)
- a = @result
- unless _tmp
- self.pos = _save
- break
- end
- @result = begin; (h | a.pos || h()).incr; end
- _tmp = true
- i = @result
- unless _tmp
- self.pos = _save
- break
- end
- while true
- _tmp = apply(:_sp)
- break unless _tmp
- end
- _tmp = true
- unless _tmp
- self.pos = _save
- break
- end
-
- _save2 = self.pos
- while true # choice
- _tmp = apply_with_args(:_comma, h)
- break if _tmp
- self.pos = _save2
-
- _save3 = self.pos
- while true # sequence
-
- _save4 = self.pos
- while true # choice
- _tmp = apply(:_nl)
- break if _tmp
- self.pos = _save4
- _tmp = apply(:_sheebang)
- break if _tmp
- self.pos = _save4
- break
- end # end choice
-
- unless _tmp
- self.pos = _save3
- break
- end
- _tmp = apply(:__hyphen_)
- unless _tmp
- self.pos = _save3
- break
- end
- _tmp = apply_with_args(:_block, i)
- unless _tmp
- self.pos = _save3
- end
- break
- end # end sequence
-
- break if _tmp
- self.pos = _save2
- break
- end # end choice
-
- c = @result
- unless _tmp
- self.pos = _save
- break
- end
- @result = begin;
- if a.name == :act
- a.args.push *Array(c); a
- else
- n(a.pos, :act, a, nil, *Array(c))
- end
- ; end
- _tmp = true
- unless _tmp
- self.pos = _save
- end
- break
- end # end sequence
-
- set_failed_rule :_chain_cont unless _tmp
- return _tmp
- end
-
# chain_val = (cons(h) | expr(h))
def _chain_val(h)
@@ -3744,8 +3649,7 @@ def _eof
Rules[:_part_head] = rule_info("part_head", "sp+ !(&keypart) (ph_comma(h) | expr(h) | {[]})")
Rules[:_ph_comma] = rule_info("ph_comma", "(expr(h):a w \",\" - ph_comma(h):b { b.unshift a ; b } | expr(h):a w \",\" - expr(h):b { [a,b] })")
Rules[:_expr] = rule_info("expr", "value(h):e &{ e.pos.column > h.column } {e}")
- Rules[:_chain] = rule_info("chain", "(chain(h):a w \".\" - chain(h):b {n(a.pos, :chain, a, b)} | operator:a !(&brace) o w chain(h):b {n(a.pos, :chain, a, *Array(b.name == :chain && b.args || b))} | chain_cont(h) | chain_val(h):a sp* chain(a.pos):b {n(a.pos, :chain, a, *Array(b.name == :chain && b.args || b))} | chain_val(h))")
- Rules[:_chain_cont] = rule_info("chain_cont", "chain_val(h):a {(h | a.pos || h()).incr}:i sp* (comma(h) | (nl | sheebang) - block(i)):c { if a.name == :act a.args.push *Array(c); a else n(a.pos, :act, a, nil, *Array(c)) end }")
+ Rules[:_chain] = rule_info("chain", "(chain(h):a w \".\" - chain(h):b {chain_cont(a, b)} | operator:a !(&brace) o w chain(h):b {n(a.pos, :chain, a, *Array(b.name == :chain && b.args || b))} | chain_val(h):a sp* chain(a.pos):b {chain_cont(a, b)} | chain_val(h))")
Rules[:_chain_val] = rule_info("chain_val", "(cons(h) | expr(h))")
Rules[:_block] = rule_info("block", "(chain(h):a sp* t - block(h):b {n(a.pos, :block, a, *Array(b.name == :block && b.args || b))} | chain(h))")
Rules[:_root] = rule_info("root", "- block(h)?:b - eof {b}")
View
@@ -1,7 +1,7 @@
module Akin
module Parser
-
+
BRACES_ALIST = [
['(', ')'],
['{', '}'],
@@ -10,15 +10,15 @@ module Parser
['\{', '\}'],
['\[', '\]']
]
-
+
def braces
@braces ||= BRACES_ALIST.dup
end
-
+
def brace(text)
braces.assoc(text) || braces.rassoc(text)
end
-
+
def node(*a, &b)
Node.new(*a, &b)
end
@@ -31,27 +31,27 @@ def current_position(o = pos)
def h
Position.new(0, 0)
- end
-
+ end
+
class Position
attr_accessor :line, :column
-
+
def initialize(line = nil, column = nil)
@line, @column = line, column
end
-
+
def |(other)
if @line.nil? || @line.zero?
other
else
self
end
end
-
+
def incr(line = 0, column = 1)
self.class.new @line + line, @column + column
end
-
+
def at(line = 0, column = 0)
self.class.new line, column
end
@@ -105,7 +105,19 @@ def text_node(p, parts)
end
node(p, :chain, m, *ary.map { |a| [n(p, :oper, "++"), a] }.flatten)
end
-
+
+ def chain_cont(a, b)
+ if b.name == :chain
+ if a.name == :chain
+ a.args.push *b.args; a
+ else
+ n(a.pos, :chain, a, *b.args)
+ end
+ else
+ n(a.pos, :chain, a, b)
+ end
+ end
+
end # Parser
-
+
end
Oops, something went wrong.

0 comments on commit 88a5674

Please sign in to comment.