// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ebnf

import (
	"container/vector";
	"go/scanner";
	"go/token";
	"os";
	"strconv";
)


type parser struct {
	scanner.ErrorVector;
	scanner	scanner.Scanner;
	pos	token.Position;	// token position
	tok	token.Token;	// one token look-ahead
	lit	[]byte;		// token literal
}


func (p *parser) next() {
	p.pos, p.tok, p.lit = p.scanner.Scan();
	if p.tok.IsKeyword() {
		// TODO Should keyword mapping always happen outside scanner?
		//      Or should there be a flag to scanner to enable keyword mapping?
		p.tok = token.IDENT
	}
}


func (p *parser) errorExpected(pos token.Position, msg string) {
	msg = "expected " + msg;
	if pos.Offset == p.pos.Offset {
		// the error happened at the current position;
		// make the error message more specific
		msg += ", found '" + p.tok.String() + "'";
		if p.tok.IsLiteral() {
			msg += " " + string(p.lit)
		}
	}
	p.Error(pos, msg);
}


func (p *parser) expect(tok token.Token) token.Position {
	pos := p.pos;
	if p.tok != tok {
		p.errorExpected(pos, "'"+tok.String()+"'")
	}
	p.next();	// make progress in any case
	return pos;
}


func (p *parser) parseIdentifier() *Name {
	pos := p.pos;
	name := string(p.lit);
	p.expect(token.IDENT);
	return &Name{pos, name};
}


func (p *parser) parseToken() *Token {
	pos := p.pos;
	value := "";
	if p.tok == token.STRING {
		value, _ = strconv.Unquote(string(p.lit));
		// Unquote may fail with an error, but only if the scanner found
		// an illegal string in the first place. In this case the error
		// has already been reported.
		p.next();
	} else {
		p.expect(token.STRING)
	}
	return &Token{pos, value};
}


func (p *parser) parseTerm() (x Expression) {
	pos := p.pos;

	switch p.tok {
	case token.IDENT:
		x = p.parseIdentifier()

	case token.STRING:
		tok := p.parseToken();
		x = tok;
		if p.tok == token.ELLIPSIS {
			p.next();
			x = &Range{tok, p.parseToken()};
		}

	case token.LPAREN:
		p.next();
		x = &Group{pos, p.parseExpression()};
		p.expect(token.RPAREN);

	case token.LBRACK:
		p.next();
		x = &Option{pos, p.parseExpression()};
		p.expect(token.RBRACK);

	case token.LBRACE:
		p.next();
		x = &Repetition{pos, p.parseExpression()};
		p.expect(token.RBRACE);
	}

	return x;
}


func (p *parser) parseSequence() Expression {
	var list vector.Vector;

	for x := p.parseTerm(); x != nil; x = p.parseTerm() {
		list.Push(x)
	}

	// no need for a sequence if list.Len() < 2
	switch list.Len() {
	case 0:
		return nil
	case 1:
		return list.At(0).(Expression)
	}

	// convert list into a sequence
	seq := make(Sequence, list.Len());
	for i := 0; i < list.Len(); i++ {
		seq[i] = list.At(i).(Expression)
	}
	return seq;
}


func (p *parser) parseExpression() Expression {
	var list vector.Vector;

	for {
		x := p.parseSequence();
		if x != nil {
			list.Push(x)
		}
		if p.tok != token.OR {
			break
		}
		p.next();
	}

	// no need for an Alternative node if list.Len() < 2
	switch list.Len() {
	case 0:
		return nil
	case 1:
		return list.At(0).(Expression)
	}

	// convert list into an Alternative node
	alt := make(Alternative, list.Len());
	for i := 0; i < list.Len(); i++ {
		alt[i] = list.At(i).(Expression)
	}
	return alt;
}


func (p *parser) parseProduction() *Production {
	name := p.parseIdentifier();
	p.expect(token.ASSIGN);
	expr := p.parseExpression();
	p.expect(token.PERIOD);
	return &Production{name, expr};
}


func (p *parser) parse(filename string, src []byte) Grammar {
	// initialize parser
	p.ErrorVector.Reset();
	p.scanner.Init(filename, src, p, 0);
	p.next();	// initializes pos, tok, lit

	grammar := make(Grammar);
	for p.tok != token.EOF {
		prod := p.parseProduction();
		name := prod.Name.String;
		if _, found := grammar[name]; !found {
			grammar[name] = prod
		} else {
			p.Error(prod.Pos(), name+" declared already")
		}
	}

	return grammar;
}


// Parse parses a set of EBNF productions from source src.
// It returns a set of productions. Errors are reported
// for incorrect syntax and if a production is declared
// more than once.
//
func Parse(filename string, src []byte) (Grammar, os.Error) {
	var p parser;
	grammar := p.parse(filename, src);
	return grammar, p.GetError(scanner.Sorted);
}
