do
var mod_string = "do\n{string}\nend"
var nmodule = parse_module(mod_string)
- var nblock = nmodule.n_classdefs.first.n_propdefs.first.as(AMainMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(ADoExpr).n_block.as(not null)
+ var nblock = nmodule.n_classdefs.first.n_propdefs.first.as(AMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(ADoExpr).n_block.as(not null)
return nblock
end
do
var mod_string = "var dummy = \n{string}"
var nmodule = parse_module(mod_string)
- var nexpr = nmodule.n_classdefs.first.n_propdefs.first.as(AMainMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(AVardeclExpr).n_expr.as(not null)
+ var nexpr = nmodule.n_classdefs.first.n_propdefs.first.as(AMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(AVardeclExpr).n_expr.as(not null)
return nexpr
end
+ # Parse a super class declaration
+ # Fatal error if the `string` is not a syntactically correct super class declaration
+ fun parse_superclass(string: String): APropdef
+ do
+ var mod_string = "class Dummy\nsuper {string}\nend"
+ var nclassdef = parse_classdef(mod_string).as(AStdClassdef)
+ var nsuperclasses = nclassdef.n_propdefs
+ if nsuperclasses.length != 1 then
+ self.fatal_error(null, "Fatal Error: not a super class declaration")
+ abort
+ end
+ return nsuperclasses.first
+ end
+
# Try to parse the `string` as something
#
# Returns the first possible syntacticaly correct type among:
tree = (new Parser(lexer)).parse
eof = tree.n_eof
if not eof isa AError then
- var ntype = tree.n_base.n_classdefs.first.n_propdefs.first.as(AMainMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(AVardeclExpr).n_type.n_types.first
+ var ntype = tree.n_base.n_classdefs.first.n_propdefs.first.as(AMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(AVardeclExpr).n_type.n_types.first
+ ntype.parent = null
return ntype
end
error = eof
lexer = new Lexer(source)
var first = lexer.next
- if not first isa EOF then
- var second = lexer.next
- if second isa EOF and not second isa AError then
- return first
- end
+ if first isa EOF then return first
+ var second = lexer.next
+ if second isa EOF and not second isa AError then
+ first.parent = null
+ return first
end
lexer = new InjectedLexer(source)
tree = (new Parser(lexer)).parse
eof = tree.n_eof
if not eof isa AError then
- var nexpr = tree.n_base.n_classdefs.first.n_propdefs.first.as(AMainMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(AVardeclExpr).n_expr.as(AParExpr).n_expr
+ var nexpr = tree.n_base.n_classdefs.first.n_propdefs.first.as(AMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(AVardeclExpr).n_expr.as(AParExpr).n_expr
+ nexpr.parent = null
return nexpr
end
if eof.location > error.location then error = eof
tree = (new Parser(lexer)).parse
eof = tree.n_eof
if not eof isa AError then
- var nblock = tree.n_base.n_classdefs.first.n_propdefs.first.as(AMainMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(ADoExpr).n_block.as(ABlockExpr)
+ var nblock = tree.n_base.n_classdefs.first.n_propdefs.first.as(AMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(ADoExpr).n_block.as(ABlockExpr)
nblock.n_kwend = null # drop injected token
+ nblock.parent = null
return nblock
end
if eof.location > error.location then error = eof
end
end
+# A modified lexer that feed tokens before and after the real tokens.
class InjectedLexer
super Lexer
+ # The tokens to use before the real tokens (in order).
var injected_before = new List[Token]
+
+ # The tokens to use after the real tokens (in order).
+ # The real EOF token is produced after these tokens.
var injected_after = new List[Token]
private var is_finished = false
do
if not injected_before.is_empty then
var tok = injected_before.shift
- if tok._location == null then tok._location = new Location(file, 1, 1, 1, 0)
return tok
end
if not is_finished then
end
var tok = injected_after.shift
- if tok._location == null then tok._location = new Location(file, 1, 1, 1, 0)
return tok
end
end
-
-redef class ANode
- # Return an array of tokens that match a given text
- fun collect_tokens_by_text(text: String): Array[Token]
- do
- var v = new CollectTokensByTextVisitor(text)
- v.enter_visit(self)
- return v.result
- end
-
- # Return an array of node that are annotated
- # The attached node can be retrieved by two invocation of parent
- fun collect_annotations_by_name(name: String): Array[AAnnotation]
- do
- var v = new CollectAnnotationsByNameVisitor(name)
- v.enter_visit(self)
- return v.result
- end
-end
-
-private class CollectTokensByTextVisitor
- super Visitor
- var text: String
- init(text: String) do self.text = text
- var result = new Array[Token]
- redef fun visit(node)
- do
- node.visit_all(self)
- if node isa Token and node.text == text then result.add(node)
- end
-end
-
-private class CollectAnnotationsByNameVisitor
- super Visitor
- var name: String
- init(name: String) do self.name = name
- var result = new Array[AAnnotation]
- redef fun visit(node)
- do
- node.visit_all(self)
- if node isa AAnnotation and node.n_atid.n_id.text == name then result.add(node)
- end
-end