1. package com.sun.java_cup.internal;
  2. import java.util.Enumeration;
  3. /** This class represents the complete "action" table of the parser.
  4. * It has one row for each state in the parse machine, and a column for
  5. * each terminal symbol. Each entry in the table represents a shift,
  6. * reduce, or an error.
  7. *
  8. * @see com.sun.java_cup.internal.parse_action
  9. * @see com.sun.java_cup.internal.parse_action_row
  10. * @version last updated: 11/25/95
  11. * @author Scott Hudson
  12. */
  13. public class parse_action_table {
  14. /*-----------------------------------------------------------*/
  15. /*--- Constructor(s) ----------------------------------------*/
  16. /*-----------------------------------------------------------*/
  17. /** Simple constructor. All terminals, non-terminals, and productions must
  18. * already have been entered, and the viable prefix recognizer should
  19. * have been constructed before this is called.
  20. */
  21. public parse_action_table()
  22. {
  23. /* determine how many states we are working with */
  24. _num_states = lalr_state.number();
  25. /* allocate the array and fill it in with empty rows */
  26. under_state = new parse_action_row[_num_states];
  27. for (int i=0; i<_num_states; i++)
  28. under_state[i] = new parse_action_row();
  29. }
  30. /*-----------------------------------------------------------*/
  31. /*--- (Access to) Instance Variables ------------------------*/
  32. /*-----------------------------------------------------------*/
  33. /** How many rows/states are in the machine/table. */
  34. protected int _num_states;
  35. /** How many rows/states are in the machine/table. */
  36. public int num_states() {return _num_states;}
  37. /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  38. /** Actual array of rows, one per state. */
  39. public parse_action_row[] under_state;
  40. /*-----------------------------------------------------------*/
  41. /*--- General Methods ---------------------------------------*/
  42. /*-----------------------------------------------------------*/
  43. /** Check the table to ensure that all productions have been reduced.
  44. * Issue a warning message (to System.err) for each production that
  45. * is never reduced.
  46. */
  47. public void check_reductions()
  48. throws internal_error
  49. {
  50. parse_action act;
  51. production prod;
  52. /* tabulate reductions -- look at every table entry */
  53. for (int row = 0; row < num_states(); row++)
  54. {
  55. for (int col = 0; col < under_state[row].size(); col++)
  56. {
  57. /* look at the action entry to see if its a reduce */
  58. act = under_state[row].under_term[col];
  59. if (act != null && act.kind() == parse_action.REDUCE)
  60. {
  61. /* tell production that we used it */
  62. ((reduce_action)act).reduce_with().note_reduction_use();
  63. }
  64. }
  65. }
  66. /* now go across every production and make sure we hit it */
  67. for (Enumeration p = production.all(); p.hasMoreElements(); )
  68. {
  69. prod = (production)p.nextElement();
  70. /* if we didn't hit it give a warning */
  71. if (prod.num_reductions() == 0)
  72. {
  73. /* count it *
  74. emit.not_reduced++;
  75. /* give a warning if they haven't been turned off */
  76. if (!emit.nowarn)
  77. {
  78. System.err.println("*** Production \"" +
  79. prod.to_simple_string() + "\" never reduced");
  80. lexer.warning_count++;
  81. }
  82. }
  83. }
  84. }
  85. /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*
  86. /** Convert to a string. */
  87. public String toString()
  88. {
  89. String result;
  90. int cnt;
  91. result = "-------- ACTION_TABLE --------\n";
  92. for (int row = 0; row < num_states(); row++)
  93. {
  94. result += "From state #" + row + "\n";
  95. cnt = 0;
  96. for (int col = 0; col < under_state[row].size(); col++)
  97. {
  98. /* if the action is not an error print it */
  99. if (under_state[row].under_term[col].kind() != parse_action.ERROR)
  100. {
  101. result += " [term " + col + ":" + under_state[row].under_term[col] + "]";
  102. /* end the line after the 2nd one */
  103. cnt++;
  104. if (cnt == 2)
  105. {
  106. result += "\n";
  107. cnt = 0;
  108. }
  109. }
  110. }
  111. /* finish the line if we haven't just done that */
  112. if (cnt != 0) result += "\n";
  113. }
  114. result += "------------------------------";
  115. return result;
  116. }
  117. /*-----------------------------------------------------------*/
  118. }