   if result
     return lex consume(input, result), tokens
 
-  # Operators must follow coefficients or variables
-  if state == "COEFFICIENT" or state == "VARIABLE"
-    result = /^[<>+-]/.exec input
+  # Lex tokens!
+  for lexer in lexers
+    continue unless state in lexer.states
+    result = lexer.regexp.exec input
     if result
-      token = new Token "OPERATOR", result[0]
-      return lex consume(input, result), tokens.concat(token)
-
-  # Coefficients can exist at the start of an expression, or after an operator
-  if not state or state == "OPERATOR"
-    result = /^(-?[0-9]+(\.[0-9]+)?)|(-)/.exec input
-    if result
-      token = new Token "COEFFICIENT", result[0]
-      return lex consume(input, result), tokens.concat(token)
-
-  # Variables can come at any point except after a variable
-  if state != "VARIABLE"
-    result = /^[xyXY]/.exec input
-    if result
-      token = new Token "VARIABLE", result[0]
+      token = new Token lexer.token, result[0]
       return lex consume(input, result), tokens.concat(token)
 
   throw "Parse error at '#{input}' (tokens: #{tokens}, last token: #{previous})"
+
+# These inputs should all be parseable. Not a maximally reduced set,
+# but I think this covers everything
+good = ["2x + 0.5y < 350", "-3x+2y-50<0","-x-3y-1>0", "2<x+y", "2x+-5y+5+6>0"]
 
 console.log "Good inputs:\n"
 for i in good
   console.log i
   console.log lex(i).join(" -> ")
+
+# These should be invalid.
+bad  = ["< 5", "horse", "x + y + z < 0", "x = 0"]
 
 console.log "\nBad inputs:\n"
 for i in bad


  toString: -> "[#{@type} '#{@value}']"

lex = (input, tokens=[]) ->
  if input.length == 0
    return tokens

# Normal form of the inequality is x + y + c < 0
class Inequality
  constructor: (@x, @y, @c) ->
