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

Support IELR(1) Parser Generation #398

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

junk0612
Copy link
Collaborator

@junk0612 junk0612 commented Apr 23, 2024

Support the generation of the IELR(1) parser described in this paper.
https://www.sciencedirect.com/science/article/pii/S0167642309001191

This PR will be ready for merging when the following is done.

  • Add tests
    • Currently, I have only created a grammar file and verified its operation in my local environment.
  • Refactor
    • The data structure is awful and needs to be improved because the priority was to achieve the expected results.

@junk0612 junk0612 force-pushed the generate_ielr_parser branch from 2d975c5 to a49fe82 Compare June 25, 2024 17:19
@jasone
Copy link

jasone commented Jul 26, 2024

A couple months ago I poked around the internet looking for independent IELR(1) implementations, and besides lrama found only an inactive rust-based attempt. Recently I completed my own implementation and wrote a technical report with the hope that it might help others. IELR(1) turns out to be a real bear to figure out, even if it takes only a moderate amount of code. I hope you find the time and inspiration to complete this effort. Good luck!

@junk0612 junk0612 force-pushed the generate_ielr_parser branch from a49fe82 to 604737d Compare September 4, 2024 06:28
@junk0612 junk0612 force-pushed the generate_ielr_parser branch 7 times, most recently from b3078e1 to 0a300f7 Compare September 25, 2024 18:33
@junk0612 junk0612 marked this pull request as ready for review September 25, 2024 18:33
@junk0612 junk0612 requested review from ydah and yui-knk September 25, 2024 18:33
@junk0612 junk0612 force-pushed the generate_ielr_parser branch from 0a300f7 to 0ba3241 Compare October 11, 2024 09:42
@junk0612 junk0612 force-pushed the generate_ielr_parser branch from 9bf8584 to 7da9676 Compare November 14, 2024 05:10
@junk0612
Copy link
Collaborator Author

junk0612 commented Nov 14, 2024

On 7da9676 , Lrama can parse CRuby's parse.y at ruby/ruby@028958f .

These are the files of parsing results.
ruby path/to/id2token path/to/parse.y | bundle exec lrama -v - lalr
lalr.output

ruby path/to/id2token path/to/parse.y | bundle exec lrama -D lr.type=ielr -v - ielr
ielr.output

@@ -92,6 +92,20 @@ def compute
report_duration(:compute_default_reduction) { compute_default_reduction }
end

def compute_ielr
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note]: Ref "3.5.4. Algorithm" of the paper.

@@ -524,5 +541,52 @@ def compute_default_reduction
end.first
end
end

def split_states
transition_queue = []
Copy link
Collaborator

@yui-knk yui-knk Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nits]: It seems this variable is not used.

@@ -524,5 +541,52 @@ def compute_default_reduction
end.first
end
end

def split_states
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note]: "Definition 3.45 (split_states)"

@@ -142,5 +160,274 @@ def rr_conflicts
conflict.type == :reduce_reduce
end
end

def propagate_lookaheads(next_state)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note]: Definition 3.40 (propagate_lookaheads)

def propagate_lookaheads(next_state)
next_state.kernels.map {|item|
lookahead_sets =
if item.position == 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note]: Corresponding to case 2 of Definition 3.40 because position is 0-origin in this code base.

def propagate_lookaheads(next_state)
next_state.kernels.map {|item|
lookahead_sets =
if item.position == 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nits]: I personally like to make the condition order to be aligned with the original paper for readability of the algorithm. For example

if item.position > 1
  ...
else
  ...
end

if item.position == 1
goto_follow_set(item.lhs)
else
kernel = kernels.find {|k| k.predecessor_item_of?(item) }
Copy link
Collaborator

@yui-knk yui-knk Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note]: C[k] is the kernel (1) whose LHS and RHS are same with the item's one and (2) whose position is item.position - 1. #predecessor_item_of? is a method for such calculation.

item_lookahead_set[kernel]
end

[item, lookahead_sets & next_state.lookahead_set_filters[item]]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note]: This is same with the definition case 1 because case 1 requires tokens which are in both lookahead_set_filters of s' kernel and item_lookahead_sets of s kernel.

@@ -92,6 +92,20 @@ def compute
report_duration(:compute_default_reduction) { compute_default_reduction }
end

def compute_ielr
report_duration(:split_states) { split_states }
report_duration(:compute_direct_read_sets) { compute_direct_read_sets }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note]: Compute LA set again, once states are splitted. See Phase 4 and Phase 5 on "3.1. Overview".

!@item_lookahead_set.nil?
end

def compatible_lookahead?(filtered_lookahead)
Copy link
Collaborator

@yui-knk yui-knk Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[note]: This method is same with "Definition 3.43 (is_compatible)".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nits]: If so, I prefer to use is_compatible? as a method name for clarity.

@yui-knk yui-knk mentioned this pull request Jan 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants