/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

options {
    IGNORE_CASE = true;
    STATIC = false;
    UNICODE_INPUT=true;
}

PARSER_BEGIN(CommentParser)
package org.apache.kylin.query.util;
import java.io.StringReader;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CommentParser {

    private final static Logger logger = LoggerFactory.getLogger(CommentParser.class);


    public static void main(String args[]) throws ParseException {
        System.out.println("Input SQL:");
        Scanner reader = new Scanner(System.in, "UTF-8");
        String sql = reader.nextLine();
        reader.close();
        CommentParser parser = new CommentParser(new StringReader(sql));
        String parseResult = parser.Input();
        System.out.println("Translated SQL:");
        System.out.println(parseResult);
    }

    public CommentParser(String sql) {
        this(new StringReader(sql));
    }
}

PARSER_END(CommentParser)

//< DEFAULT, ESCAPE, FUNCTION >
//SKIP :
//{
//  "\t"
//| "\n"
//| "\r"
//}

<DEFAULT>
SKIP : {
    <"--" (~["\n","\r"])*>
}

<DEFAULT>
SKIP :
{
    "/**/"
    | <"/*" ~["+"]> : WITHINCOMMENT
}

< DEFAULT >
TOKEN :
{
 < REMAIN_TOKEN : [" ", "\t","\n", "\r", ",", "/", "-" ] >
| < QUOTE: "'" >
| < QUOTED_STRING: <QUOTE> ( (~["'"]) | ("''"))* <QUOTE> >
| < DOUBLE_QUOTE: "\"" >
| < DOUBLE_QUOTE_STRING: <DOUBLE_QUOTE> ( (~["\""]) | ("\"\""))* <DOUBLE_QUOTE> >
| < ANY : (~[" ", ",", "\t", "\n", "\r", "/", "-" ])+ >
| < HINT_BEG: "/*+" >
| < COMMENT_END: "*/" >
| < HINT: <HINT_BEG> (~["\n", "\r", "*", "/"])* <COMMENT_END> >
}

<WITHINCOMMENT>
SKIP :
{
  "*/" : DEFAULT
}

<WITHINCOMMENT>
MORE :
{
  < ~[] >
}

/** Root production. */
String Input() :
{
    String innerString;
    StringBuilder transformedStr = new StringBuilder();
}
{
    (
    LOOKAHEAD(2)
    innerString = Expression()
    {
        transformedStr.append(innerString);
    }
    )+
    <EOF>
    {
        return transformedStr.toString();
    }
}

/** Brace counting production. */
String Expression() :
{
    String innerString = "";
    String nextString = "";
}
{
    {
        if (Thread.currentThread().isInterrupted()) {
            throw new ParseException("CommentParser is interrupted");
        }
    }
    (
     innerString = QuotedString()
    | innerString = DoubleQuoteString()
    | innerString = RemainToken()
    | innerString = Any()
    | innerString = Hint()
    )
    {
        return innerString + nextString;
    }
}

String Hint():
{}
{
    <HINT>
    {
        logger.trace("meet token <HINT>");
        return getToken(0).image;
    }
}

String RemainToken() :
{}
{
    < REMAIN_TOKEN >
    {
        logger.trace("meet token <REMAIN_TOKEN>");
        return getToken(0).image;
    }
}

String QuotedString() :
{
    String s;
}
{
    <QUOTED_STRING>
    {
        logger.trace("meet token in <QUOTED_STRING>: " + getToken(0).image);
        return getToken(0).image;
    }
}

String DoubleQuoteString() :
{
    String s;
}
{
    <DOUBLE_QUOTE_STRING>
    {
        logger.trace("meet token in <QUOTED2_STRING>: " + getToken(0).image);
        return getToken(0).image;
    }
}

String Any() :
{}
{
    < ANY >
    {
        logger.trace("meet token in <ANY>: " + getToken(0).image);
        return getToken(0).image;
    }
}