Last active
December 15, 2015 05:19
-
-
Save marionette-of-u/5207999 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| 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