summaryrefslogtreecommitdiffstats
path: root/parser.go
diff options
context:
space:
mode:
authorThibaut Horel <thibaut.horel@gmail.com>2016-03-15 22:12:44 -0400
committerThibaut Horel <thibaut.horel@gmail.com>2016-03-15 22:12:44 -0400
commit58011496071a49e8f5f916a0416c36806ee94614 (patch)
treec32bb04676b54ae0718fb68f97b984b970456628 /parser.go
parent9a5261e37badd5422b8c16d93a5b1663c4be602f (diff)
downloadbibtex-58011496071a49e8f5f916a0416c36806ee94614.tar.gz
Add crossref resolution, minor api changes, first template inspired by plain.bst
Diffstat (limited to 'parser.go')
-rw-r--r--parser.go49
1 files changed, 37 insertions, 12 deletions
diff --git a/parser.go b/parser.go
index b4a3ada..15e941d 100644
--- a/parser.go
+++ b/parser.go
@@ -48,11 +48,12 @@ func NewParser(r io.Reader) *parser {
default:
name = ""
}
- res := make(map[string]Value)
+ res := make(map[string]Value, len(strings))
for key, s := range strings {
- res[key] = []Literal{StringLiteral(s)}
+ res[key] = StringLiteral(s)
}
- db := &Database{Strings: res, Entries: make(map[string]Entry)}
+ db := &Database{Strings: res, Entries: make(map[string]Entry),
+ CrossRefs: make(map[string]int)}
return &parser{Reader: bufio.NewReader(r), lineno: 1, colno: 0,
fname: name, Database: db}
}
@@ -229,7 +230,7 @@ func (p *parser) readNumber() NumberLiteral {
return NumberLiteral(n)
}
-func (p *parser) readLiteral() Literal {
+func (p *parser) readLiteral() Value {
if ch := p.peek(); ch == '{' {
return p.readBraceLiteral()
} else if ch == '"' {
@@ -242,16 +243,18 @@ func (p *parser) readLiteral() Literal {
panic(p.NewError("Expected an identifier"))
}
if v, in := p.Strings[id]; in {
- return VariableLiteral{id, &v}
+ return VarLiteral{id, &v}
} else {
p.Warning(fmt.Sprintf("Unknown string %q", id))
- return VariableLiteral{id, &v}
+ l := Value(StringLiteral(""))
+ return VarLiteral{id, &l}
}
}
}
-func (p *parser) readValue() (res Value) {
+func (p *parser) readValue() Value {
var ch rune
+ var res LiteralList
res = append(res, p.readLiteral())
for {
p.eatSpace()
@@ -263,7 +266,11 @@ func (p *parser) readValue() (res Value) {
break
}
}
- return
+ if len(res) == 1 {
+ return res[0]
+ } else {
+ return res
+ }
}
func (p *parser) readIdValue() (string, Value) {
@@ -297,7 +304,8 @@ func (p *parser) readOpen() rune {
func (p *parser) readPreamble() {
close := p.readOpen()
p.eatSpace()
- p.Preamble = append(p.Preamble, p.readValue())
+ prb := p.Preamble.(LiteralList)
+ p.Preamble = append(prb, p.readValue())
p.eatSpace()
if ch := p.read(); ch != close {
p.unread()
@@ -323,6 +331,18 @@ func (p *parser) readString() {
}
}
+func (p *parser) checkCrossRef(id string, value Value) {
+ if id != "crossref" {
+ return
+ }
+ key := strings.ToLower(value.String())
+ if _, in := p.Entries[key]; in {
+ p.Warning(fmt.Sprintf("Crossreference %q defined before being used",
+ key))
+ }
+ p.CrossRefs[key] += 1
+}
+
func (p *parser) readEntry(t string) {
close := p.readOpen()
p.eatSpace()
@@ -332,10 +352,11 @@ func (p *parser) readEntry(t string) {
entry.Type = t
entry.Fields = make(map[string]Value)
key = strings.ToLower(key)
+ store := true
if _, in := p.Entries[key]; in {
p.Warning(fmt.Sprintf("Entry %q already defined, ignoring", key))
- return
+ store = false
}
for {
@@ -354,6 +375,7 @@ func (p *parser) readEntry(t string) {
p.Warning(fmt.Sprintf("Field %q already defined, ignoring",
id))
} else {
+ p.checkCrossRef(id, value)
entry.Fields[id] = value
entry.FNames = append(entry.FNames, id)
}
@@ -363,8 +385,11 @@ func (p *parser) readEntry(t string) {
panic(p.NewError(fmt.Sprintf("Expected ',' or %q", close)))
}
}
- p.Entries[key] = entry
- p.EKeys = append(p.EKeys, key)
+
+ if store {
+ p.Entries[key] = entry
+ p.EKeys = append(p.EKeys, key)
+ }
}
func (p *parser) readDeclaration() (err error) {