#print " expected: {state.error_msg}"
#print " node_stack={node_stack.join(", ")}"
#print " state_stack={state_stack.join(", ")}"
+ node_stack.add(token)
var error: NError
if token isa NLexerError then
error = token
error.text = token.text
error.token = token
end
- error.error_tree.items.add_all(node_stack)
+ error.error_tree.children.add_all(node_stack)
error.expected = state.error_msg
node_stack.clear
node_stack.add error
# The current state
# Used by generated parsers
- var state: LRState
+ var state: LRState is noinit
init
do
# Should the parser stop
# Used by generated parsers
- var stop writable = true
+ var stop = true is writable
# Parse a full sequence of tokens and return a complete syntactic tree
fun parse: Node
last_state = state
end
var c
+ var next
if pos >= length then
c = '\0'
+ next = null
else
- c = text[pos]
+ c = text.chars[pos]
+ next = state.trans(c)
end
- var next = state.trans(c)
if next == null then
if pos_start < length then
if last_state == null then
super Visitor
var writer: OStream
private var indent = 0
- init(writer: OStream) do self.writer = writer
redef fun visit(n)
do
for i in [0..indent[ do writer.write(" ")
# The name of the node (as used in the grammar file)
fun node_name: String do return class_name
- # A point of view on the direct childrens of the node
+ # A point of view on the direct children of the node
fun children: SequenceRead[nullable Node] is abstract
+ # A point of view of a depth-first visit of all non-null children
+ var depth: Collection[Node] = new DephCollection(self)
+
# Visit all the children of the node with the visitor `v`
protected fun visit_children(v: Visitor)
do
end
# The position of the node in the input stream
- var position: nullable Position writable = null
+ var position: nullable Position = null is writable
# Produce a graphiz file for the syntaxtic tree rooted at `self`.
fun to_dot(filepath: String)
end
end
+private class DephCollection
+ super Collection[Node]
+ var node: Node
+ redef fun iterator do return new DephIterator([node].iterator)
+end
+
+private class DephIterator
+ super Iterator[Node]
+
+ var stack = new List[Iterator[nullable Node]]
+
+ init(i: Iterator[nullable Node]) is old_style_init do
+ stack.add i
+ end
+
+ redef fun is_ok do return not stack.is_empty
+ redef fun item do return stack.last.item.as(not null)
+ redef fun next
+ do
+ var i = stack.last
+ stack.push i.item.children.iterator
+ i.next
+ while is_ok do
+ if not stack.last.is_ok then
+ stack.pop
+ continue
+ end
+ if stack.last.item == null then
+ stack.last.next
+ continue
+ end
+ return
+ end
+ end
+end
+
# A token produced by the lexer and used in a syntactic tree
abstract class NToken
super Node
end
# The text associated with the token
- var text: String writable = ""
+ var text: String = "" is writable
redef fun to_s do
var res = super
class NLexerError
super NError
- redef fun unexpected do return "character '{text.first}'"
+ redef fun unexpected do return "character '{text.chars.first}'"
end
# A parser error linked to a unexpected token
class NParserError
super NError
+
# The unexpected token
- var token: nullable NToken
+ var token: nullable NToken = null
- redef fun unexpected do return token.node_name
+ redef fun unexpected
+ do
+ var res = token.node_name
+ var text = token.text
+ if not text.is_empty and res != "'{text}'" then
+ res += " '{text.escape_to_c}'"
+ end
+ return res
+ end
end
# A hogeneous sequence of node, used to represent unbounded lists (and + modifier)
class Nodes[T: Node]
super Node
- redef fun children do return items
- var items = new Array[T]
+ redef var children: Array[T] = new Array[T]
end
-# A production with a specific, named and statically typed childrens
+# A production with a specific, named and statically typed children
class NProd
super Node
redef var children: SequenceRead[nullable Node] = new NProdChildren(self)
var filepath = args.shift
var text
if filepath == "-" then
- text = stdin.read_all
+ text = sys.stdin.read_all
else if filepath == "-e" then
if args.is_empty then
print "Error: -e need a text"
tpv.enter_visit(n)
n = n.error_tree
else
- print "ROOT: {n} (see {astout} and {astdotout})"
+ print "ROOT: {n}; {n.depth.length} nodes (see {astout} and {astdotout})"
end
tpv.enter_visit(n)
n.to_dot(astdotout)