import regex import symbol import string import vector import util fun lexer(regs: vector::vector): lexer { /*var toRet:lexer*/ var toRet.construct() :lexer regs.for_each( fun(reg: regex::regex) { toRet.add_regex(util::make_pair(reg.regexString, reg)); }) return toRet } fun lexer(regs: vector::vector>): lexer { /*var toRet:lexer*/ var toRet.construct() :lexer regs.for_each( fun(reg: util::pair) toRet.add_regex(util::make_pair(reg.first.name, reg.second)); ) return toRet } obj lexer (Object) { var regs: vector::vector> var input: string::string var position: int fun construct(): *lexer { regs.construct() input.construct() position = 0 return this } fun destruct() { regs.destruct() input.destruct() } fun copy_construct(old: *lexer) { regs.copy_construct(&old->regs) input.copy_construct(&old->input) position = old->position } fun operator=(old: lexer) { destruct() copy_construct(&old) } fun add_regex(name: string::string, newOne: regex::regex) { regs.add(util::make_pair(name,newOne)) } fun add_regex(newOne: util::pair) { regs.add(newOne) } fun add_regex(newOne: regex::regex) { regs.add(util::make_pair(newOne.regexString, newOne)) } fun add_regex(newOne: *char) { regs.add(util::make_pair(string::string(newOne), regex::regex(newOne))) } fun set_input(in: string::string) { input = in } fun next(): symbol::symbol { if (position >= input.length()) return symbol::eof_symbol() var max = regs.map(fun(reg_pair: util::pair): util::pair { return util::make_pair(reg_pair.second.long_match(input.slice(position, -1)), reg_pair.first); }) .max(fun(first: util::pair, second: util::pair): bool { return first.first < second.first; }) if (max.first < 0) return symbol::invalid_symbol() position += max.first return symbol::symbol(max.second, true, input.slice(position-max.first, position)) } }