Advertisement
Guest User

LALR1

a guest
Jun 25th, 2025
30
0
29 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.81 KB | Source Code | 0 0
  1. package com.viffx.CodingLanguage.Compiler.Automata;
  2.  
  3. import com.viffx.CodingLanguage.Compiler.Grammar;
  4. import com.viffx.CodingLanguage.Compiler.Symbols.NonTerminal;
  5. import com.viffx.CodingLanguage.Compiler.Symbols.Symbol;
  6. import com.viffx.CodingLanguage.Compiler.Symbols.Terminal;
  7.  
  8. import java.util.*;
  9. import java.util.function.BiConsumer;
  10. import java.util.function.Consumer;
  11.  
  12. public class LALR1 {
  13.     private final Grammar G;
  14.  
  15.     public LALR1(Grammar g) {
  16.         G = g;
  17.     }
  18.  
  19.     private Set<Terminal> FIRST(List<Symbol> symbols) {
  20.         Symbol first = symbols.getFirst();
  21.         if (first == null) return new HashSet<>();
  22.         if (first instanceof Terminal t) return Set.of(t);
  23.  
  24.         Set<Item> items = CLOSURE(G.station((NonTerminal) first));
  25.         Set<Terminal> terminals = new HashSet<>();
  26.         for (Item i : items) {
  27.             Symbol symbol = G.symbol(i);
  28.             if (symbol == null) continue;
  29.             if (symbol instanceof Terminal t) {
  30.                 terminals.add(t);
  31.             }
  32.         }
  33.         return terminals;
  34.     }
  35.     /*
  36.     * Set<Item> CLOSURE(Set<Item> I)*/
  37.     private Set<Item> CLOSURE (Set<Item> I) {
  38.         Set<Item> J = new HashSet<>(I);
  39.         Queue<Item> worklist = new LinkedList<>(J);
  40.         while (!worklist.isEmpty()) {
  41.             Item A = worklist.poll();
  42.             Symbol symbol = G.symbol(A);
  43.             if (symbol == null) continue;
  44.             if (symbol instanceof NonTerminal nt) {
  45.                 int index = G.NT_index(nt);
  46.                 if (index < 0) throw new RuntimeException(nt + " is undefined in the given grammar.");
  47.                 int count = Math.max(0,  G.NT_count(nt));
  48.                 for (int i = index; i - index < count; i++) {
  49.                     Item newItem = new Item(i,0);
  50.                     if (J.add(newItem)) worklist.add(newItem);
  51.                 }
  52.             }
  53.         }
  54.         return J;
  55.     }
  56.     private Set<Item> GOTO(Set<Item> I, Symbol x) {
  57.         Set<Item> advanced = new HashSet<>();
  58.         for (Item item : I) {
  59.             Symbol symbol = G.symbol(item);
  60.             if (symbol == null || !G.symbol(item).equals(x)) continue;
  61.             advanced.add(item.advance(G));
  62.         }
  63.         return CLOSURE(advanced);
  64.     }
  65.     private HashSet<Set<Item>> LR0ITEMS(Set<Item> START) {
  66.         HashSet<Set<Item>> C = new HashSet<>(Set.of(START));
  67.         Queue<Set<Item>> worklist = new LinkedList<>(C);
  68.         while (!worklist.isEmpty()) {
  69.             Set<Item> I = worklist.poll();
  70.             for (Symbol X : G.symbols()) {
  71.                 Set<Item> GOTO = GOTO(I,X);
  72.                 if (GOTO.isEmpty()) continue;
  73.                 if (C.add(GOTO)) worklist.add(GOTO);
  74.             }
  75.         }
  76.         return C;
  77.     }
  78.     /* Gets the start item.
  79.     * Throws an exception if there is more than one production for the start item
  80.     * Throws an exception if that the production is not a single non-terminal
  81.     * */
  82.     private Set<Item> startItem(int index) {
  83.         List<List<Symbol>> START = G.productions(NonTerminal.START);
  84.         if (START.isEmpty()) throw new RuntimeException("Start is undefined in the given grammar.");
  85.         List<Symbol> START_PRODUCTION = new ArrayList<>(START.getFirst());
  86.         if (START.size() != 1 || START_PRODUCTION.size() != 1 || START_PRODUCTION.getFirst() instanceof Terminal) throw new RuntimeException("Start must be defined as \"START > {Non terminal}\"");
  87.         return Set.of(new Item(index,0, Set.of(Terminal.TEST)));
  88.     }
  89.     public Set<Item> KERNEL(Set<Item> LR0STATE, int index) {
  90.         Set<Item> kernel = new HashSet<>();
  91.         for (Item LR0ITEM : LR0STATE) {
  92.             if (LR0ITEM.dot() > 0 || LR0ITEM.production() == index) {
  93.                 kernel.add(LR0ITEM);
  94.             }
  95.         }
  96.         return kernel;
  97.     }
  98.  
  99.     public Set<Set<Item>> LALR1ITEMS() {
  100.         int index = G.NT_index(NonTerminal.START);
  101.         Set<Item> START = CLOSURE(startItem(index));
  102.  
  103.         // [CALCULATE_KERNELS]
  104.         HashSet<Set<Item>> kernels = new HashSet<>();
  105.         HashSet<Set<Item>> LR0ITEMS = LR0ITEMS(START);
  106. //        KERNEL(LR0ITEMS.getFirst(),index).forEach(item -> System.out.println("\t" + item.toReadable(G)));
  107.         int count = 0;
  108.         for (Set<Item> state : LR0ITEMS) {
  109.             System.out.println("I" + count++ + ":");
  110.             state.forEach(item -> System.out.println("\t" + item.toReadable(G)));
  111.             System.out.println();
  112.         }
  113.         for (Set<Item> LR0STATE : LR0ITEMS) kernels.add(KERNEL(LR0STATE,index));
  114.         count = 0;
  115.         for (Set<Item> state : kernels) {
  116.             System.out.println("I" + count++ + ":");
  117.             state.forEach(item -> System.out.println("\t" + item.toReadable(G)));
  118.             System.out.println();
  119.         }
  120.         HashMap<Item,Set<Channel>> channelsMap = new HashMap<>();
  121. //        // [CALCULATE_LOOKAHEADS]
  122.         for (Set<Item> I : kernels) {
  123.             for (Item A : I) {
  124.                 for (Symbol X : G.symbols()) {
  125.                     if (!A.atEnd(G) && G.symbol(A).equals(X)) {
  126.                         // Step 1: Closure with dummy lookahead
  127.                         Item A_with_hash = new Item(A.production(), A.dot(), Set.of(Terminal.TEST));
  128.                         Set<Item> closure = CLOSURE(Set.of(A_with_hash));
  129.  
  130.                         // Step 2: GOTO over symbol X
  131.                         Set<Item> gotoSet = GOTO(closure, X);
  132.  
  133.                         for (Item B : gotoSet) {
  134.                             if (B.atEnd(G)) continue;
  135.                             if (!G.symbol(B).equals(X)) continue;
  136.  
  137.                             if (B.lookahead().contains(Terminal.TEST)) {
  138.                                 // Propagation from A to B
  139.                                 channelsMap.computeIfAbsent(A, _ -> new HashSet<>())
  140.                                         .add(new Propagated(B));
  141.                             } else {
  142.                                 // Spontaneous generation for B
  143. //                                Set<Terminal> lookahead = FIRST(B); // or FIRST(B.β a)
  144.                                 channelsMap.computeIfAbsent(B, _ -> new HashSet<>())
  145.                                         .add(new Spontaneous(null));
  146.                             }
  147.                         }
  148.                     }
  149.                 }
  150.             }
  151.         }
  152.         channelsMap.forEach((item, channel) -> {
  153.             System.out.println(item + " -> " + channel);
  154.         });
  155.         System.out.println("Hi");
  156. //
  157. //        // [INITIALIZE_LOOKAHEAD_TABLE]
  158.  
  159. //        Map<Integer,Set<Terminal>> lookaheads = new HashMap<>();
  160. //        Map<Integer,Set<Integer>> propagatingChannels = new HashMap<>();
  161. //        channelsMap.forEach((item, channels) -> {
  162. //            for (Channel channel : channels) {
  163. //                if (channel instanceof Spontaneous spontaneous) {
  164. //                    lookaheads.computeIfAbsent(item.hashCode(), _ -> new HashSet<>()).addAll(spontaneous.terminals());
  165. //                    continue;
  166. //                }
  167. //                propagatingChannels.computeIfAbsent(item.hashCode(), _ -> new HashSet<>()).add(((Propagated) channel).item().hashCode());
  168. //                System.out.println(item.hashCode() + " -> " + ((Propagated) channel).item().hashCode());
  169. //            }
  170. //            //0,32,1,33,156,157,94,95
  171. //        });
  172. //        System.out.println("Hi");
  173. //
  174. //        // [PUMP_LOOKAHEADS]
  175. //        boolean change;
  176. //        do {
  177. //            change = false;
  178. //            for (Map.Entry<Integer,Set<Integer>> entry : propagatingChannels.entrySet()) {
  179. //                Integer from = entry.getKey();
  180. //                for (Integer target : entry.getValue()) {
  181. //                    System.out.println(lookaheads.containsKey(from));
  182. //                    if (!lookaheads.containsKey(from)) continue;
  183. //                    Set<Terminal> fromLookahead = lookaheads.get(from);
  184. //                    change |= lookaheads.computeIfAbsent(target, _ -> new HashSet<>()).addAll(fromLookahead);
  185. //                }
  186. //            }
  187. //        } while (change);
  188. //
  189. //        lookaheads.forEach((item, terminals) -> {System.out.println(item + "->" + terminals);});
  190.         return null; // STFU
  191.     }
  192.  
  193.     private sealed interface Channel permits Propagated, Spontaneous {}
  194.     private record Propagated(Item item) implements Channel {
  195.         @Override
  196.         public String toString() {
  197.             return "Propagated{" +
  198.                     "item=" + item +
  199.                     '}';
  200.         }
  201.     }
  202.     private record Spontaneous(Set<Terminal> terminals) implements Channel {
  203.         @Override
  204.         public String toString() {
  205.             return "Spontaneous{" +
  206.                     "terminals=" + terminals +
  207.                     '}';
  208.         }
  209.     }
  210.     // I.forEach(item1 -> {System.out.println(item1.toReadable(G));});
  211.  
  212. }
  213.  
  214.  
Tags: compiler
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement