Skip to content

Commit

Permalink
Added after reduce code
Browse files Browse the repository at this point in the history
  • Loading branch information
yoavst committed Dec 16, 2018
1 parent 6d587f5 commit 7022406
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 33 deletions.
78 changes: 45 additions & 33 deletions cup/parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -198,20 +198,20 @@ terminal
terminal String
PACKAGE, IMPORT, CODE, ACTION, PARSER, TERMINAL, NON, NONTERMINAL, INIT,
SCAN, WITH, START, PRECEDENCE, LEFT, RIGHT, NONASSOC, SUPER, EXTENDS,
OPTION;
AFTER, REDUCE, OPTION;

terminal String ID, CODE_STRING;

non terminal
package_spec, parser_spec,
option_spec, option_list, option_, action_code_part,
code_parts, code_part,
parser_code_part, start_spec,
import_spec, init_code, scan_code, symbol,
terminal_non_terminal, decl_symbol_list, new_symbol_id,
option_spec, option_list, option_, action_code_part,
code_parts, code_part,
parser_code_part, start_spec,
import_spec, init_code, scan_code, after_reduce_code, symbol,
terminal_non_terminal, decl_symbol_list, new_symbol_id,
preced, assoc, precterminal_list, precterminal_id,
production, rhs_list, rhs;

non terminal Grammar spec;

non terminal String symbol_id, label_id, robust_id;
Expand All @@ -220,15 +220,15 @@ non terminal StringBuilder multipart_id, import_id, type_id,
non terminal symbol wild_symbol_id;

non terminal production_part prod_part;
non terminal symbol prod_precedence;
non terminal symbol prod_precedence;

/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/

start with spec;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

spec ::=
spec ::=
package_spec
import_spec*
code_parts
Expand All @@ -238,22 +238,22 @@ spec ::=
production+
{: RESULT = grammar; :}
|
/* error recovery assuming something went wrong before symbols
/* error recovery assuming something went wrong before symbols
and we have TERMINAL or NON TERMINAL to sync on. if we get
an error after that, we recover inside symbol_list or
production_list
an error after that, we recover inside symbol_list or
production_list
*/
error
error
symbol+
preced*
start_spec
production+
{: RESULT = grammar; :}
;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

package_spec ::=
package_spec ::=
PACKAGE multipart_id:id SEMI
{:
/* save the package name */
Expand All @@ -263,11 +263,11 @@ package_spec ::=
/* empty */
;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

import_spec ::=
IMPORT import_id:id SEMI
{:
{:
/* save this import on the imports list */
parser.emit.import_list.add(id.toString());
:}
Expand All @@ -278,13 +278,13 @@ import_spec ::=
// (we check in the part action to make sure we don't have 2 of any part)
code_part ::=
option_spec | parser_spec |
action_code_part | parser_code_part | init_code | scan_code ;
code_parts ::=
action_code_part | parser_code_part | init_code | scan_code | after_reduce_code;
code_parts ::=
| code_parts code_part;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

parser_spec ::=
parser_spec ::=
PARSER multipart_id:name SEMI
{: parser.main.setOption("parser", name.toString()); :}
| PARSER multipart_id:name LT typearglist:types GT SEMI
Expand All @@ -295,12 +295,12 @@ parser_spec ::=

option_spec ::= OPTION option_list SEMI;
option_list ::= option_list COMMA option_ | option_;
option_ ::= robust_id:opt {: parser.main.setOption(opt); :}
option_ ::= robust_id:opt {: parser.main.setOption(opt); :}
| robust_id:opt EQUALS robust_id:val
{: parser.main.setOption(opt, val); :};
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

action_code_part ::=
action_code_part ::=
ACTION CODE CODE_STRING:user_code SEMI?
{:
if (parser.emit.action_code!=null)
Expand All @@ -310,9 +310,9 @@ action_code_part ::=
:}
;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

parser_code_part ::=
parser_code_part ::=
PARSER CODE CODE_STRING:user_code SEMI?
{:
if (parser.emit.parser_code!=null)
Expand All @@ -322,30 +322,42 @@ parser_code_part ::=
:}
;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

init_code ::=
init_code ::=
INIT WITH CODE_STRING:user_code SEMI?
{:
{:
if (parser.emit.init_code!=null)
ErrorManager.getManager().emit_warning("Redundant init code (skipping)");
else /* save the user code */
parser.emit.init_code = user_code;
:}
;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

scan_code ::=
SCAN WITH CODE_STRING:user_code SEMI?
{:
{:
if (parser.emit.scan_code!=null)
ErrorManager.getManager().emit_warning("Redundant scan code (skipping)");
else /* save the user code */
parser.emit.scan_code = user_code;
:}
;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

after_reduce_code ::=
AFTER REDUCE CODE_STRING:user_code SEMI?
{:
if (parser.emit.after_reduce_code!=null)
ErrorManager.getManager().emit_warning("Redundant after reduce code (skipping)");
else /* save the user code */
parser.emit.after_reduce_code = user_code;
:}
;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

symbol ::=
Expand Down
2 changes: 2 additions & 0 deletions flex/Lexer.jflex
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ ident = ([:jletter:] | "_" ) ([:jletterdigit:] | [:jletter:] | "_" )*
"nonassoc" { return symbol("NONASSOC",NONASSOC,yytext()); }
"extends" { return symbol("EXTENDS",EXTENDS,yytext()); }
"super" { return symbol("SUPER",SUPER,yytext()); }
"after" { return symbol("AFTER",AFTER,yytext()); }
"reduce" { return symbol("REDUCE",REDUCE,yytext()); }
{ident} { return symbol("ID",ID,yytext()); }

}
Expand Down
20 changes: 20 additions & 0 deletions src/com/github/jhoenicke/javacup/emit.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ as well as to report counts of various things (such as number of conflicts
init_code - user supplied code to be executed as the parser
is being initialized.
scan_code - user supplied code to get the next Symbol.
after_reduce_code - user code that will run after every reduce
start_production - the start production for the grammar.
import_list - list of imports for use with action class.
num_conflicts - number of conflicts detected.
Expand Down Expand Up @@ -148,6 +149,11 @@ public class emit {

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

/** User code that will be inserted after every reduce call. */
public String after_reduce_code = null;

/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

/** List of imports (Strings containing class names) to go with actions. */
public ArrayList<String> import_list = new ArrayList<String>();

Expand Down Expand Up @@ -348,6 +354,17 @@ else if (prod instanceof action_production)
&& (symbol.the_symbol.name().endsWith("*")
|| symbol.the_symbol.name().endsWith("+"));

if (i == 0) {
out.println(" " + RUNTIME_PACKAGE + ".Symbol " +
"$first = " +
stackelem(prod.rhs_stackdepth() - i, is_java15) + ";");
}
if (i == prod.rhs_stackdepth() - 1) {
out.println(" " + RUNTIME_PACKAGE + ".Symbol " +
"$last = " +
stackelem(prod.rhs_stackdepth() - i, is_java15) + ";");
}

if (label != null)
{
if (i == 0)
Expand Down Expand Up @@ -475,6 +492,9 @@ else if (prod instanceof action_production)
}
leftright = ", " + leftsym + ", " + rightsym;
}
if (after_reduce_code != null) {
out.println(after_reduce_code);
}
/* code to return lhs symbol */
out.println(" return parser.getSymbolFactory().newSymbol(" +
"\"" + prod.lhs().name() + "\", " +
Expand Down

0 comments on commit 7022406

Please sign in to comment.