/*
 * [The "BSD license"]
 *  Copyright (c) 2010 Terence Parr
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.antlr.tool;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/** Load a grammar file and scan it just until we learn a few items
 *  of interest.  Currently: name, type, imports, tokenVocab, language option.
 *
 *  GrammarScanner (at bottom of this class) converts grammar to stuff like:
 *
 *   grammar Java ; options { backtrack true memoize true }
 *   import JavaDecl JavaAnnotations JavaExpr ;
 *   ... : ...
 *
 *  First ':' or '@' indicates we can stop looking for imports/options.
 *
 *  Then we just grab interesting grammar properties.
 */
public class GrammarSpelunker {
    protected String grammarFileName;
    protected String token;
    protected Scanner scanner;

    // grammar info / properties
    protected String grammarModifier;
    protected String grammarName;
    protected String tokenVocab;
    protected String language = "Java"; // default
    protected String inputDirectory;
    protected List<String> importedGrammars;

    public GrammarSpelunker(String inputDirectory, String grammarFileName) {
        this.inputDirectory = inputDirectory;
        this.grammarFileName = grammarFileName;
    }

    void consume() throws IOException { token = scanner.nextToken(); }

    protected void match(String expecting) throws IOException {
        //System.out.println("match "+expecting+"; is "+token);
        if ( token.equals(expecting) ) consume();
        else throw new Error("Error parsing "+grammarFileName+": '"+token+
                             "' not expected '"+expecting+"'");
    }

    public void parse() throws IOException {
        Reader r = new FileReader((inputDirectory != null ? inputDirectory + File.separator : "") + grammarFileName);
        BufferedReader br = new BufferedReader(r);
        try {
            scanner = new Scanner(br);
            consume();
            grammarHeader();
            // scan until imports or options
            while ( token!=null && !token.equals("@") && !token.equals(":") &&
                    !token.equals("import") && !token.equals("options") )
            {
                consume();
            }
            if ( token.equals("options") ) options();
            // scan until options or first rule
            while ( token!=null && !token.equals("@") && !token.equals(":") &&
                    !token.equals("import") )
            {
                consume();
            }
            if ( token.equals("import") ) imports();
            // ignore rest of input; close up shop
        }
        finally {
            if ( br!=null ) br.close();
        }
    }

    protected void grammarHeader() throws IOException {
        if ( token==null ) return;
        if ( token.equals("tree") || token.equals("parser") || token.equals("lexer") ) {
            grammarModifier=token;
            consume();
        }
        match("grammar");
        grammarName = token;
        consume(); // move beyond name
    }

    // looks like "options { backtrack true ; tokenVocab MyTokens ; }"
    protected void options() throws IOException {
        match("options");
        match("{");
        while ( token!=null && !token.equals("}") ) {
            String name = token;
            consume();
            String value = token;
            consume();
            match(";");
            if ( name.equals("tokenVocab") ) tokenVocab = value;
            if ( name.equals("language") ) language = value;
        }
        match("}");
    }

    // looks like "import JavaDecl JavaAnnotations JavaExpr ;"
    protected void imports() throws IOException {
        match("import");
        importedGrammars = new ArrayList<String>();
        while ( token!=null && !token.equals(";") ) {
            importedGrammars.add(token);
            consume();
        }
        match(";");
        if ( importedGrammars.size()==0 ) importedGrammars = null;
    }

    public String getGrammarModifier() { return grammarModifier; }

    public String getGrammarName() { return grammarName; }

    public String getTokenVocab() { return tokenVocab; }

    public String getLanguage() { return language; }

    public List<String> getImportedGrammars() { return importedGrammars; }

    /** Strip comments and then return stream of words and
     *  tokens {';', ':', '{', '}'}
     */ 
    public static class Scanner {
        public static final int EOF = -1;
        Reader input;
        int c;

        public Scanner(Reader input) throws IOException {
            this.input = input;
            consume();
        }

        boolean isDIGIT() { return c>='0'&&c<='9'; }
        boolean isID_START() { return c>='a'&&c<='z' || c>='A'&&c<='Z'; }
        boolean isID_LETTER() { return isID_START() || c>='0'&&c<='9' || c=='_'; }
        
        void consume() throws IOException { c = input.read(); }

        public String nextToken() throws IOException {
            while ( c!=EOF ) {
                //System.out.println("check "+(char)c);
                switch ( c ) {
                    case ';' : consume(); return ";";
                    case '{' : consume(); return "{";
                    case '}' : consume(); return "}";
                    case ':' : consume(); return ":";
                    case '@' : consume(); return "@";
                    case '/' : COMMENT(); break;
                    case '\'': return STRING();
                    default:
                        if ( isID_START() ) return ID();
                        else if ( isDIGIT() ) return INT();
                        consume(); // ignore anything else
                }
            }
            return null;
        }

        /** NAME : LETTER+ ; // NAME is sequence of >=1 letter */
        String ID() throws IOException {
            StringBuffer buf = new StringBuffer();
            while ( c!=EOF && isID_LETTER() ) { buf.append((char)c); consume(); }
            return buf.toString();
        }

        String INT() throws IOException {
            StringBuffer buf = new StringBuffer();
            while ( c!=EOF && isDIGIT() ) { buf.append((char)c); consume(); }
            return buf.toString();
        }

        String STRING() throws IOException {
            StringBuffer buf = new StringBuffer();
            consume();
            while ( c!=EOF && c!='\'' ) {
                if ( c=='\\' ) {
                    buf.append((char)c);
                    consume();
                }
                buf.append((char)c);
                consume();
            }
            consume(); // scan past '
            return buf.toString();
        }

        void COMMENT() throws IOException {
            if ( c=='/' ) {
                consume();
                if ( c=='*' ) {
                    consume();
        scarf:
                    while ( true ) {
                        if ( c=='*' ) {
                            consume();
                            if ( c=='/' ) { consume(); break scarf; }
                        }
                        else {
                            while ( c!=EOF && c!='*' ) consume();
                        }
                    }
                }
                else if ( c=='/' ) {
                    while ( c!=EOF && c!='\n' ) consume();
                }
            }
        }
    }

    /** Tester; Give grammar filename as arg */
    public static void main(String[] args) throws IOException {
        GrammarSpelunker g = new GrammarSpelunker(".", args[0]);
        g.parse();
        System.out.println(g.grammarModifier+" grammar "+g.grammarName);
        System.out.println("language="+g.language);
        System.out.println("tokenVocab="+g.tokenVocab);
        System.out.println("imports="+g.importedGrammars);
    }
}
