Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- source ../plugin/vimpeg.vim
- let p = Vimpeg({'skip_white': 1})
- " Ideas {{{
- " - For later, maybe create callback functions populated with vars
- " corresponding to each element? Check Definition(). Not sure if all vars
- " would be used, though.
- " - Add support for double quoted strings.
- " - Should VimPEG's function have the abort flag?
- " }}}
- " Original PEG syntax {{{
- " # Hierarchical syntax
- " Grammar <- Spacing Definition+ EndOfFile
- " Definition <- Identifier LEFTARROW Expression
- " Expression <- Sequence (SLASH Sequence)*
- " Sequence <- Prefix*
- " Prefix <- (AND / NOT)? Suffix
- " Suffix <- Primary (QUESTION / STAR / PLUS)?
- " Primary <- Identifier !LEFTARROW / OPEN Expression CLOSE / Literal / Class / DOT
- " # Lexical syntax
- " Identifier <- IdentStart IdentCont* Spacing
- " IdentStart <- [a-zA-Z_]
- " IdentCont <- IdentStart / [0-9]
- " Literal <- [’] (![’] Char)* [’] Spacing / ["] (!["] Char)* ["] Spacing
- " Class <- ’[’ (!’]’ Range)* ’]’ Spacing
- " Range <- Char ’-’ Char / Char
- " Char <- ’\\’ [nrt’"\[\]\\] / ’\\’ [0-2][0-7][0-7] / ’\\’ [0-7][0-7]? / !’\\’ .
- " LEFTARROW <- ’<-’ Spacing
- " SLASH <- ’/’ Spacing
- " AND <- ’&’ Spacing
- " NOT <- ’!’ Spacing
- " QUESTION <- ’?’ Spacing
- " STAR <- ’*’ Spacing
- " PLUS <- ’+’ Spacing
- " OPEN <- ’(’ Spacing
- " CLOSE <- ’)’ Spacing
- " DOT <- ’.’ Spacing
- " Spacing <- (Space / Comment)*
- " Comment <- ’#’ (!EndOfLine .)* EndOfLine
- " Space <- ’ ’ / ’\t’ / EndOfLine
- " EndOfLine <- ’\r\n’ / ’\n’ / ’\r’
- " EndOfFile <- !.
- " }}}
- " VimPEG syntax {{{
- " <definition> ::= <label> <mallet> <expression> <callback>?
- " <expression> ::= <sequence> ( <or> <sequence> )*
- " <sequence> ::= <prefix>*
- " <prefix> ::= <not>? <suffix>
- " <suffix> ::= <primary> ( <question> | <star> | <plus> )?
- " <primary> ::= <label> !<mallet> | <open> <expression> <close> | <regex>
- " <callback> ::= <right_arrow> <identifier>
- " <label> ::= <lt> <identifier> <gt>
- " <identifier> ::= <ident_start> <ident_cont>*
- " <ident_cont> ::= '\w'
- " <ident_start> ::= '\h'
- " <regex> ::= <dquoted_string> | <squoted_string>
- " <dquoted_string> ::= <dquote> ( <double_backslash> | <escaped_dquote> | '[^"]' )* <dquote>
- " <squoted_string> ::= <squote> ( "[^']" | <double_squote> )* <squote>
- " <escaped_dquote> ::= <backslash> <dquote>
- " <double_backslash> ::= <backslash> <backslash>
- " <backslash> ::= '\'
- " <dquote> ::= '"'
- " <double_squote> ::= ''''''
- " <squote> ::= "'"
- " <right_arrow> ::= '->'
- " <mallet> ::= '::='
- " <or> ::= '|'
- " <not> ::= '!'
- " <question> ::= '?'
- " <star> ::= '\*'
- " <plus> ::= '+'
- " <close> ::= ')'
- " <open> ::= '('
- " <gt> ::= '>'
- " <lt> ::= '<'
- " }}}
- " Parser grammar {{{
- let expr = p.and(['label', 'mallet', 'expression', p.maybe_one('callback')],
- \{'id': 'definition', 'on_match': 'Definition'})
- call p.and(['sequence', p.maybe_many(p.and(['or', 'sequence']))],
- \{'id': 'expression', 'on_match': 'Expression'})
- call p.maybe_many('prefix',
- \{'id': 'sequence', 'on_match': 'Sequence'})
- call p.and([p.maybe_one('not'), 'suffix'],
- \{'id': 'prefix', 'on_match': 'Prefix'})
- call p.and(['primary', p.maybe_one(p.or(['question', 'star', 'plus']))],
- \{'id': 'suffix', 'on_match': 'Suffix'})
- call p.or([p.and(['label', p.not_has('mallet')]), p.and(['open', 'expression', 'close']), 'regex'],
- \{'id': 'primary', 'on_match': 'Primary'})
- call p.and(['right_arrow', 'identifier'],
- \{'id': 'callback', 'on_match': 'Callback'})
- call p.and(['lt', 'identifier', 'gt'],
- \{'id': 'label', 'on_match': 'Label'})
- call p.and(['ident_start', p.many('ident_cont')],
- \{'id': 'identifier', 'on_match': 'Identifier'})
- call p.e('\w',
- \{'id': 'ident_cont'})
- call p.e('\h',
- \{'id': 'ident_start'})
- call p.or(['squoted_string', 'dquoted_string'],
- \{'id': 'regex', 'on_match': 'Regex'})
- call p.and(['dquote', p.maybe_many(p.or(['double_backslash', 'escaped_dquote', p.e('[^"]')])), 'dquote'],
- \{'id': 'dquoted_string', 'on_match': 'Dquoted_string'})
- call p.and(['squote', p.maybe_many(p.or([p.e('[^'']'),'double_squote'])), 'squote'],
- \{'id': 'squoted_string', 'on_match': 'Squoted_string'})
- call p.and(['backslash', 'dquote'],
- \{'id': 'escaped_dquote', 'on_match': 'Escaped_dquote'})
- call p.and(['backslash', 'backslash'],
- \{'id': 'double_backslash', 'on_match': 'Double_backslash'})
- call p.e('\',
- \{'id': 'backslash', 'on_match': 'Backslash'})
- call p.e('"',
- \{'id': 'dquote', 'on_match': 'Dquote'})
- call p.e("''",
- \{'id': 'double_squote', 'on_match': 'Double_squote'})
- call p.e("'",
- \{'id': 'squote', 'on_match': 'Squote'})
- call p.e('->',
- \{'id': 'right_arrow', 'on_match': 'Right_arrow'})
- call p.e('::=',
- \{'id': 'mallet', 'on_match': 'Mallet'})
- call p.e('|',
- \{'id': 'or', 'on_match': 'Or'})
- call p.e('!',
- \{'id': 'not', 'on_match': 'Not'})
- call p.e('?',
- \{'id': 'question', 'on_match': 'Question'})
- call p.e('\*',
- \{'id': 'star', 'on_match': 'Star'})
- call p.e('+',
- \{'id': 'plus', 'on_match': 'Plus'})
- call p.e(')',
- \{'id': 'close', 'on_match': 'Close'})
- call p.e('(',
- \{'id': 'open', 'on_match': 'Open'})
- call p.e('>',
- \{'id': 'gt', 'on_match': 'Gt'})
- call p.e('<',
- \{'id': 'lt', 'on_match': 'Lt'})
- " }}}
- " Callback functions {{{
- function! Definition(elems)
- echom string(a:elems)
- let label = a:elems[0]
- let mallet = a:elems[1]
- let expression = a:elems[2]
- let callback = len(a:elems[3]) > 0 ? a:elems[3][0] : ''
- let result = 'call '.expression[:-2].",\n \\{'id': ".label.
- \(callback != '' ? ", 'on_match': ".string(callback) : '') . "})"
- echom 'Definition: ' . result
- return result
- endfunction
- function! Expression(elems)
- echom string(a:elems)
- if len(a:elems[1]) > 0
- echom 1
- let result = 'p.or(['.a:elems[0]. ', '. join(a:elems[1][0][1:], ', ').'])'
- else
- echom 2
- let result = a:elems[0]
- endif
- echom 'Expression: ' . result
- return result
- endfunction
- function! Sequence(elems)
- echom string(a:elems)
- let sequence = a:elems
- if len(sequence) > 1
- let result = 'p.and(['.join(sequence, ', ').'])'
- else
- let result = sequence[0]
- endif
- echom 'Sequence: ' . result
- return result
- endfunction
- function! Prefix(elems)
- let suffix = a:elems[1]
- if len(a:elems[0]) > 0
- let prefix = a:elems[1][0]
- let result = 'p.or('.suffix.')'
- else
- let result = suffix
- endif
- echom 'Prefix: ' . result
- return result
- endfunction
- function! Suffix(elems)
- let primary = a:elems[0]
- if len(a:elems[1]) > 0
- let suffix = a:elems[1][0]
- let result = 'p.'.(suffix == '*' ? 'maybe_many' : (suffix == '+' ? 'many' : 'maybe_one')) . '('.primary.')'
- else
- let result = primary
- endif
- echom 'Suffix: ' . result
- return result
- endfunction
- function! Primary(elems)
- echom 'Primary: '.string(a:elems)
- let len = len(a:elems)
- if type(a:elems) == type('')
- let result = a:elems
- elseif len == 2
- let result = a:elems[0]
- else
- let result = a:elems[1]
- endif
- echom 'Primary: ' . result
- return result
- endfunction
- function! Callback(elems)
- let callback = a:elems[1]
- echom 'Callback: ' . callback
- return callback
- endfunction
- function! Label(elems)
- echo a:elems
- let result = "'".a:elems[1]."'"
- echom 'Label: ' . result
- return result
- endfunction
- function! Identifier(elems)
- let id = a:elems[0] . join(a:elems[1], '')
- echom 'Identifier: ' . id
- return id
- endfunction
- function! Regex(elems)
- echom string(a:elems)
- let regex = 'p.e('.a:elems.')'
- echom 'Regex: ' . regex
- return regex
- endfunction
- function! Dquoted_string(elems)
- echom string(a:elems)
- let dquoted_string = a:elems[0].join(a:elems[1], '').a:elems[2]
- echom 'Dquoted_string: ' . dquoted_string
- return dquoted_string
- endfunction
- function! Squoted_string(elems)
- echom string(a:elems)
- let squoted_string = a:elems[0]
- echom 'Squoted_string: ' . squoted_string
- return squoted_string
- endfunction
- function! Escaped_dquote(elems)
- echom string(a:elems)
- let escaped_dquote = a:elems[0]
- echom 'Escaped_dquote: ' . escaped_dquote
- return escaped_dquote
- endfunction
- function! Double_backslash(elems)
- echom string(a:elems)
- let double_backslash = a:elems[0]
- echom 'Double_backslash: ' . double_backslash
- return double_backslash
- endfunction
- function! Backslash(elems)
- echom string(a:elems)
- let backslash = a:elems[0]
- echom 'Backslash: ' . backslash
- return backslash
- endfunction
- function! Dquote(elems)
- echom string(a:elems)
- let dquote = a:elems[0]
- echom 'Dquote: ' . dquote
- return dquote
- endfunction
- function! Double_squote(elems)
- let double_squote = a:elems[0]
- echom 'Double_squote: ' . double_squote
- return double_squote
- endfunction
- function! Squote(elems)
- let squote = a:elems[0]
- "echom 'Squote: ' . squote
- return squote
- endfunction
- function! Right_arrow(elems)
- let right_arrow = a:elems[0]
- "echom 'Right_arrow: ' . right_arrow
- return right_arrow
- endfunction
- function! Mallet(elems)
- let mallet = a:elems
- "echom 'Mallet: ' . mallet
- return mallet
- endfunction
- function! Or(elems)
- let or = a:elems[0]
- "echom 'Or: ' . or
- return or
- endfunction
- function! Not(elems)
- let not = a:elems[0]
- "echom 'Not: ' . not
- return not
- endfunction
- function! Question(elems)
- let question = a:elems[0]
- "echom 'Question: ' . question
- return question
- endfunction
- function! Star(elems)
- let star = a:elems[0]
- "echom 'Star: ' . star
- return star
- endfunction
- function! Plus(elems)
- let plus = a:elems[0]
- "echom 'Plus: ' . plus
- return plus
- endfunction
- function! Close(elems)
- let close = a:elems[0]
- "echom 'Close: ' . close
- return close
- endfunction
- function! Open(elems)
- let open = a:elems[0]
- "echom 'Open: ' . open
- return open
- endfunction
- function! Gt(elems)
- let gt = a:elems[0]
- "echom 'Gt: ' . gt
- return gt
- endfunction
- function! Lt(elems)
- let lt = a:elems[0]
- "echom 'Lt: ' . lt
- return lt
- endfunction
- " }}}
- function! Test(expr)
- let expr = substitute(a:expr, '^"\s*', '', '')
- echom expr
- let result = g:expr.match(expr).value
- echom expr
- return result
- endfunction
- nore <leader><leader> :w<bar>so %<bar>echo Test(getline('.'))<CR>
- finish
- " <hola> ::= <id1> <id2> | 'dido' -> Dado
Advertisement
Add Comment
Please, Sign In to add comment