Skip to content

Instantly share code, notes, and snippets.

@marionette-of-u
Last active December 15, 2015 05:19
Show Gist options
  • Select an option

  • Save marionette-of-u/5207999 to your computer and use it in GitHub Desktop.

Select an option

Save marionette-of-u/5207999 to your computer and use it in GitHub Desktop.
let s:token = { 'ast': 0, 'pls': 1, 'l_pare': 2, 'r_pare': 3, 'id': 4, 'token_0': 5 }
let s:stack = {}
function! s:stack.ctor()
let self.gap_ = 0
let self.tmp_ = []
let self.stack_ = []
endfunction
function! s:stack.reset_tmp()
let self.gap_ = len(self.stack_)
let self.tmp_ = []
endfunction
function! s:stack.commit_tmp()
if len(self.stack_) > self.gap_
call remove(self.stack_, self.gap_, len(self.stack_) - 1)
endif
let l:i = 0
while l:i < len(self.tmp_)
call add(self.stack_, self.tmp_[i])
let l:i += 1
endwhile
endfunction
function! s:stack.push(f)
call add(self.tmp_, copy(a:f))
endfunction
function! s:stack.pop(n_)
let l:n = a:n_
if len(self.tmp_) < l:n
let l:n -= len(self.tmp_)
let self.tmp_ = []
let self.gap_ -= l:n
else
call remove(self.tmp_, len(self.tmp_) - l:n, len(self.tmp_) - 1)
endif
endfunction
function! s:stack.top()
if len(self.tmp_) > 0
return self.tmp_[len(self.tmp_) - 1]
else
return self.stack_[self.gap_ - 1]
endif
endfunction
function! s:stack.get_arg(base, index)
let l:n = len(self.tmp_)
if (a:base - a:index) <= l:n
return self.tmp_[l:n - (a:base - a:index)]
else
return self.stack_[self.gap_ - (a:base - l:n) + a:index]
endif
endfunction
function! s:stack.clear()
let self.stack_ = []
endfunction
let s:stack_frame = {}
function! s:stack_frame.ctor(s, g, v)
let self.state = copy(a:s)
let self.gotof = copy(a:g)
let self.value = copy(a:v)
endfunction
let s:parser = {}
function! s:parser.ctor(sa)
let self.sa_ = copy(a:sa)
let self.stack_ = copy(s:stack)
call self.stack_.ctor()
call self.reset()
endfunction
function! s:parser.reset()
let self.error_ = 0
let self.accepted_ = 0
call self.clear_stack()
call self.reset_tmp_stack()
call self.push_stack('state_0', 'gotof_0', 0)
call self.commit_tmp_stack()
endfunction
function! s:parser.post(token, value)
call self.reset_tmp_stack()
while self[self.stack_top().state](a:token, a:value) == 1
endwhile
if self.error_ == 0
call self.commit_tmp_stack()
endif
return self.accepted_ || self.error_
endfunction
function! s:parser.accept()
if self.error_ == 1
return 0
endif
return 1
endfunction
function! s:parser.clear_stack()
call self.stack_.clear()
endfunction
function! s:parser.reset_tmp_stack()
call self.stack_.reset_tmp()
endfunction
function! s:parser.push_stack(s, g, v)
let l:x = copy(s:stack_frame)
call l:x.ctor(a:s, a:g, a:v)
call self.stack_.push(l:x)
return 1
endfunction
function! s:parser.pop_stack(n)
call self.stack_.pop(a:n)
endfunction
function! s:parser.commit_tmp_stack()
call self.stack_.commit_tmp()
endfunction
function! s:parser.stack_top()
return self.stack_.top()
endfunction
function! s:parser.get_arg(base, index)
return self.stack_.get_arg(a:base, a:index)['value']
endfunction
function! s:parser.call_0_make_mlt(nonterminal_index, base, arg_idx_0, arg_idx_1)
let l:r = self.sa_.make_mlt(self.get_arg(a:base, a:arg_idx_0), self.get_arg(a:base, a:arg_idx_1))
call self.pop_stack(a:base)
return self[self.stack_top().gotof](a:nonterminal_index, l:r)
endfunction
function! s:parser.call_0_make_pls(nonterminal_index, base, arg_idx_0, arg_idx_1)
let l:r = self.sa_.make_pls(self.get_arg(a:base, a:arg_idx_0), self.get_arg(a:base, a:arg_idx_1))
call self.pop_stack(a:base)
return self[self.stack_top().gotof](a:nonterminal_index, l:r)
endfunction
function! s:parser.call_0_make_id(nonterminal_index, base, arg_idx_0)
let l:r = self.sa_.make_id(self.get_arg(a:base, a:arg_idx_0))
call self.pop_stack(a:base)
return self[self.stack_top().gotof](a:nonterminal_index, l:r)
endfunction
function! s:parser.call_0_make_exp(nonterminal_index, base, arg_idx_0)
let l:r = self.sa_.make_exp(self.get_arg(a:base, a:arg_idx_0))
call self.pop_stack(a:base)
return self[self.stack_top().gotof](a:nonterminal_index, l:r)
endfunction
function! s:parser.gotof_0(nonterminal_index, v)
if a:nonterminal_index == 0
return self.push_stack('state_7', 'gotof_7', a:v)
else
return 0
endif
endfunction
function! s:parser.state_0(t, value)
if a:t == s:token.l_pare
call self.push_stack('state_1', 'gotof_1', a:value)
return 0
elseif a:t == s:token.id
call self.push_stack('state_8', 'gotof_8', a:value)
return 0
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
function! s:parser.gotof_1(nonterminal_index, v)
if a:nonterminal_index == 0
return self.push_stack('state_4', 'gotof_4', a:v)
else
return 0
endif
endfunction
function! s:parser.state_1(t, value)
if a:t == s:token.l_pare
call self.push_stack('state_1', 'gotof_1', a:value)
return 0
elseif a:t == s:token.id
call self.push_stack('state_8', 'gotof_8', a:value)
return 0
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
function! s:parser.gotof_2(nonterminal_index, v)
if a:nonterminal_index == 0
return self.push_stack('state_5', 'gotof_5', a:v)
else
return 0
endif
endfunction
function! s:parser.state_2(t, value)
if a:t == s:token.l_pare
call self.push_stack('state_1', 'gotof_1', a:value)
return 0
elseif a:t == s:token.id
call self.push_stack('state_8', 'gotof_8', a:value)
return 0
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
function! s:parser.gotof_3(nonterminal_index, v)
if a:nonterminal_index == 0
return self.push_stack('state_6', 'gotof_6', a:v)
else
return 0
endif
endfunction
function! s:parser.state_3(t, value)
if a:t == s:token.l_pare
call self.push_stack('state_1', 'gotof_1', a:value)
return 0
elseif a:t == s:token.id
call self.push_stack('state_8', 'gotof_8', a:value)
return 0
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
function! s:parser.gotof_4(nonterminal_index, v)
return 1
endfunction
function! s:parser.state_4(t, value)
if a:t == s:token.ast
call self.push_stack('state_2', 'gotof_2', a:value)
return 0
elseif a:t == s:token.pls
call self.push_stack('state_3', 'gotof_3', a:value)
return 0
elseif a:t == s:token.r_pare
call self.push_stack('state_9', 'gotof_9', a:value)
return 0
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
function! s:parser.gotof_5(nonterminal_index, v)
return 1
endfunction
function! s:parser.state_5(t, value)
if a:t == s:token.ast || a:t == s:token.pls || a:t == s:token.r_pare || a:t == s:token.token_0
return self.call_0_make_mlt(0, 3, 0, 2)
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
function! s:parser.gotof_6(nonterminal_index, v)
return 1
endfunction
function! s:parser.state_6(t, value)
if a:t == s:token.ast
call self.push_stack('state_2', 'gotof_2', a:value)
return 0
elseif a:t == s:token.pls || a:t == s:token.r_pare || a:t == s:token.token_0
return self.call_0_make_pls(0, 3, 0, 2)
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
function! s:parser.gotof_7(nonterminal_index, v)
return 1
endfunction
function! s:parser.state_7(t, value)
if a:t == s:token.ast
call self.push_stack('state_2', 'gotof_2', a:value)
return 0
elseif a:t == s:token.pls
call self.push_stack('state_3', 'gotof_3', a:value)
return 0
elseif a:t == s:token.token_0
let self.accepted_ = 1
let self.accepted_value = self.get_arg(1, 0)
return 0
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
function! s:parser.gotof_8(nonterminal_index, v)
return 1
endfunction
function! s:parser.state_8(t, value)
if a:t == s:token.ast || a:t == s:token.pls || a:t == s:token.r_pare || a:t == s:token.token_0
return self.call_0_make_id(0, 1, 0)
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
function! s:parser.gotof_9(nonterminal_index, v)
return 1
endfunction
function! s:parser.state_9(t, value)
if a:t == s:token.ast || a:t == s:token.pls || a:t == s:token.r_pare || a:t == s:token.token_0
return self.call_0_make_exp(0, 3, 1)
else
call self.sa_.syntax_error()
let self.error_ = 1
return 0
endif
endfunction
let s:semantic_action = {}
function! s:semantic_action.make_mlt(arg_0, arg_1)
return 'multi(' . a:arg_0 . ', ' . a:arg_1 . ')'
endfunction
function! s:semantic_action.make_pls(arg_0, arg_1)
return 'plus(' . a:arg_0 . ', ' . a:arg_1 . ')'
endfunction
function! s:semantic_action.make_id(arg_0)
return a:arg_0
endfunction
function! s:semantic_action.make_exp(arg_0)
return a:arg_0
endfunction
function! s:semantic_action.syntax_error()
echo 'error'
endfunction
let s:p = copy(s:parser)
call s:p.ctor(s:semantic_action)
" call s:p.post(s:token.l_pare, ' ')
call s:p.post(s:token.id, 'id_0')
call s:p.post(s:token.pls, ' ')
call s:p.post(s:token.id, 'id_1')
" call s:p.post(s:token.r_pare, ' ')
call s:p.post(s:token.ast, ' ')
call s:p.post(s:token.id, 'id_2')
call s:p.post(s:token.token_0, ' ')
if s:p.accept()
echo s:p.accepted_value
endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment