// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. /** * @author tonyv */ options { LOOKAHEAD = 1; STATIC = false; UNICODE_INPUT = true; } PARSER_BEGIN(Parser) package com.yahoo.search.query.textserialize.parser; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.LinkedHashMap; public class Parser { private DispatchFormHandler dispatchFormHandler; private Object dispatchContext; public Parser(java.io.Reader stream, DispatchFormHandler dispatchFormHandler, Object dispatchContext) { this(stream); this.dispatchFormHandler = dispatchFormHandler; this.dispatchContext = dispatchContext; } private static String parseString(String in) { return stripEnclosingQuotes( in.replace("\\\\", "\\").replace("\\\"", "\"")); } private static String stripEnclosingQuotes(String in) { return in.substring(1, in.length() - 1); } } PARSER_END(Parser) Object start(): { final Object result; } { result = form() { return result; } } Object form(): { final Object result; } { ( result = dispatchForm() | result = map() | result = array() | result = literal() ) { return result; } } Object literal(): { final Object result; } { ( result = string() | result = number() | result = bool() | result = null_() ) { return result; } } String string(): { Token t; } { t = { return parseString(t.image); } } Double number(): { Token t; } { t = { return Double.valueOf(t.image); } } Boolean bool(): { Token t; } { t = { if ("on".equals(t.image)) return true; return Boolean.valueOf(t.image); } } Object null_(): {} { { return null; } } Map map(): { Object key, value; Map result = new LinkedHashMap(); } { ( key = form() value = form() { result.put(key, value); } )* { return result; } } Object dispatchForm(): { Token symbol; List arguments; } { symbol = arguments = forms() { return dispatchFormHandler.dispatch(symbol.image, arguments, dispatchContext); } } List forms(): { Object value; List results = new ArrayList(); } { ( value = form() { results.add(value); } )* { return results; } } List array(): { List result; } { result = forms() { return result; } } SKIP : { " " | "\n" | "\r" | "\t" | "\f" | "," } TOKEN : { < OPEN_PAREN: "(" > } TOKEN : { < CLOSE_PAREN: ")" > } TOKEN : { < OPEN_CURLY: "{" > } TOKEN : { < CLOSE_CURLY: "}" > } TOKEN : { < OPEN_SQUARE: "[" > } TOKEN : { < CLOSE_SQUARE: "]" > } TOKEN : { } TOKEN : { } TOKEN : { < STRING: ()* > } TOKEN : { < #STRING_CHARACTER: "\\\\" | "\\\"" | ~["\"", "\\"] > } TOKEN : { < #QUOTE: "\"" > } TOKEN : { < NUMBER: ()? ()+ ("." ()*)? ()? > } TOKEN : { < #EXPONENT: ["e", "E"] ()? ()+ > } TOKEN : { < #SIGN: ["+", "-"] >} TOKEN : { < #DIGIT: ["0" - "9"] > } TOKEN : { < SYMBOL: ()* > } TOKEN : { < #SYMBOL_FIRST: ["a"-"z"] | ["A"-"Z"] | "+" | "-" | "*" | "/" | "!" | "?" | "-" | "_" | "=" | ">" | "<" > } TOKEN : { < #SYMBOL_REST: | ["0" - "9"] | "." > }