Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Extract reimann from its ustate chrysalis

  • Loading branch information...
commit d87e6dfa1a8d9cd12de324d60b4adfa37afa0d4f 0 parents
@aphyr authored
Showing with 6,460 additions and 0 deletions.
  1. +12 −0 .gitignore
  2. +9 −0 BUILDING
  3. +227 −0 LICENSE
  4. +372 −0 README.markdown
  5. +11 −0 THANKS
  6. +9 −0 bin/reimann
  7. +2 −0  build_parser.sh
  8. +7 −0 leiningen/build.clj
  9. +41 −0 project.clj
  10. +33 −0 proto/reimann/proto.proto
  11. +18 −0 reimann.config
  12. +111 −0 src/reimann/Query.g
  13. +1,480 −0 src/reimann/QueryLexer.java
  14. +2,426 −0 src/reimann/QueryParser.java
  15. +6 −0 src/reimann/bin.clj
  16. +86 −0 src/reimann/client.clj
  17. +61 −0 src/reimann/common.clj
  18. +38 −0 src/reimann/config.clj
  19. +45 −0 src/reimann/core.clj
  20. +47 −0 src/reimann/email.clj
  21. +21 −0 src/reimann/folds.clj
  22. +66 −0 src/reimann/graphite.clj
  23. +62 −0 src/reimann/index.clj
  24. +64 −0 src/reimann/query.clj
  25. +61 −0 src/reimann/server.clj
  26. +392 −0 src/reimann/streams.clj
  27. +36 −0 test/reimann/test/bench.clj
  28. +28 −0 test/reimann/test/client.clj
  29. +137 −0 test/reimann/test/core.clj
  30. +14 −0 test/reimann/test/email.clj
  31. +27 −0 test/reimann/test/graphite.clj
  32. +49 −0 test/reimann/test/index.clj
  33. +146 −0 test/reimann/test/query.clj
  34. +23 −0 test/reimann/test/server.clj
  35. +293 −0 test/reimann/test/streams.clj
