bairui

Vimpeg version of Crenshaw's Assignment Expression parser

Jun 26th, 2011
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VIM 4.51 KB | None | 0 0
  1. " Assignment Expression PEG
  2. " Barry Arthur, Jun 2011
  3.  
  4. source ../plugin/vimpeg.vim
  5. let p = Vimpeg()
  6.  
  7. "http://pastebin.com/anE5m37A
  8. "Grammar for Jack Crenshaw's Assignment Expression Parser (Part 3):
  9.   "<assignment>  ::=  <name> = <expression>
  10.   "<expression>  ::=  <term> ( <add> | <subtract> )*
  11.   "<subtract>    ::=  '-' <term>
  12.   "<add>         ::=  '+' <term>
  13.   "<term>        ::=  <factor> ( <multiply> | <divide> )*
  14.   "<divide>      ::=  '/' <factor>
  15.   "<multiply>    ::=  '*' <factor>
  16.   "<factor>      ::=  <number> | '(' <expression> ')' | <ident>
  17.   "<ident>       ::=  <func> | <name>
  18.   "<func>        ::=  <name> '(' ')'
  19.   "<name>        ::=  <alpha> <alphanum>*
  20.   "<alpha>       ::=  [a-zA-Z_]
  21.   "<alphanum>    ::=  <alpha> | <digit>
  22.   "<number>      ::=  <digit>+
  23.   "<digit>       ::=  [0-9]
  24.  
  25. "http://pastebin.com/S5XLq9SP
  26. let ass = p.and(['name', p.e('='), 'expression'],                               {'id': 'assignment', 'on_match': 'Assignment'})
  27. call      p.and(['term', p.maybe_many(p.or(['add', 'subtract']))],              {'id': 'expression', 'on_match': 'Expression'})
  28. call      p.and([p.e('-'), 'term'],                                             {'id': 'subtract',   'on_match': 'Op'})
  29. call      p.and([p.e('+'), 'term'],                                             {'id': 'add',        'on_match': 'Op'})
  30. call      p.and(['factor', p.maybe_many(p.or(['multiply', 'divide']))],         {'id': 'term',       'on_match': 'Term'})
  31. call      p.and([p.e('/'), 'factor'],                                           {'id': 'divide',     'on_match': 'Op'})
  32. call      p.and([p.e('*'), 'factor'],                                           {'id': 'multiply',   'on_match': 'Op'})
  33. call       p.or(['number', p.and([p.e('('), 'expression', p.e(')')]), 'ident'], {'id': 'factor',     'on_match': 'Factor'})
  34. call       p.or(['func', 'name'],                                               {'id': 'ident',      'on_match': 'Ident'})
  35. call      p.and(['name', p.and([p.e('('), p.e(')')])],                          {'id': 'func',       'on_match': 'Func'})
  36. call      p.and(['alpha', p.maybe_many('alphanum')],                            {'id': 'name',       'on_match': 'Name'})
  37. call        p.e('[a-zA-Z_]',                                                    {'id': 'alpha'})
  38. call       p.or(['alpha', 'digit'],                                             {'id': 'alphanum'})
  39. call     p.many('digit',                                                        {'id': 'number',     'on_match': 'Number'})
  40. call        p.e('[0-9]',                                                        {'id': 'digit'})
  41.  
  42. func! Assignment(elems)
  43.   "echo 'Assignment='.string(a:elems)
  44.   return "let " . a:elems[0][0] . ' = ' . a:elems[2][0]
  45. endfunc
  46. func! Expression(elems)
  47.   "echo 'Expression='.string(a:elems)
  48.   return Flatten(a:elems)
  49. endfunc
  50. func! Factor(elems)
  51.   "echo 'Factor='.string(a:elems)
  52.   return Flatten(a:elems)
  53. endfunc
  54. func! Op(elems)
  55.   return Flatten(a:elems)
  56. endfunc
  57. func! Term(elems)
  58.   echo 'Term='.string(a:elems)
  59.   return Flatten(a:elems)
  60. endfunc
  61. func! Ident(elems)
  62.   "echo 'Ident='.string(a:elems)
  63.   return a:elems[0]
  64. endfunc
  65. func! Func(elems)
  66.   "echo 'Func='.string(a:elems)
  67.   return Flatten(a:elems)
  68. endfunc
  69. func! Name(elems)
  70.   "echo 'Name='.string(a:elems)
  71.   return Flatten(a:elems)
  72. endfunc
  73. func! Number(elems)
  74.   return Flatten(a:elems)
  75. endfunc
  76.  
  77. function! Flatten(array)
  78.   if type(a:array) == type([])
  79.     return join(map(a:array, 'Flatten(v:val)'), '')
  80.   elseif type(a:array) == type(0)
  81.     return '' . a:array
  82.   elseif type(a:array) == type("")
  83.     return a:array
  84.   endif
  85. endfunction
  86.  
  87. " Toggle the return options here to variously see the entire match object, or
  88. " the evaluated result (the 'value').
  89. func! Ass(expr)
  90.   return string(g:ass.match(a:expr))
  91.   "return string(g:ass.match(a:expr)['value'])
  92. endfunc
  93.  
  94. " client side
  95. "echo 'let x = 45'           . '==' . Ass('x = 45')
  96. "echo 'let x = 45 - 101'           . '==' . Ass('x = 45 - 101')
  97. "echo 'let x = 45 + 99'      . '==' . Ass('x = 45 + 99')
  98. "echo 'let x = 15 - 101'     . '==' . Ass('x = 15 - 101')
  99. "echo 'let x = 234 * 3'      . '==' . Ass('x = 234 * 3')
  100. "echo 'let x = 1023 / 2'     . '==' . Ass('x = 1023 / 2')
  101. "echo 'let x = (1023 / 2) + 7'     . '==' . Ass('x = (1023 / 2) + 7')
  102. echo 'let x = ((1023 / 2) * 9) + (7 - 2)'     . '==' . Ass('x = ((1023 / 2) * 9) + (7 - 2)')
  103.  
  104. "echo 'let x = a / 2'        . '==' . Ass('x = a / 2')
  105. "echo 'let x = abc / 2'      . '==' . Ass('x = abc / 2')
  106. "echo 'let x = apple() / 2'  . '==' . Ass('x = apple() / 2')
Advertisement
Add Comment
Please, Sign In to add comment