Skip to content

Instantly share code, notes, and snippets.

@Micrified
Created February 15, 2019 09:05
Show Gist options
  • Select an option

  • Save Micrified/326d3344ebdfefccbe5a99867e2a865e to your computer and use it in GitHub Desktop.

Select an option

Save Micrified/326d3344ebdfefccbe5a99867e2a865e to your computer and use it in GitHub Desktop.
// Returns the first-set for the given non-terminal.
func firstSet (b byte, g I) ([]byte, error) {
var set []byte = []byte{};
var hasEpsilon bool = false;
// Ensure b is a non-terminal.
if !isNT(b) {
return nil, errors.New("First-Set only valid for non-terminals!");
}
// Determine if epsilon is included in the grammar.
for p := range g {
// Skip irrelevant productions.
if (p.lhs != b) continue;
// Check if the production leads to an empty rule (epsilon).
if (len(p.rhs) == 0) {
hasEpsilon = true;
set = append(set, '@');
break;
}
}
// Parse through all self-rules.
for p := range g {
// Skip irrelevant productions.
if (p.lhs != b) continue;
// If production is a terminal, add it to first-set.
if (len(p.rhs) == 1 && isNT(p.rhs[0])) {
set = append(set, p.rhs[0]);
continue;
}
}
// If epsilon is in production, check the other rules.
if (hasEpsilon == false) {
return set, nil;
}
// Otherwise check the other rules.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment