Skip to content

Commit

Permalink
Updated parser to take into account comments enclosed within single q…
Browse files Browse the repository at this point in the history
…uotes
  • Loading branch information
fredericlemoine committed Sep 13, 2023
1 parent 76f7e39 commit b7837b6
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 19 deletions.
2 changes: 2 additions & 0 deletions io/newick/newick_lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ func (s *Scanner) Scan() (tok Token, lit string) {
return OPENBRACK, string(ch)
case ']':
return CLOSEBRACK, string(ch)
case '\'':
return LABEL, string(ch)
case ',':
return NEWSIBLING, string(ch)
case ';':
Expand Down
10 changes: 6 additions & 4 deletions io/newick/newick_nodestack.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ func (ns *NodeStack) Push(n *tree.Node, e *tree.Edge) {
ns.elt = append(ns.elt, nodeStackElt{n, e})
}

/**
/*
*
Pops and returns the head of the Stack. The calling function is
responsible for freeing the elt: free(elt).
Expand All @@ -36,7 +37,7 @@ Returns an error if the stack is empty
func (ns *NodeStack) Pop() (n *tree.Node, e *tree.Edge, err error) {
var last nodeStackElt
if len(ns.elt) == 0 {
err = errors.New("Cannot Pop an empty stack")
err = errors.New("cannot pop an empty stack")
return
}
last, ns.elt = ns.elt[len(ns.elt)-1], ns.elt[:len(ns.elt)-1]
Expand All @@ -46,12 +47,13 @@ func (ns *NodeStack) Pop() (n *tree.Node, e *tree.Edge, err error) {
return
}

/**
/*
*
Returns the head of the Stack, and an error if the stack is empty
*/
func (ns *NodeStack) Head() (n *tree.Node, e *tree.Edge, err error) {
if len(ns.elt) == 0 {
err = errors.New("An empty stack has no head")
err = errors.New("an empty stack has no head")
return
}
head := ns.elt[len(ns.elt)-1]
Expand Down
28 changes: 14 additions & 14 deletions io/newick/newick_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (p *Parser) scanIgnoreWhitespace() (tok Token, lit string) {
func (p *Parser) Parse() (newtree *tree.Tree, err error) {
// May have information inside [] before the tree
tok, lit := p.scanIgnoreWhitespace()
if tok == OPENBRACK {
if tok == OPENBRACK || tok == LABEL {
if _, err = p.consumeComment(tok, lit); err != nil {
return
}
Expand All @@ -83,7 +83,7 @@ func (p *Parser) Parse() (newtree *tree.Tree, err error) {
return
}
if level != 0 {
err = fmt.Errorf("Newick Error : Mismatched parenthesis after parsing")
err = fmt.Errorf("newick error : mismatched parenthesis after parsing")
return
}
tok, lit = p.scanIgnoreWhitespace()
Expand Down Expand Up @@ -125,7 +125,7 @@ func (p *Parser) parseIter(t *tree.Tree, level *int) (prevTok Token, err error)
case OPENPAR:
if node == nil {
if *level > 0 {
err = errors.New("Nil node at depth > 0")
err = errors.New("nil node at depth > 0")
return
}
node = t.NewNode()
Expand All @@ -135,7 +135,7 @@ func (p *Parser) parseIter(t *tree.Tree, level *int) (prevTok Token, err error)
t.SetRoot(node)
} else {
if *level == 0 {
err = errors.New("Newick Error: An open parenthesis while the stack is empty... Forgot a ';' at the end of previous tree?")
err = errors.New("newick Error: An open parenthesis while the stack is empty... Forgot a ';' at the end of previous tree?")
return
}
newNode = t.NewNode()
Expand All @@ -153,11 +153,11 @@ func (p *Parser) parseIter(t *tree.Tree, level *int) (prevTok Token, err error)
prevTok = tok
(*level)--
if _, _, err = nodeStack.Pop(); err != nil {
err = errors.New("Newick Error: Closing parenthesis while the stack is already empty")
err = errors.New("newick Error: Closing parenthesis while the stack is already empty")
return
}
node, edge, _ = nodeStack.Head()
case OPENBRACK:
case OPENBRACK, LABEL:
var comment string
//if prevTok == OPENPAR || prevTok == NEWSIBLING || prevTok == -1 {
if comment, err = p.consumeComment(tok, lit); err != nil {
Expand All @@ -172,17 +172,17 @@ func (p *Parser) parseIter(t *tree.Tree, level *int) (prevTok Token, err error)
// Else we add comment to node
node.AddComment(comment)
} else {
err = errors.New("Newick Error: Comment should not be located here: " + lit)
err = errors.New("newick error: comment should not be located here: " + lit)
return
}
prevTok = CLOSEBRACK
case CLOSEBRACK:
// Error here should not have
err = errors.New("Newick Error: Mismatched ] here...")
err = errors.New("newick error: mismatched ] here")
return
case STARTLEN:
if tok, lit = p.scanIgnoreWhitespace(); tok != NUMERIC {
err = errors.New("Newick Error: No numeric value after :")
err = errors.New("newick error: no numeric value after ':'")
return
}
// We skip length if the length is assigned to the root node
Expand Down Expand Up @@ -275,7 +275,7 @@ func (p *Parser) parseIter(t *tree.Tree, level *int) (prevTok Token, err error)
case EOT:
p.unscan()
if (*level) != 0 {
err = errors.New("Newick Error: Mismatched parenthesis at ;")
err = errors.New("newick Error: Mismatched parenthesis at ;")
return
}
prevTok = tok
Expand All @@ -291,19 +291,19 @@ func (p *Parser) parseIter(t *tree.Tree, level *int) (prevTok Token, err error)
// At the end returns the matching ] token and lit.
// If the given token is not a [, then returns an error
func (p *Parser) consumeComment(curtoken Token, curlit string) (comment string, err error) {
if curtoken == OPENBRACK {
if curtoken == OPENBRACK || curtoken == LABEL {
commenttoken, commentlit := p.scanIgnoreWhitespace()
for commenttoken != CLOSEBRACK {
for (curtoken == LABEL && commenttoken != LABEL) || (curtoken == OPENBRACK && commenttoken != CLOSEBRACK) {
if commenttoken == EOF || commenttoken == ILLEGAL {
err = fmt.Errorf("Unmatched bracket")
err = fmt.Errorf("unmatched bracket")
return
} else {
comment += commentlit
}
commenttoken, commentlit = p.scanIgnoreWhitespace()
}
} else {
err = fmt.Errorf("A comment must start with [")
err = fmt.Errorf("a comment must start with [")
}
return
}
4 changes: 3 additions & 1 deletion io/newick/newick_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
STARTLEN // :
OPENBRACK // [ : For comment
CLOSEBRACK // ] : For comment
LABEL // ' : For comment associated to nodes/edges
NEWSIBLING // ,
EOT // ;
)
Expand All @@ -26,5 +27,6 @@ func isWhitespace(ch rune) bool {
func isIdent(ch rune) bool {
return ch != '[' && ch != ']' &&
ch != '(' && ch != ')' &&
ch != ',' && ch != ':' && ch != ';'
ch != ',' && ch != ':' &&
ch != ';' && ch != '\''
}

0 comments on commit b7837b6

Please sign in to comment.