Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NitCC bootstrap #2844

Merged
merged 12 commits into from
Jul 23, 2024
Prev Previous commit
Next Next commit
nitcc: move plusize, quesize and groupize to grammar.nit
Signed-off-by: Jean Privat <[email protected]>
privat committed Jul 22, 2024
commit 1079127cd1038793433e8674e3e3c8019e401945
78 changes: 78 additions & 0 deletions contrib/nitcc/src/grammar.nit
Original file line number Diff line number Diff line change
@@ -288,6 +288,84 @@ class Gram
return res
end

# Pool of elements that are modified with + (reuse them!)
var plusizes = new HashMap[Element, Production]

# Create a + version of an element
#
# ```
# foo = x bar+ y | z ;
# ```
#
# becomes
#
# ```
# foo = x abs0 y | z ;
# abs0 = {one:} bar | {more:} abs0 bar ;
# ```
fun plusize(e: Element): Production
do
if plusizes.has_key(e) then return plusizes[e]
var name = "{e}+"
var prod = new Production(name)
prod.acname = "Nodes[{e.acname}]"
prods.add(prod)
var alt1 = prod.new_alt("{name}_one", e)
alt1.codes = [new CodeNewNodes(alt1), new CodePop, new CodeAdd: Code]
var alt2 = prod.new_alt("{name}_more", prod, e)
alt2.codes = [new CodePop, new CodePop, new CodeAdd: Code]
plusizes[e] = prod
return prod
end

# Pool of elements that are modified with ? (reuse them!)
var quesizes = new HashMap[Element, Production]

# Create a ? version of an element
#
# ```
# foo = x bar? y | z ;
# ```
#
# becomes
#
# ```
# foo = x abs0 y | z ;
# abs0 = {one:} bar | {none} Empty ;
# ```
fun quesize(e: Element): Production
do
if quesizes.has_key(e) then return quesizes[e]
var name = "{e}?"
var prod = new Production(name)
prod.acname = "nullable {e.acname}"
prods.add(prod)
var a1 = prod.new_alt("{name}_one", e)
a1.codes = [new CodePop]
var a0 = prod.new_alt0("{name}_none")
a0.codes = [new CodeNull]
quesizes[e] = prod
return prod
end

# Pool for anoymous grouped production (reuse them!)
var groupizes = new HashMap[Array[Element], Production]

# Create an anonymous production that groups some elements.
# Note: an anonymous production is always returned, even if `es` is empty or single.
fun groupize(es: Array[Element]): Production
do
if groupizes.has_key(es) then return groupizes[es]
var name = "_group{groupizes.length}"
var prod = new Production(name)
prods.add(prod)
var a1 = prod.new_alt2("{name}_single", es)
groupizes[es] = prod
return prod
end



# Generate the nodes classes
fun gen_to_nit(filepath: String, name: String)
do
88 changes: 7 additions & 81 deletions contrib/nitcc/src/nitcc_semantic.nit
Original file line number Diff line number Diff line change
@@ -59,7 +59,7 @@ class CollectNameVisitor
v2.enter_visit(n)

# Inline all the `?`
gram.inline(v2.quesizes.values)
gram.inline(v2.gram.quesizes.values)
# Inline all the prods suffixed by '_inline' #TODO use a real keyword
for p in gram.prods do
if not p.name.has_suffix("_inline") then continue
@@ -119,81 +119,7 @@ private class CheckNameVisitor
# Known rejected tokens
var rejecteds = new Array[Element]

# Pool of elements that are modified with + (reuse them!)
var plusizes = new HashMap[Element, Production]

# Create a + version of an element
#
# ```
# foo = x bar+ y | z ;
# ```
#
# becomes
#
# ```
# foo = x abs0 y | z ;
# abs0 = {one:} bar | {more:} abs0 bar ;
# ```
fun plusize(e: Element): Production
do
if plusizes.has_key(e) then return plusizes[e]
var name = "{e}+"
var prod = new Production(name)
prod.acname = "Nodes[{e.acname}]"
v1.gram.prods.add(prod)
var alt1 = prod.new_alt("{name}_one", e)
alt1.codes = [new CodeNewNodes(alt1), new CodePop, new CodeAdd: Code]
var alt2 = prod.new_alt("{name}_more", prod, e)
alt2.codes = [new CodePop, new CodePop, new CodeAdd: Code]
plusizes[e] = prod
return prod
end

# Pool of elements that are modified with ? (reuse them!)
var quesizes = new HashMap[Element, Production]

# Create a ? version of an element
#
# ```
# foo = x bar? y | z ;
# ```
#
# becomes
#
# ```
# foo = x abs0 y | z ;
# abs0 = {one:} bar | {none} Empty ;
# ```
fun quesize(e: Element): Production
do
if quesizes.has_key(e) then return quesizes[e]
var name = "{e}?"
var prod = new Production(name)
prod.acname = "nullable {e.acname}"
v1.gram.prods.add(prod)
var a1 = prod.new_alt("{name}_one", e)
a1.codes = [new CodePop]
var a0 = prod.new_alt0("{name}_none")
a0.codes = [new CodeNull]
quesizes[e] = prod
return prod
end

# Pool for anoymous grouped production (reuse them!)
var groupizes = new HashMap[Array[Element], Production]

# Create an anonymous production that groups some elements.
# Note: an anonymous production is always returned, even if `es` is empty or single.
fun groupize(es: Array[Element]): Production
do
if groupizes.has_key(es) then return groupizes[es]
var name = "_group{groupizes.length}"
var prod = new Production(name)
v1.gram.prods.add(prod)
var a1 = prod.new_alt2("{name}_single", es)
groupizes[es] = prod
return prod
end
fun gram: Gram do return v1.gram

# The current nexpr, used to track dependency on named expressions (see `Nexpr::precs`)
var nexpr: nullable Nexpr = null
@@ -717,8 +643,8 @@ redef class Nelem_star
redef fun accept_check_name_visitor(v) do
super
var elem = v.elems.pop
elem = v.plusize(elem)
elem = v.quesize(elem)
elem = v.gram.plusize(elem)
elem = v.gram.quesize(elem)
set_elem(v, null, elem)
end
end
@@ -727,7 +653,7 @@ redef class Nelem_ques
redef fun accept_check_name_visitor(v) do
super
var elem = v.elems.pop
elem = v.quesize(elem)
elem = v.gram.quesize(elem)
set_elem(v, null, elem)
end
end
@@ -736,7 +662,7 @@ redef class Nelem_plus
redef fun accept_check_name_visitor(v) do
super
var elem = v.elems.pop
elem = v.plusize(elem)
elem = v.gram.plusize(elem)
set_elem(v, null, elem)
end
end
@@ -746,7 +672,7 @@ redef class Nelem_par
var old = v.elems
v.elems = new Array[Element]
super
var elem = v.groupize(v.elems)
var elem = v.gram.groupize(v.elems)
v.elems = old
set_elem(v, null, elem)
end