12 .gitignore
@@ -0,0 +1,12 @@
+.cake
+pom.xml
+*.jar
+*.war
+*.deb
+lib
+classes
+build
+.lein-deps-sum
+.lein-failures
+protosrc/
+reimann-*.zip
9 BUILDING
@@ -0,0 +1,9 @@
+# To get started
+lein deps
+lein javac
+lein protobuf compile
+lein compile
+
+# For debian
+lein uberjar
+lein deb
227 LICENSE
@@ -0,0 +1,227 @@
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
+THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and
+documentation distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and
+are distributed by that particular Contributor. A Contribution
+'originates' from a Contributor if it was added to the Program by such
+Contributor itself or anyone acting on such Contributor's
+behalf. Contributions do not include additions to the Program which:
+(i) are separate modules of software distributed in conjunction with
+the Program under their own license agreement, and (ii) are not
+derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor
+which are necessarily infringed by the use or sale of its Contribution
+alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this
+Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free copyright
+license to reproduce, prepare derivative works of, publicly display,
+publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and
+object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free patent
+license under Licensed Patents to make, use, sell, offer to sell,
+import and otherwise transfer the Contribution of such Contributor, if
+any, in source code and object code form. This patent license shall
+apply to the combination of the Contribution and the Program if, at
+the time the Contribution is added by the Contributor, such addition
+of the Contribution causes such combination to be covered by the
+Licensed Patents. The patent license shall not apply to any other
+combinations which include the Contribution. No hardware per se is
+licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the
+licenses to its Contributions set forth herein, no assurances are
+provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow
+Recipient to distribute the Program, it is Recipient's responsibility
+to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient
+copyright rights in its Contribution, if any, to grant the copyright
+license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form
+under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties
+and conditions, express and implied, including warranties or
+conditions of title and non-infringement, and implied warranties or
+conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability
+for damages, including direct, indirect, special, incidental and
+consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are
+offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such
+Contributor, and informs licensees how to obtain it in a reasonable
+manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained
+within the Program.
+
+Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain
+responsibilities with respect to end users, business partners and the
+like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a
+commercial product offering should do so in a manner which does not
+create potential liability for other Contributors. Therefore, if a
+Contributor includes the Program in a commercial product offering,
+such Contributor ("Commercial Contributor") hereby agrees to defend
+and indemnify every other Contributor ("Indemnified Contributor")
+against any losses, damages and costs (collectively "Losses") arising
+from claims, lawsuits and other legal actions brought by a third party
+against the Indemnified Contributor to the extent caused by the acts
+or omissions of such Commercial Contributor in connection with its
+distribution of the Program in a commercial product offering. The
+obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property
+infringement. In order to qualify, an Indemnified Contributor must: a)
+promptly notify the Commercial Contributor in writing of such claim,
+and b) allow the Commercial Contributor tocontrol, and cooperate with
+the Commercial Contributor in, the defense and any related settlement
+negotiations. The Indemnified Contributor may participate in any such
+claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to
+the risks and costs of program errors, compliance with applicable
+laws, damage to or loss of data, programs or equipment, and
+unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
+ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further
+action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Program itself (excluding combinations of the Program with other
+software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of
+the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of
+time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use
+and distribution of the Program as soon as reasonably
+practicable. However, Recipient's obligations under this Agreement and
+any licenses granted by Recipient relating to the Program shall
+continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and
+may only be modified in the following manner. The Agreement Steward
+reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement
+Steward has the right to modify this Agreement. The Eclipse Foundation
+is the initial Agreement Steward. The Eclipse Foundation may assign
+the responsibility to serve as the Agreement Steward to a suitable
+separate entity. Each new version of the Agreement will be given a
+distinguishing version number. The Program (including Contributions)
+may always be distributed subject to the version of the Agreement
+under which it was received. In addition, after a new version of the
+Agreement is published, Contributor may elect to distribute the
+Program (including its Contributions) under the new version. Except as
+expressly stated in Sections 2(a) and 2(b) above, Recipient receives
+no rights or licenses to the intellectual property of any Contributor
+under this Agreement, whether expressly, by implication, estoppel or
+otherwise. All rights in the Program not expressly granted under this
+Agreement are reserved.
+
+This Agreement is governed by the laws of the State of Washington and
+the intellectual property laws of the United States of America. No
+party to this Agreement will bring a legal action under this Agreement
+more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.
372 README.markdown
@@ -0,0 +1,372 @@
+Update
+======
+
+For performance reasons, and for fun, I've started work on a drop-in
+replacement for ustate: reimann.
+
+Reimann uses the same wire protocol and queries, so you can forward from ustate
+to reimann and vice-versa. The ruby ustate client in master already supports
+reimann. Simple benchmarks suggest 3,000 synchronous events/sec on a single
+thread; most of the time spent in network code. There is low-hanging
+optimization fruit here--I'm just trying to get it feature-complete so I can
+test on real datasets. Underlying stream primitives like rates already handle
+hundreds of thousands of events/sec on a Macbook Pro.
+
+Reimann provides a more expressive language for filtering, changing, splitting,
+and combining events across time and state space. Instead of *states*, you
+submit *events* which flow through various pipes. You no longer have to
+aggregate states over time on the client; it's possible to submit *every* event
+directly to reimann and it will compute rates, percentiles, etc.
+
+Ready:
+
+- TCP server
+- TCP forwarding
+- Configuration file
+- Stream primitives
+ - Rates
+ - Percentiles
+ - Split by field
+ - Where filter
+ - Combine streams (with let bindings; macro pending)
+ - Change values
+ - Forward to another ustate/reimann
+- State index
+- Send emails
+- Query parser
+- Querying states
+- Basic expiry
+
+TODO before release:
+
+- Forward to graphite
+- Docs, demo, slides for talk
+
+After that:
+- HSQL index
+- UDP server
+- UDP client
+- Ruby UDP client
+- Drop aleph, replace with raw netty?
+- Subscribe to streams?
+
+The Sinatra dashboard will still be maintained, as will the ruby clients.
+
+Overview
+======
+
+UState ("United States", "microstate", etc.) is a state aggregation daemon. It
+accepts a stream of state transitions and maintains an index of service states,
+which can be queried or forwarded to various handlers. A state is simply:
+
+ state {
+ host: A hostname, e.g. "api1", "foo.com",
+ service: e.g. "API port 8000 reqs/sec",
+ state: Any string less than 255 bytes, e.g. "ok", "warning", "critical",
+ time: The time that the service entered this state, in unix time,
+ description: Freeform text,
+ metric_f: A floating-point number associated with this state, e.g. the number of reqs/sec,
+ once: A boolean, described below.
+ }
+
+Normally, every state received by the server fires Index#on_state. When
+state.state changes, Index#on_state_change is called. You can, for example,
+register to send a single email whenever a state changes to :warning.
+
+:once states are transient. They fire Index#on_state and #on_state_once, but do
+*not* update the index. They can be used for events which are instantaneous;
+instead of sending {state: error} and {state: ok}, send {state: error,
+once:true}.
+
+For example, recoverable errors may not hang your application, but
+should be processed by the email notifier. Sending a :once state with
+the error description means you can receive an email for each error,
+instead of two for entering and exiting the error state.
+
+At http://showyou.com, we use UState to monitor the health and performance of
+hundreds of services across our infrastructure, including CPU, queries/second,
+latency bounds, disk usage, queues, and others.
+
+UState also includes a simple dashboard Sinatra app.
+
+Installing
+==========
+
+ git clone git://github.com/aphyr/ustate.git
+
+or
+
+ gem install ustate-client
+
+For the client:
+
+ gem install beefcake trollop
+
+For the server:
+
+ gem install treetop eventmachine sequel sqlite3 trollop beefcake
+
+For the dashboard:
+
+ gem install sinatra thin erubis sass
+
+We run UState from Upstart. An example job is in docs/upstart.conf.
+
+Demo
+====
+
+To try it out, install all the gems above, and clone the repository. Start the server with
+
+ bin/server
+
+UState listens on TCP socket host:port, and accepts connections from clients. Start a basic testing client with
+
+ bin/test
+
+The tester spews randomly generated statistics at a server on the default local host and port. To see it in action, run the dashboard:
+
+ cd lib/ustate/dash
+ ../../../bin/dash
+
+Server
+======
+
+The server loads a file in the working directory named config.rb. Override with
+--config-file. Its contents are instance-evaled in the context of the current
+server. You can use this to extend ustate with additional behavior.
+
+Expiring States
+---------------
+
+The reaper periodically kills states matching queries which are too old. It
+will ensure that any state matching a query will be present for *at least* that
+many seconds. For instance:
+
+ # States expire after 10 seconds
+ reaper.default = 10
+
+ # Except for daily stats, which last 2 days
+ reaper.reap 'service =~ "%daily%"', 2 * 24 * 3600
+
+ # We need to know RIGHT AWAY if the fridge fails to check in.
+ reaper.reap 'host = "fridge"', 1
+
+In this configuration, daily updates from host fridge will stay around for 2
+days, everything not on the fridge expires after 10 seconds, and other fridge
+updates are kept for only one second.
+
+Note that the reaper does some query recomposition which can lead to
+inefficient patterns. Writing an optimizer is on my list.
+
+Email
+-----
+
+config.rb:
+
+ # Email comes from this address (required):
+ emailer.from = 'ustate@your.net'
+
+ # Use this SMTP relay (default 127.0.0.1)
+ emailer.host = '123.4.56.7'
+
+ # Receive mail when a state transition matches any of ...
+ emailer.tell 'you@gmail.com', 'state = "error" or state = "critical"'
+ emailer.tell 'you@gmail.com', 'service =~ "mysql%"'
+
+Aggregating states
+---
+
+UState can fold together states matching some criteria to provide a more
+general overview of a complex system. Folds are executed in a separate thread
+and polled from the index every aggregator.interval seconds.
+
+config.rb:
+
+ # Add together the metrics for all feed mergers on any host.
+ # The resulting state has service name 'feed merger', but no host.
+ aggregator.sum 'service = "feed merger" and host != null', host: nil
+
+ # Average latencies
+ aggregator.average 'service = "api latency"'
+
+ # You can also pass any block to aggregator.fold. The block will be called
+ # with an array of states matching your query.
+ aggregator.fold 'service = "custom"' do |states|
+ UState::State.new(
+ service: 'some crazy result',
+ metric_f: states.map(&:metric_f).max
+ )
+ end
+
+Graphite
+---
+
+UState can forward metrics to Graphite. Just specify a query matching states
+you'd like to forward. Forwarding is performed in a separate thread, and polled
+from the index every graphite.interval seconds.
+
+config.rb:
+
+ graphite.host = 'foo'
+ graphite.port = 12345
+
+ # Submit states every 5 seconds
+ graphite.interval = 5
+
+ # Send everything without a host
+ graphite.graph 'host = null'
+
+ # And also include the disk use on all nodes
+ graphite.graph 'service = "disk"'
+
+Custom hooks
+------------
+
+config.rb:
+
+ # Log all states received to console.
+ index.on_state do |s|
+ p s
+ end
+
+ # Forward state transitions to another server.
+ require 'ustate/client'
+ client = UState::Client.new :host => '123.45.67.8'
+ index.on_state_change do |old, new|
+ client << new
+ end
+ index.on_state_once do |state|
+ client << state
+ end
+
+Client
+======
+
+You can use the git repo, or the gem.
+
+ gem install ustate-client
+
+Then:
+
+ require 'ustate'
+ require 'ustate/client'
+
+ # Create a client
+ c = UState::Client.new(
+ host: "my.host", # Default localhost
+ port: 1234 # Default 55956
+ )
+
+ # Insert a state
+ c << {
+ state: "ok",
+ service: "My service"
+ }
+
+ # Query for states
+ c.query.states # => [UState::State(state: 'ok', service: 'My service')]
+ c.query('state != "ok"').states # => []
+
+Client state management
+-----------------------
+
+UState provides some classes to make managing state updates easier.
+
+UState::MetricThread starts a thread to poll a metric periodically, which can
+be used to flush an accumulated value to ustate at regular intervals.
+
+UState::AutoState bundles a state and a client together. Any changes to the
+AutoState automatically send the new state to the client.
+
+The Dashboard
+=============
+
+The dashboard runs a file in the local directory: config.rb. That file can
+override any configuration options on the Dash class (hence all Sinatra
+configuration) as well as the Ustate client, etc.
+
+ set :port, 6000 # HTTP server on port 6000
+ config[:client][:host] = 'my.ustate.server'
+
+It also loads views from the local directory. Sinatra makes it awkward to
+compose multiple view directories, so you'll probably want to create your own
+view/ and config.rb. I've provided an example stylesheet, layout, and dashboard
+in lib/ustate/dash/views--as well as an extensive set of functions for laying
+out states corresponding to any query: see lib/ustate/dash/helper/renderer.rb.
+The way I figure, you're almost certainly going to want to write your own, so
+I'm going to give you the tools you need, and get out of your way.
+
+An example config.rb, additional controllers, views, and public directory are
+all in doc/dash. Should give you ideas for extending the dashboard for your own needs.
+
+Protocol
+========
+
+A connection to UState is a stream of messages. Each message is a 4 byte
+network-endian integer *length*, followed by a Procol Buffer Message of
+*length* bytes. See proto/message.proto for the protobuf particulars.
+
+The server will accept a repeated list of States, and respond with a
+confirmation message with either an acknowledgement or an error. Check the `ok`
+boolean in the message; if false, message.error will be a descriptive string.
+
+States are uniquely identified by host and service. Both allow null. State.time
+is the time in unix epoch seconds and is required.
+
+You can also query states using a very basic expression language. The grammar
+is specified as a Parsable Expression Grammar in query_string.treetop. Examples
+include:
+
+ state = "ok"
+
+ (service =~ "disk%") or (state == "critical" and host =~ "%.trioptimum.com")
+
+ metric_f > 2.0 and not host = "tau ceti 5"
+
+ # All states
+ true
+
+ # No states
+ false
+
+Just submit a Message with your query in Message.query.string. Search queries
+will return a message with repeated States matching that expression. An null
+expression will return no states.
+
+Performance
+===========
+
+On a macbook pro 8,3, I see >1300 queries/sec or >1200 inserts/sec. The client
+is fully threadsafe, and performs well concurrently. I will continue to tune
+UState for latency and throughput, and welcome patches.
+
+For large installations, I plan to implement a selective forwarder. Local
+ustate servers can accept high volumes of states from a small set of nodes, and
+forward updates at a larger granularity to supervisors, and so forth, in a
+tree. The query language should be able to support proxying requests to the
+most recent source of a state, so very large sets of services can be maintained
+at high granularity.
+
+Future directions
+=====
+
+Several people have mentioned wanting to query historical states; to replay the
+events in ustate over time. There are some difficulties here; notably that
+compressing hundreds of millions of states can make it a little tricky to query
+states over the entire dataset. If we restrict ourselves to specific time
+ranges, storing sequential states as protocol buffers compressed with snappy
+could work, especially if only *state* changes are written. Storing only state
+deltas might work as well.
+
+UState currently offers only one-second time resolution. Sub-second times will
+be provided by a second field (e.g. State.nanoseconds). I haven't decided on
+the granularity yet.
+
+It'd be interesting to subscribe to states matching a query and receive states
+pushed to you as soon as they change.
+
+Should be easy to add a UDP acceptor for states as well. Have to figure out
+eventmachine with multiple backends.
+
+When the protocol and architecture are finalized, I plan to reimplement the
+server in a faster language.
11 THANKS
@@ -0,0 +1,11 @@
+#flatland and #leiningen, including jodaro, ninjudd, raynes, and amalloy,
+helped with protobufs parsing, leiningen, and general clojure questions.
+
+Showyou, my employer, gave me the problems I needed Reimann for, and the time to solve them.
+
+John Mullerleile (jrecursive) was deeply involved in talking through the
+concept and structure of Reimann, as well as offering advice around the JVM.
+
+C Scott Andreas (cscotta) gave many helpful suggestions around the JVM, Maven,
+high_scale_lib. Our conversations filled my head with many excellent algorithms
+and ideas.
9 bin/reimann
@@ -0,0 +1,9 @@
+#!/bin/bash
+if [ -z "$1" ]
+then
+ config="/etc/reimann/reimann.config"
+else
+ config=$1
+fi
+
+java -jar /usr/lib/reimann/reimann.jar "$config"
2  build_parser.sh
@@ -0,0 +1,2 @@
+java -cp 'lib/*' org.antlr.Tool src/reimann/Query.g
+lein javac
7 leiningen/build.clj
@@ -0,0 +1,7 @@
+(ns leiningen.build)
+
+(defn build [project & args]
+ "Build everything! Yay!"
+ (leiningen.compile/compile project)
+ (leiningen.protobuf/compile project)
+ (leiningen.javac/javac project))
41 project.clj
@@ -0,0 +1,41 @@
+(defproject reimann "0.0.1-SNAPSHOT"
+ :description "reimann: folds events into states"
+ :url "http://github.com/aphyr/ustate"
+ :repositories {
+ "boundary-site" "http://maven.boundary.com/artifactory/repo"
+ }
+ :dependencies [
+ [clojure "1.2.0"]
+ [aleph "0.2.0"]
+ [protobuf "0.6.0-beta5"]
+ [org.antlr/antlr "3.2"]
+ [com.boundary/high-scale-lib "1.0.3"]
+ [clj-time "0.3.4"]
+ [com.draines/postal "1.7-SNAPSHOT"]
+ ]
+ :dev-dependencies [
+ [lein-deb "1.0.0-SNAPSHOT"]
+ [protobuf "0.6.0-beta5"]
+ ]
+ :test-selectors {:default (complement :integration)
+ :integration :integration
+ :all (fn [_] true)}
+ :java-source-path "src/reimann/"
+ :aot [reimann.bin]
+ :main reimann.bin
+ ; Work around a bug where protobufs get nuked.
+ :disable-implicit-clean true
+ :deb {:maintainer {:name "Kyle Kingsbury"
+ :email "aphyr@aphyr.com"}
+ ; I wish I could use relative paths here, but lein-deb complains
+ ; "No directory specified for tarfileset". Hmm.
+ :filesets [{:file "/home/aphyr/ustate/reimann/reimann-0.0.1-SNAPSHOT-standalone.jar"
+ :fullpath "/usr/lib/reimann/reimann.jar"}
+ {:file "/home/aphyr/ustate/reimann/reimann.config"
+ :fullpath "/etc/reimann/reimann.config"}
+ {:file "/home/aphyr/ustate/reimann/bin/reimann"
+ :fullpath "/usr/bin/reimann"
+ :filemode "0755"}]
+ :depends ""}
+ :deb-skip-jar true
+)
33 proto/reimann/proto.proto
@@ -0,0 +1,33 @@
+option java_package = "reimann";
+option java_outer_classname = "Proto";
+
+message State {
+ optional int64 time = 1;
+ optional string state = 2;
+ optional string service = 3;
+ optional string host = 4;
+ optional string description = 5;
+ optional bool once = 6;
+ optional float metric_f = 15;
+}
+
+message Event {
+ optional int64 time = 1;
+ optional string state = 2;
+ optional string service = 3;
+ optional string host = 4;
+ optional string description = 5;
+ optional float metric_f = 15;
+}
+
+message Query {
+ optional string string = 1;
+}
+
+message Msg {
+ optional bool ok = 2;
+ optional string error = 3;
+ repeated State states = 4;
+ optional Query query = 5;
+ repeated Event events = 6;
+}
18 reimann.config
@@ -0,0 +1,18 @@
+; vim: filetype=clojure
+
+(tcp-server)
+
+(let [client (tcp-client)
+ index (update (index))]
+
+ (streams
+ (with {:metric_f 1 :host nil :service "events/sec"}
+ (rate 5 index))
+
+ (where (service #"^per")
+ (percentiles 5 [0 0.5 0.95 0.99 1]
+ index))
+
+ index
+
+))
111 src/reimann/Query.g
@@ -0,0 +1,111 @@
+grammar Query;
+
+options {
+ output=AST;
+ ASTLabelType=CommonTree;
+}
+
+tokens {
+ AND = 'and';
+ OR = 'or';
+ NOT = 'not';
+ APPROXIMATELY = '=~';
+ NOT_EQUAL = '!=';
+ EQUAL = '=';
+ LESSER = '<';
+ LESSER_EQUAL = '<=';
+ GREATER = '>';
+ GREATER_EQUAL = '>=';
+}
+
+@header {package reimann;}
+@lexer::header {package reimann;}
+
+expr : (or EOF) -> or;
+
+or : and (WS* OR^ WS* and)*;
+
+and : (not | primary) (WS* AND^ WS* (not | primary))*;
+
+not : NOT^ WS* (not | primary);
+
+
+primary : (
+ ('(' or ')') -> ^(or)
+ | simple -> simple
+ );
+
+fragment
+simple : ( t | f | nil
+ | approximately
+ | lesser
+ | lesser_equal
+ | greater
+ | greater_equal
+ | not_equal
+ | equal);
+
+approximately
+ : field WS* APPROXIMATELY^ WS* value;
+lesser : field WS* LESSER^ WS* value;
+lesser_equal
+ : field WS* LESSER_EQUAL^ WS* value;
+greater : field WS* GREATER^ WS* value;
+greater_equal
+ : field WS* GREATER_EQUAL^ WS* value;
+not_equal
+ : field WS* NOT_EQUAL^ WS* value;
+equal : field WS* EQUAL^ WS* value;
+
+value : (String | t | f | nil | INT | FLOAT);
+
+
+t : 'true';
+f : 'false';
+nil : 'null' | 'nil';
+
+field : ('host'
+ | 'service'
+ | 'state'
+ | 'description'
+ | 'metric_f'
+ | 'time'
+ );
+
+ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
+ ;
+
+INT : '-'? '0'..'9'+
+ ;
+
+FLOAT
+ : '-'? ('0'..'9')+ ('.' ('0'..'9')*)? EXPONENT?
+ ;
+
+WS : ( ' '
+ | '\t'
+ | '\r'
+ | '\n'
+ ) {$channel=HIDDEN;}
+ ;
+
+fragment
+EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
+
+String :
+// '"' (EscapeSequence | FreeChar)* '"'
+// Still don't understand why this doesn't work
+ '"' ( EscapeSequence | ~('\u0000'..'\u001f' | '\\' | '\"' ) )* '"'
+ ;
+
+ fragment EscapeSequence
+ : '\\' (UnicodeEscape |'b'|'t'|'n'|'f'|'r'|'\"'|'\\')
+ ;
+
+fragment UnicodeEscape
+ : 'u' HexDigit HexDigit HexDigit HexDigit
+ ;
+
+fragment HexDigit
+ : '0'..'9' | 'A'..'F' | 'a'..'f'
+ ;
1,480 src/reimann/QueryLexer.java
@@ -0,0 +1,1480 @@
+// $ANTLR 3.2 Sep 23, 2009 14:05:07 src/reimann/Query.g 2012-02-07 15:10:24
+package reimann;
+
+import org.antlr.runtime.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+
+public class QueryLexer extends Lexer {
+ public static final int LESSER_EQUAL=11;
+ public static final int EXPONENT=19;
+ public static final int T__29=29;
+ public static final int T__28=28;
+ public static final int T__27=27;
+ public static final int T__26=26;
+ public static final int T__25=25;
+ public static final int T__24=24;
+ public static final int T__23=23;
+ public static final int APPROXIMATELY=7;
+ public static final int FLOAT=17;
+ public static final int INT=16;
+ public static final int NOT=6;
+ public static final int ID=18;
+ public static final int AND=4;
+ public static final int EOF=-1;
+ public static final int HexDigit=22;
+ public static final int T__30=30;
+ public static final int T__31=31;
+ public static final int T__32=32;
+ public static final int T__33=33;
+ public static final int LESSER=10;
+ public static final int GREATER=12;
+ public static final int WS=14;
+ public static final int T__34=34;
+ public static final int NOT_EQUAL=8;
+ public static final int UnicodeEscape=21;
+ public static final int EQUAL=9;
+ public static final int OR=5;
+ public static final int String=15;
+ public static final int GREATER_EQUAL=13;
+ public static final int EscapeSequence=20;
+
+ // delegates
+ // delegators
+
+ public QueryLexer() {;}
+ public QueryLexer(CharStream input) {
+ this(input, new RecognizerSharedState());
+ }
+ public QueryLexer(CharStream input, RecognizerSharedState state) {
+ super(input,state);
+
+ }
+ public String getGrammarFileName() { return "src/reimann/Query.g"; }
+
+ // $ANTLR start "AND"
+ public final void mAND() throws RecognitionException {
+ try {
+ int _type = AND;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:5:5: ( 'and' )
+ // src/reimann/Query.g:5:7: 'and'
+ {
+ match("and");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "AND"
+
+ // $ANTLR start "OR"
+ public final void mOR() throws RecognitionException {
+ try {
+ int _type = OR;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:6:4: ( 'or' )
+ // src/reimann/Query.g:6:6: 'or'
+ {
+ match("or");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "OR"
+
+ // $ANTLR start "NOT"
+ public final void mNOT() throws RecognitionException {
+ try {
+ int _type = NOT;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:7:5: ( 'not' )
+ // src/reimann/Query.g:7:7: 'not'
+ {
+ match("not");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "NOT"
+
+ // $ANTLR start "APPROXIMATELY"
+ public final void mAPPROXIMATELY() throws RecognitionException {
+ try {
+ int _type = APPROXIMATELY;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:8:15: ( '=~' )
+ // src/reimann/Query.g:8:17: '=~'
+ {
+ match("=~");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "APPROXIMATELY"
+
+ // $ANTLR start "NOT_EQUAL"
+ public final void mNOT_EQUAL() throws RecognitionException {
+ try {
+ int _type = NOT_EQUAL;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:9:11: ( '!=' )
+ // src/reimann/Query.g:9:13: '!='
+ {
+ match("!=");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "NOT_EQUAL"
+
+ // $ANTLR start "EQUAL"
+ public final void mEQUAL() throws RecognitionException {
+ try {
+ int _type = EQUAL;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:10:7: ( '=' )
+ // src/reimann/Query.g:10:9: '='
+ {
+ match('=');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "EQUAL"
+
+ // $ANTLR start "LESSER"
+ public final void mLESSER() throws RecognitionException {
+ try {
+ int _type = LESSER;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:11:8: ( '<' )
+ // src/reimann/Query.g:11:10: '<'
+ {
+ match('<');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "LESSER"
+
+ // $ANTLR start "LESSER_EQUAL"
+ public final void mLESSER_EQUAL() throws RecognitionException {
+ try {
+ int _type = LESSER_EQUAL;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:12:14: ( '<=' )
+ // src/reimann/Query.g:12:16: '<='
+ {
+ match("<=");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "LESSER_EQUAL"
+
+ // $ANTLR start "GREATER"
+ public final void mGREATER() throws RecognitionException {
+ try {
+ int _type = GREATER;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:13:9: ( '>' )
+ // src/reimann/Query.g:13:11: '>'
+ {
+ match('>');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "GREATER"
+
+ // $ANTLR start "GREATER_EQUAL"
+ public final void mGREATER_EQUAL() throws RecognitionException {
+ try {
+ int _type = GREATER_EQUAL;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:14:15: ( '>=' )
+ // src/reimann/Query.g:14:17: '>='
+ {
+ match(">=");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "GREATER_EQUAL"
+
+ // $ANTLR start "T__23"
+ public final void mT__23() throws RecognitionException {
+ try {
+ int _type = T__23;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:15:7: ( '(' )
+ // src/reimann/Query.g:15:9: '('
+ {
+ match('(');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__23"
+
+ // $ANTLR start "T__24"
+ public final void mT__24() throws RecognitionException {
+ try {
+ int _type = T__24;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:16:7: ( ')' )
+ // src/reimann/Query.g:16:9: ')'
+ {
+ match(')');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__24"
+
+ // $ANTLR start "T__25"
+ public final void mT__25() throws RecognitionException {
+ try {
+ int _type = T__25;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:17:7: ( 'true' )
+ // src/reimann/Query.g:17:9: 'true'
+ {
+ match("true");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__25"
+
+ // $ANTLR start "T__26"
+ public final void mT__26() throws RecognitionException {
+ try {
+ int _type = T__26;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:18:7: ( 'false' )
+ // src/reimann/Query.g:18:9: 'false'
+ {
+ match("false");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__26"
+
+ // $ANTLR start "T__27"
+ public final void mT__27() throws RecognitionException {
+ try {
+ int _type = T__27;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:19:7: ( 'null' )
+ // src/reimann/Query.g:19:9: 'null'
+ {
+ match("null");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__27"
+
+ // $ANTLR start "T__28"
+ public final void mT__28() throws RecognitionException {
+ try {
+ int _type = T__28;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:20:7: ( 'nil' )
+ // src/reimann/Query.g:20:9: 'nil'
+ {
+ match("nil");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__28"
+
+ // $ANTLR start "T__29"
+ public final void mT__29() throws RecognitionException {
+ try {
+ int _type = T__29;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:21:7: ( 'host' )
+ // src/reimann/Query.g:21:9: 'host'
+ {
+ match("host");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__29"
+
+ // $ANTLR start "T__30"
+ public final void mT__30() throws RecognitionException {
+ try {
+ int _type = T__30;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:22:7: ( 'service' )
+ // src/reimann/Query.g:22:9: 'service'
+ {
+ match("service");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__30"
+
+ // $ANTLR start "T__31"
+ public final void mT__31() throws RecognitionException {
+ try {
+ int _type = T__31;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:23:7: ( 'state' )
+ // src/reimann/Query.g:23:9: 'state'
+ {
+ match("state");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__31"
+
+ // $ANTLR start "T__32"
+ public final void mT__32() throws RecognitionException {
+ try {
+ int _type = T__32;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:24:7: ( 'description' )
+ // src/reimann/Query.g:24:9: 'description'
+ {
+ match("description");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__32"
+
+ // $ANTLR start "T__33"
+ public final void mT__33() throws RecognitionException {
+ try {
+ int _type = T__33;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:25:7: ( 'metric_f' )
+ // src/reimann/Query.g:25:9: 'metric_f'
+ {
+ match("metric_f");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__33"
+
+ // $ANTLR start "T__34"
+ public final void mT__34() throws RecognitionException {
+ try {
+ int _type = T__34;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:26:7: ( 'time' )
+ // src/reimann/Query.g:26:9: 'time'
+ {
+ match("time");
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "T__34"
+
+ // $ANTLR start "ID"
+ public final void mID() throws RecognitionException {
+ try {
+ int _type = ID;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:75:5: ( ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )* )
+ // src/reimann/Query.g:75:7: ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )*
+ {
+ if ( (input.LA(1)>='A' && input.LA(1)<='Z')||input.LA(1)=='_'||(input.LA(1)>='a' && input.LA(1)<='z') ) {
+ input.consume();
+
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;}
+
+ // src/reimann/Query.g:75:31: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )*
+ loop1:
+ do {
+ int alt1=2;
+ int LA1_0 = input.LA(1);
+
+ if ( ((LA1_0>='0' && LA1_0<='9')||(LA1_0>='A' && LA1_0<='Z')||LA1_0=='_'||(LA1_0>='a' && LA1_0<='z')) ) {
+ alt1=1;
+ }
+
+
+ switch (alt1) {
+ case 1 :
+ // src/reimann/Query.g:
+ {
+ if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='A' && input.LA(1)<='Z')||input.LA(1)=='_'||(input.LA(1)>='a' && input.LA(1)<='z') ) {
+ input.consume();
+
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;}
+
+
+ }
+ break;
+
+ default :
+ break loop1;
+ }
+ } while (true);
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "ID"
+
+ // $ANTLR start "INT"
+ public final void mINT() throws RecognitionException {
+ try {
+ int _type = INT;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:78:5: ( ( '-' )? ( '0' .. '9' )+ )
+ // src/reimann/Query.g:78:7: ( '-' )? ( '0' .. '9' )+
+ {
+ // src/reimann/Query.g:78:7: ( '-' )?
+ int alt2=2;
+ int LA2_0 = input.LA(1);
+
+ if ( (LA2_0=='-') ) {
+ alt2=1;
+ }
+ switch (alt2) {
+ case 1 :
+ // src/reimann/Query.g:78:7: '-'
+ {
+ match('-');
+
+ }
+ break;
+
+ }
+
+ // src/reimann/Query.g:78:12: ( '0' .. '9' )+
+ int cnt3=0;
+ loop3:
+ do {
+ int alt3=2;
+ int LA3_0 = input.LA(1);
+
+ if ( ((LA3_0>='0' && LA3_0<='9')) ) {
+ alt3=1;
+ }
+
+
+ switch (alt3) {
+ case 1 :
+ // src/reimann/Query.g:78:12: '0' .. '9'
+ {
+ matchRange('0','9');
+
+ }
+ break;
+
+ default :
+ if ( cnt3 >= 1 ) break loop3;
+ EarlyExitException eee =
+ new EarlyExitException(3, input);
+ throw eee;
+ }
+ cnt3++;
+ } while (true);
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "INT"
+
+ // $ANTLR start "FLOAT"
+ public final void mFLOAT() throws RecognitionException {
+ try {
+ int _type = FLOAT;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:82:5: ( ( '-' )? ( '0' .. '9' )+ ( '.' ( '0' .. '9' )* )? ( EXPONENT )? )
+ // src/reimann/Query.g:82:9: ( '-' )? ( '0' .. '9' )+ ( '.' ( '0' .. '9' )* )? ( EXPONENT )?
+ {
+ // src/reimann/Query.g:82:9: ( '-' )?
+ int alt4=2;
+ int LA4_0 = input.LA(1);
+
+ if ( (LA4_0=='-') ) {
+ alt4=1;
+ }
+ switch (alt4) {
+ case 1 :
+ // src/reimann/Query.g:82:9: '-'
+ {
+ match('-');
+
+ }
+ break;
+
+ }
+
+ // src/reimann/Query.g:82:14: ( '0' .. '9' )+
+ int cnt5=0;
+ loop5:
+ do {
+ int alt5=2;
+ int LA5_0 = input.LA(1);
+
+ if ( ((LA5_0>='0' && LA5_0<='9')) ) {
+ alt5=1;
+ }
+
+
+ switch (alt5) {
+ case 1 :
+ // src/reimann/Query.g:82:15: '0' .. '9'
+ {
+ matchRange('0','9');
+
+ }
+ break;
+
+ default :
+ if ( cnt5 >= 1 ) break loop5;
+ EarlyExitException eee =
+ new EarlyExitException(5, input);
+ throw eee;
+ }
+ cnt5++;
+ } while (true);
+
+ // src/reimann/Query.g:82:26: ( '.' ( '0' .. '9' )* )?
+ int alt7=2;
+ int LA7_0 = input.LA(1);
+
+ if ( (LA7_0=='.') ) {
+ alt7=1;
+ }
+ switch (alt7) {
+ case 1 :
+ // src/reimann/Query.g:82:27: '.' ( '0' .. '9' )*
+ {
+ match('.');
+ // src/reimann/Query.g:82:31: ( '0' .. '9' )*
+ loop6:
+ do {
+ int alt6=2;
+ int LA6_0 = input.LA(1);
+
+ if ( ((LA6_0>='0' && LA6_0<='9')) ) {
+ alt6=1;
+ }
+
+
+ switch (alt6) {
+ case 1 :
+ // src/reimann/Query.g:82:32: '0' .. '9'
+ {
+ matchRange('0','9');
+
+ }
+ break;
+
+ default :
+ break loop6;
+ }
+ } while (true);
+
+
+ }
+ break;
+
+ }
+
+ // src/reimann/Query.g:82:45: ( EXPONENT )?
+ int alt8=2;
+ int LA8_0 = input.LA(1);
+
+ if ( (LA8_0=='E'||LA8_0=='e') ) {
+ alt8=1;
+ }
+ switch (alt8) {
+ case 1 :
+ // src/reimann/Query.g:82:45: EXPONENT
+ {
+ mEXPONENT();
+
+ }
+ break;
+
+ }
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "FLOAT"
+
+ // $ANTLR start "WS"
+ public final void mWS() throws RecognitionException {
+ try {
+ int _type = WS;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:85:5: ( ( ' ' | '\\t' | '\\r' | '\\n' ) )
+ // src/reimann/Query.g:85:9: ( ' ' | '\\t' | '\\r' | '\\n' )
+ {
+ if ( (input.LA(1)>='\t' && input.LA(1)<='\n')||input.LA(1)=='\r'||input.LA(1)==' ' ) {
+ input.consume();
+
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;}
+
+ _channel=HIDDEN;
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "WS"
+
+ // $ANTLR start "EXPONENT"
+ public final void mEXPONENT() throws RecognitionException {
+ try {
+ // src/reimann/Query.g:93:10: ( ( 'e' | 'E' ) ( '+' | '-' )? ( '0' .. '9' )+ )
+ // src/reimann/Query.g:93:12: ( 'e' | 'E' ) ( '+' | '-' )? ( '0' .. '9' )+
+ {
+ if ( input.LA(1)=='E'||input.LA(1)=='e' ) {
+ input.consume();
+
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;}
+
+ // src/reimann/Query.g:93:22: ( '+' | '-' )?
+ int alt9=2;
+ int LA9_0 = input.LA(1);
+
+ if ( (LA9_0=='+'||LA9_0=='-') ) {
+ alt9=1;
+ }
+ switch (alt9) {
+ case 1 :
+ // src/reimann/Query.g:
+ {
+ if ( input.LA(1)=='+'||input.LA(1)=='-' ) {
+ input.consume();
+
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;}
+
+
+ }
+ break;
+
+ }
+
+ // src/reimann/Query.g:93:33: ( '0' .. '9' )+
+ int cnt10=0;
+ loop10:
+ do {
+ int alt10=2;
+ int LA10_0 = input.LA(1);
+
+ if ( ((LA10_0>='0' && LA10_0<='9')) ) {
+ alt10=1;
+ }
+
+
+ switch (alt10) {
+ case 1 :
+ // src/reimann/Query.g:93:34: '0' .. '9'
+ {
+ matchRange('0','9');
+
+ }
+ break;
+
+ default :
+ if ( cnt10 >= 1 ) break loop10;
+ EarlyExitException eee =
+ new EarlyExitException(10, input);
+ throw eee;
+ }
+ cnt10++;
+ } while (true);
+
+
+ }
+
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "EXPONENT"
+
+ // $ANTLR start "String"
+ public final void mString() throws RecognitionException {
+ try {
+ int _type = String;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // src/reimann/Query.g:95:9: ( '\"' ( EscapeSequence | ~ ( '\\u0000' .. '\\u001f' | '\\\\' | '\\\"' ) )* '\"' )
+ // src/reimann/Query.g:98:5: '\"' ( EscapeSequence | ~ ( '\\u0000' .. '\\u001f' | '\\\\' | '\\\"' ) )* '\"'
+ {
+ match('\"');
+ // src/reimann/Query.g:98:9: ( EscapeSequence | ~ ( '\\u0000' .. '\\u001f' | '\\\\' | '\\\"' ) )*
+ loop11:
+ do {
+ int alt11=3;
+ int LA11_0 = input.LA(1);
+
+ if ( (LA11_0=='\\') ) {
+ alt11=1;
+ }
+ else if ( ((LA11_0>=' ' && LA11_0<='!')||(LA11_0>='#' && LA11_0<='[')||(LA11_0>=']' && LA11_0<='\uFFFF')) ) {
+ alt11=2;
+ }
+
+
+ switch (alt11) {
+ case 1 :
+ // src/reimann/Query.g:98:11: EscapeSequence
+ {
+ mEscapeSequence();
+
+ }
+ break;
+ case 2 :
+ // src/reimann/Query.g:98:28: ~ ( '\\u0000' .. '\\u001f' | '\\\\' | '\\\"' )
+ {
+ if ( (input.LA(1)>=' ' && input.LA(1)<='!')||(input.LA(1)>='#' && input.LA(1)<='[')||(input.LA(1)>=']' && input.LA(1)<='\uFFFF') ) {
+ input.consume();
+
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;}
+
+
+ }
+ break;
+
+ default :
+ break loop11;
+ }
+ } while (true);
+
+ match('\"');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "String"
+
+ // $ANTLR start "EscapeSequence"
+ public final void mEscapeSequence() throws RecognitionException {
+ try {
+ // src/reimann/Query.g:102:9: ( '\\\\' ( UnicodeEscape | 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\\\' ) )
+ // src/reimann/Query.g:102:13: '\\\\' ( UnicodeEscape | 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\\\' )
+ {
+ match('\\');
+ // src/reimann/Query.g:102:18: ( UnicodeEscape | 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\\\' )
+ int alt12=8;
+ switch ( input.LA(1) ) {
+ case 'u':
+ {
+ alt12=1;
+ }
+ break;
+ case 'b':
+ {
+ alt12=2;
+ }
+ break;
+ case 't':
+ {
+ alt12=3;
+ }
+ break;
+ case 'n':
+ {
+ alt12=4;
+ }
+ break;
+ case 'f':
+ {
+ alt12=5;
+ }
+ break;
+ case 'r':
+ {
+ alt12=6;
+ }
+ break;
+ case '\"':
+ {
+ alt12=7;
+ }
+ break;
+ case '\\':
+ {
+ alt12=8;
+ }
+ break;
+ default:
+ NoViableAltException nvae =
+ new NoViableAltException("", 12, 0, input);
+
+ throw nvae;
+ }
+
+ switch (alt12) {
+ case 1 :
+ // src/reimann/Query.g:102:19: UnicodeEscape
+ {
+ mUnicodeEscape();
+
+ }
+ break;
+ case 2 :
+ // src/reimann/Query.g:102:34: 'b'
+ {
+ match('b');
+
+ }
+ break;
+ case 3 :
+ // src/reimann/Query.g:102:38: 't'
+ {
+ match('t');
+
+ }
+ break;
+ case 4 :
+ // src/reimann/Query.g:102:42: 'n'
+ {
+ match('n');
+
+ }
+ break;
+ case 5 :
+ // src/reimann/Query.g:102:46: 'f'
+ {
+ match('f');
+
+ }
+ break;
+ case 6 :
+ // src/reimann/Query.g:102:50: 'r'
+ {
+ match('r');
+
+ }
+ break;
+ case 7 :
+ // src/reimann/Query.g:102:54: '\\\"'
+ {
+ match('\"');
+
+ }
+ break;
+ case 8 :
+ // src/reimann/Query.g:102:59: '\\\\'
+ {
+ match('\\');
+
+ }
+ break;
+
+ }
+
+
+ }
+
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "EscapeSequence"
+
+ // $ANTLR start "UnicodeEscape"
+ public final void mUnicodeEscape() throws RecognitionException {
+ try {
+ // src/reimann/Query.g:106:5: ( 'u' HexDigit HexDigit HexDigit HexDigit )
+ // src/reimann/Query.g:106:7: 'u' HexDigit HexDigit HexDigit HexDigit
+ {
+ match('u');
+ mHexDigit();
+ mHexDigit();
+ mHexDigit();
+ mHexDigit();
+
+ }
+
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "UnicodeEscape"
+
+ // $ANTLR start "HexDigit"
+ public final void mHexDigit() throws RecognitionException {
+ try {
+ // src/reimann/Query.g:110:5: ( '0' .. '9' | 'A' .. 'F' | 'a' .. 'f' )
+ // src/reimann/Query.g:
+ {
+ if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='A' && input.LA(1)<='F')||(input.LA(1)>='a' && input.LA(1)<='f') ) {
+ input.consume();
+
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;}
+
+
+ }
+
+ }
+ finally {
+ }
+ }
+ // $ANTLR end "HexDigit"
+
+ public void mTokens() throws RecognitionException {
+ // src/reimann/Query.g:1:8: ( AND | OR | NOT | APPROXIMATELY | NOT_EQUAL | EQUAL | LESSER | LESSER_EQUAL | GREATER | GREATER_EQUAL | T__23 | T__24 | T__25 | T__26 | T__27 | T__28 | T__29 | T__30 | T__31 | T__32 | T__33 | T__34 | ID | INT | FLOAT | WS | String )
+ int alt13=27;
+ alt13 = dfa13.predict(input);
+ switch (alt13) {
+ case 1 :
+ // src/reimann/Query.g:1:10: AND
+ {
+ mAND();
+
+ }
+ break;
+ case 2 :
+ // src/reimann/Query.g:1:14: OR
+ {
+ mOR();
+
+ }
+ break;
+ case 3 :
+ // src/reimann/Query.g:1:17: NOT
+ {
+ mNOT();
+
+ }
+ break;
+ case 4 :
+ // src/reimann/Query.g:1:21: APPROXIMATELY
+ {
+ mAPPROXIMATELY();
+
+ }
+ break;
+ case 5 :
+ // src/reimann/Query.g:1:35: NOT_EQUAL
+ {
+ mNOT_EQUAL();
+
+ }
+ break;
+ case 6 :
+ // src/reimann/Query.g:1:45: EQUAL
+ {
+ mEQUAL();
+
+ }
+ break;
+ case 7 :
+ // src/reimann/Query.g:1:51: LESSER
+ {
+ mLESSER();
+
+ }
+ break;
+ case 8 :
+ // src/reimann/Query.g:1:58: LESSER_EQUAL
+ {
+ mLESSER_EQUAL();
+
+ }
+ break;
+ case 9 :
+ // src/reimann/Query.g:1:71: GREATER
+ {
+ mGREATER();
+
+ }
+ break;
+ case 10 :
+ // src/reimann/Query.g:1:79: GREATER_EQUAL
+ {
+ mGREATER_EQUAL();
+
+ }
+ break;
+ case 11 :
+ // src/reimann/Query.g:1:93: T__23
+ {
+ mT__23();
+
+ }
+ break;
+ case 12 :
+ // src/reimann/Query.g:1:99: T__24
+ {
+ mT__24();
+
+ }
+ break;
+ case 13 :
+ // src/reimann/Query.g:1:105: T__25
+ {
+ mT__25();
+
+ }
+ break;
+ case 14 :
+ // src/reimann/Query.g:1:111: T__26
+ {
+ mT__26();
+
+ }
+ break;
+ case 15 :
+ // src/reimann/Query.g:1:117: T__27
+ {
+ mT__27();
+
+ }
+ break;
+ case 16 :
+ // src/reimann/Query.g:1:123: T__28
+ {
+ mT__28();
+
+ }
+ break;
+ case 17 :
+ // src/reimann/Query.g:1:129: T__29
+ {
+ mT__29();
+
+ }
+ break;
+ case 18 :
+ // src/reimann/Query.g:1:135: T__30
+ {
+ mT__30();
+
+ }
+ break;
+ case 19 :
+ // src/reimann/Query.g:1:141: T__31
+ {
+ mT__31();
+
+ }
+ break;
+ case 20 :
+ // src/reimann/Query.g:1:147: T__32
+ {
+ mT__32();
+
+ }
+ break;
+ case 21 :
+ // src/reimann/Query.g:1:153: T__33
+ {
+ mT__33();
+
+ }
+ break;
+ case 22 :
+ // src/reimann/Query.g:1:159: T__34
+ {
+ mT__34();
+
+ }
+ break;
+ case 23 :
+ // src/reimann/Query.g:1:165: ID
+ {
+ mID();
+
+ }
+ break;
+ case 24 :
+ // src/reimann/Query.g:1:168: INT
+ {
+ mINT();
+
+ }
+ break;
+ case 25 :
+ // src/reimann/Query.g:1:172: FLOAT
+ {
+ mFLOAT();
+
+ }
+ break;
+ case 26 :
+ // src/reimann/Query.g:1:178: WS
+ {
+ mWS();
+
+ }
+ break;
+ case 27 :
+ // src/reimann/Query.g:1:181: String
+ {
+ mString();
+
+ }
+ break;
+
+ }
+
+ }
+
+
+ protected DFA13 dfa13 = new DFA13(this);
+ static final String DFA13_eotS =
+ "\1\uffff\3\20\1\33\1\uffff\1\35\1\37\2\uffff\6\20\2\uffff\1\50\2"+
+ "\uffff\1\20\1\53\3\20\6\uffff\10\20\2\uffff\1\67\1\uffff\1\70\1"+
+ "\20\1\72\10\20\2\uffff\1\103\1\uffff\1\104\1\105\1\20\1\107\4\20"+
+ "\3\uffff\1\114\1\uffff\1\20\1\116\2\20\1\uffff\1\20\1\uffff\2\20"+
+ "\1\124\2\20\1\uffff\1\20\1\130\1\20\1\uffff\1\20\1\133\1\uffff";
+ static final String DFA13_eofS =
+ "\134\uffff";
+ static final String DFA13_minS =
+ "\1\11\1\156\1\162\1\151\1\176\1\uffff\2\75\2\uffff\1\151\1\141\1"+
+ "\157\3\145\1\uffff\1\60\1\56\2\uffff\1\144\1\60\1\164\2\154\6\uffff"+
+ "\1\165\1\155\1\154\1\163\1\162\1\141\1\163\1\164\2\uffff\1\60\1"+
+ "\uffff\1\60\1\154\1\60\2\145\1\163\1\164\1\166\1\164\1\143\1\162"+
+ "\2\uffff\1\60\1\uffff\2\60\1\145\1\60\1\151\1\145\1\162\1\151\3"+
+ "\uffff\1\60\1\uffff\1\143\1\60\1\151\1\143\1\uffff\1\145\1\uffff"+
+ "\1\160\1\137\1\60\1\164\1\146\1\uffff\1\151\1\60\1\157\1\uffff\1"+
+ "\156\1\60\1\uffff";
+ static final String DFA13_maxS =
+ "\1\172\1\156\1\162\1\165\1\176\1\uffff\2\75\2\uffff\1\162\1\141"+
+ "\1\157\1\164\2\145\1\uffff\1\71\1\145\2\uffff\1\144\1\172\1\164"+
+ "\2\154\6\uffff\1\165\1\155\1\154\1\163\1\162\1\141\1\163\1\164\2"+
+ "\uffff\1\172\1\uffff\1\172\1\154\1\172\2\145\1\163\1\164\1\166\1"+
+ "\164\1\143\1\162\2\uffff\1\172\1\uffff\2\172\1\145\1\172\1\151\1"+
+ "\145\1\162\1\151\3\uffff\1\172\1\uffff\1\143\1\172\1\151\1\143\1"+
+ "\uffff\1\145\1\uffff\1\160\1\137\1\172\1\164\1\146\1\uffff\1\151"+
+ "\1\172\1\157\1\uffff\1\156\1\172\1\uffff";
+ static final String DFA13_acceptS =
+ "\5\uffff\1\5\2\uffff\1\13\1\14\6\uffff\1\27\2\uffff\1\32\1\33\5"+
+ "\uffff\1\4\1\6\1\10\1\7\1\12\1\11\10\uffff\1\30\1\31\1\uffff\1\2"+
+ "\13\uffff\1\1\1\3\1\uffff\1\20\10\uffff\1\17\1\15\1\26\1\uffff\1"+
+ "\21\4\uffff\1\16\1\uffff\1\23\5\uffff\1\22\3\uffff\1\25\2\uffff"+
+ "\1\24";
+ static final String DFA13_specialS =
+ "\134\uffff}>";
+ static final String[] DFA13_transitionS = {
+ "\2\23\2\uffff\1\23\22\uffff\1\23\1\5\1\24\5\uffff\1\10\1\11"+
+ "\3\uffff\1\21\2\uffff\12\22\2\uffff\1\6\1\4\1\7\2\uffff\32\20"+
+ "\4\uffff\1\20\1\uffff\1\1\2\20\1\16\1\20\1\13\1\20\1\14\4\20"+
+ "\1\17\1\3\1\2\3\20\1\15\1\12\6\20",
+ "\1\25",
+ "\1\26",
+ "\1\31\5\uffff\1\27\5\uffff\1\30",
+ "\1\32",
+ "",
+ "\1\34",
+ "\1\36",
+ "",
+ "",
+ "\1\41\10\uffff\1\40",
+ "\1\42",
+ "\1\43",
+ "\1\44\16\uffff\1\45",
+ "\1\46",
+ "\1\47",
+ "",
+ "\12\22",
+ "\1\51\1\uffff\12\22\13\uffff\1\51\37\uffff\1\51",
+ "",
+ "",
+ "\1\52",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "\1\54",
+ "\1\55",
+ "\1\56",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "\1\57",
+ "\1\60",
+ "\1\61",
+ "\1\62",
+ "\1\63",
+ "\1\64",
+ "\1\65",
+ "\1\66",
+ "",
+ "",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "\1\71",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "\1\73",
+ "\1\74",
+ "\1\75",
+ "\1\76",
+ "\1\77",
+ "\1\100",
+ "\1\101",
+ "\1\102",
+ "",
+ "",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "\1\106",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "\1\110",
+ "\1\111",
+ "\1\112",
+ "\1\113",
+ "",
+ "",
+ "",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "",
+ "\1\115",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "\1\117",
+ "\1\120",
+ "",
+ "\1\121",
+ "",
+ "\1\122",
+ "\1\123",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "\1\125",
+ "\1\126",
+ "",
+ "\1\127",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ "\1\131",
+ "",
+ "\1\132",
+ "\12\20\7\uffff\32\20\4\uffff\1\20\1\uffff\32\20",
+ ""
+ };
+
+ static final short[] DFA13_eot = DFA.unpackEncodedString(DFA13_eotS);
+ static final short[] DFA13_eof = DFA.unpackEncodedString(DFA13_eofS);
+ static final char[] DFA13_min = DFA.unpackEncodedStringToUnsignedChars(DFA13_minS);
+ static final char[] DFA13_max = DFA.unpackEncodedStringToUnsignedChars(DFA13_maxS);
+ static final short[] DFA13_accept = DFA.unpackEncodedString(DFA13_acceptS);
+ static final short[] DFA13_special = DFA.unpackEncodedString(DFA13_specialS);
+ static final short[][] DFA13_transition;
+
+ static {
+ int numStates = DFA13_transitionS.length;
+ DFA13_transition = new short[numStates][];
+ for (int i=0; i<numStates; i++) {
+ DFA13_transition[i] = DFA.unpackEncodedString(DFA13_transitionS[i]);
+ }
+ }
+
+ class DFA13 extends DFA {
+
+ public DFA13(BaseRecognizer recognizer) {
+ this.recognizer = recognizer;
+ this.decisionNumber = 13;
+ this.eot = DFA13_eot;
+ this.eof = DFA13_eof;
+ this.min = DFA13_min;
+ this.max = DFA13_max;
+ this.accept = DFA13_accept;
+ this.special = DFA13_special;
+ this.transition = DFA13_transition;
+ }
+ public String getDescription() {
+ return "1:1: Tokens : ( AND | OR | NOT | APPROXIMATELY | NOT_EQUAL | EQUAL | LESSER | LESSER_EQUAL | GREATER | GREATER_EQUAL | T__23 | T__24 | T__25 | T__26 | T__27 | T__28 | T__29 | T__30 | T__31 | T__32 | T__33 | T__34 | ID | INT | FLOAT | WS | String );";
+ }
+ }
+
+
+}
2,426 src/reimann/QueryParser.java
@@ -0,0 +1,2426 @@
+// $ANTLR 3.2 Sep 23, 2009 14:05:07 src/reimann/Query.g 2012-02-07 15:10:23
+package reimann;
+
+import org.antlr.runtime.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+
+
+import org.antlr.runtime.tree.*;
+
+public class QueryParser extends Parser {
+ public static final String[] tokenNames = new String[] {
+ "<invalid>", "<EOR>", "<DOWN>", "<UP>", "AND", "OR", "NOT", "APPROXIMATELY", "NOT_EQUAL", "EQUAL", "LESSER", "LESSER_EQUAL", "GREATER", "GREATER_EQUAL", "WS", "String", "INT", "FLOAT", "ID", "EXPONENT", "EscapeSequence", "UnicodeEscape", "HexDigit", "'('", "')'", "'true'", "'false'", "'null'", "'nil'", "'host'", "'service'", "'state'", "'description'", "'metric_f'", "'time'"
+ };
+ public static final int LESSER_EQUAL=11;
+ public static final int EXPONENT=19;
+ public static final int T__29=29;
+ public static final int T__28=28;
+ public static final int T__27=27;
+ public static final int T__26=26;
+ public static final int T__25=25;
+ public static final int T__24=24;
+ public static final int T__23=23;
+ public static final int APPROXIMATELY=7;
+ public static final int FLOAT=17;
+ public static final int INT=16;
+ public static final int NOT=6;
+ public static final int ID=18;
+ public static final int AND=4;
+ public static final int EOF=-1;
+ public static final int HexDigit=22;
+ public static final int T__30=30;
+ public static final int T__31=31;
+ public static final int T__32=32;
+ public static final int WS=14;
+ public static final int GREATER=12;
+ public static final int LESSER=10;
+ public static final int T__33=33;
+ public static final int T__34=34;
+ public static final int NOT_EQUAL=8;
+ public static final int UnicodeEscape=21;
+ public static final int EQUAL=9;
+ public static final int OR=5;
+ public static final int String=15;
+ public static final int EscapeSequence=20;
+ public static final int GREATER_EQUAL=13;
+
+ // delegates
+ // delegators
+
+
+ public QueryParser(TokenStream input) {
+ this(input, new RecognizerSharedState());
+ }
+ public QueryParser(TokenStream input, RecognizerSharedState state) {
+ super(input, state);
+
+ }
+
+ protected TreeAdaptor adaptor = new CommonTreeAdaptor();
+
+ public void setTreeAdaptor(TreeAdaptor adaptor) {
+ this.adaptor = adaptor;
+ }
+ public TreeAdaptor getTreeAdaptor() {