/
lexer.rb
51 lines (36 loc) · 2.05 KB
/
lexer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
module Schemer
class Lexer < Parslet::Parser
alias_method :`, :str
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.maybe }
rule(:lparen) { `(` >> space? }
rule(:rparen) { space? >> `)` }
rule :string do
`"` >> (`""` | `"`.absnt? >> any).repeat.as(:string) >> `"`
end
rule(:letter) { match('[a-zA-Z]') }
rule(:dot) { `.` }
rule(:special_symbol) { `_` | `-` | `?` | `!` | `+` | `-` | `*` | `/` | `>=` | `<=` | `>` | `<` | `=` }
rule(:integer) { match('\d').repeat(1) }
rule(:float) { integer.repeat(1) >> dot >> integer.repeat(1) }
rule(:numeric) { `-`.maybe >> (float.as(:float) | integer.as(:integer)) }
rule(:character) { `#\\` >> letter.as(:char) }
rule(:boolean) { `#` >> (`t` | `f`).as(:boolean) }
rule(:literal) { numeric | string | character | boolean }
rule(:list) { lparen >> args.as(:list) >> rparen }
rule(:vector) { `#` >> lparen >> args.as(:vector) >> rparen }
rule(:quoted_list){ `'` >> lparen >> args.as(:quoted_list) >> rparen }
rule(:pair) { lparen >> (arg >> space >> dot >> space >> args).as(:pair) >> rparen }
rule(:symbol) { letter >> (letter | integer | special_symbol).repeat(0) }
rule(:quoted_symbol) { `'` >> symbol.as(:quoted_identifier) }
# rule(:operator) { [`+`, `-`, `*`, `/`, `>=`, `<=`, `>`, `<`, `=`].inject(:|) }
rule(:operator) { `+` | `-` | `*` | `/` | `>=` | `<=` | `>` | `<` | `=` }
# rule(:operator) { match("[\\+-\\*\\/<>=]") }
rule(:arg) { (symbol.as(:identifier) | quoted_list | literal | quoted_symbol | procedure | pair | vector | list) }
rule(:args) { (arg >> space?).repeat }
rule(:comment) { `;`.repeat(1,3) >> (`\n`.absnt? >> any).repeat.as(:comment) }
rule(:procedure) { (lparen >> (symbol.as(:identifier) | operator.as(:identifier) | procedure).as(:proc) >> (space? >> args.as(:args)).maybe >> rparen).as(:procedure) }
rule(:body) { (procedure | space | comment).repeat(0) }
root :body
end
end