Skip to content

Instantly share code, notes, and snippets.

@tyler
Created August 4, 2010 20:45
Show Gist options
  • Save tyler/508765 to your computer and use it in GitHub Desktop.
Save tyler/508765 to your computer and use it in GitHub Desktop.
class Scanner
class << self
attr_accessor :p, :marker, :line, :line_marker, :data, :output
end
%%{
machine scanner;
variable p self.p;
variable data self.data;
action mark { self.marker = self.p }
action line {
self.line += 1
emit('newline', false)
self.line_marker = self.p
}
action track_indent {
ni = p - self.marker
while ni != indent.last
if ni < indent.last
emit('dedent', false)
indent.pop
elsif ni > indent.last
emit('indent', false)
indent << ni
end
end
}
Identifier = alpha (alnum | '?' | '!' |'_')** %{emit('identifier')};
Operator = ("+" | "-" | "*" | "/" | "%" | "**" | "+=" | "-=" | "*=" |
"/=" | "%=" | "**=" | "&" | "|" | "^" | "<<" | ">>" | "&=" |
"|=" | "^=" | "<<=" | ">>=" | "=" | "==" | "===" | "<=>" |
"!=" | ">=" | "<=" | "&&" | "||" | '->' | ':') %{emit('operator')};
Symbol = ('(' | ')' | '{' | '}' | '[' | ']' | ',' | '.') %{emit('symbol')};
Number = digit+ %{emit('number')};
Token = (Identifier|Operator|Number|Symbol|' '+) >mark;
Newline = '\n' %line >mark;
Indent = ' ' %track_indent >mark;
Line = Indent** Token** Newline;
main := Line**;
}%%
%% write data;
def self.scan(input_data)
self.data = input_data
self.line = 0
self.line_marker = 0
self.output = []
indent = [0]
eof = self.data.size
%% write init;
%% write exec;
return self.output
end
def self.emit(type, payload=nil)
token = { :type => type, :line => line, :offset => marker-line_marker, :position => marker }
token[:data] = payload || self.data[marker..p-1] unless payload == false
self.output << token
end
end
Scanner.scan(<<-EOF).each { |token| p token }
module Trie
import HashMap
struct Node(a)
Char state
[Node(a)] children
[Boolean]{256} existence
a value
create = (Type t) -> Node
Node(t, state: 0)
add = (Node(a) node, String key, a value) -> Boolean
each(key): (char) ->
addNode(node, char) unless childExists?(node, char)
node = getChild(node, key)
node.value = value
get = (Node(a) node, String key) -> a
each(key): (char) ->
return nil unless childExists?(node, char)
node = getChild(node, key)
node.value
private
childExists? = (Node(a) node, Char k) -> Boolean
node.existence[k]
addNode = (Node(a) node, Char k) -> Boolean
node.existence[k] = true
node.children << Node(k)
getChild = (Node(a) node, Char k) -> Node(a)
node.find: (n) ->
n.state == k
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment