Skip to content

Commit b73ce28

Browse files
authored
Merge pull request #57 from javecs/feature/mul-div-op
演算子の * が / より優先されてしまう問題を修正しました。
2 parents d728f78 + 6ae0905 commit b73ce28

7 files changed

Lines changed: 84 additions & 181 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ plugins {
1616
}
1717

1818
group 'xyz.javecs.tools'
19-
version '0.2.2'
19+
version '0.2.3'
2020

2121
apply plugin: 'kotlin'
2222
apply plugin: 'antlr'

src/main/antlr/Expr.g4

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ stat: expr # StatExpr
66
;
77
expr: <assoc=right> expr '^' expr # Pow
88
| ('+'|'-') expr # Sign
9-
| expr '*' expr # Mul
10-
| expr '/' expr # Div
11-
| expr '%' expr # Mod
12-
| expr '+' expr # Add
13-
| expr '-' expr # Sub
9+
| expr op=('*'|'/'|'%') expr # MulDivMod
10+
| expr op=('+'|'-') expr # AddSub
1411
| ID '(' expr (',' expr)* ')' # Function
1512
| CONSTANT # Constant
1613
| NUMBER # Number

src/main/java/xyz/javecs/tools/expr/parser/ExprBaseVisitor.java

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,6 @@ public class ExprBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements E
3232
* {@link #visitChildren} on {@code ctx}.</p>
3333
*/
3434
@Override public T visitAssign(ExprParser.AssignContext ctx) { return visitChildren(ctx); }
35-
/**
36-
* {@inheritDoc}
37-
*
38-
* <p>The default implementation returns the result of calling
39-
* {@link #visitChildren} on {@code ctx}.</p>
40-
*/
41-
@Override public T visitDiv(ExprParser.DivContext ctx) { return visitChildren(ctx); }
42-
/**
43-
* {@inheritDoc}
44-
*
45-
* <p>The default implementation returns the result of calling
46-
* {@link #visitChildren} on {@code ctx}.</p>
47-
*/
48-
@Override public T visitAdd(ExprParser.AddContext ctx) { return visitChildren(ctx); }
4935
/**
5036
* {@inheritDoc}
5137
*
@@ -59,14 +45,7 @@ public class ExprBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements E
5945
* <p>The default implementation returns the result of calling
6046
* {@link #visitChildren} on {@code ctx}.</p>
6147
*/
62-
@Override public T visitSub(ExprParser.SubContext ctx) { return visitChildren(ctx); }
63-
/**
64-
* {@inheritDoc}
65-
*
66-
* <p>The default implementation returns the result of calling
67-
* {@link #visitChildren} on {@code ctx}.</p>
68-
*/
69-
@Override public T visitMod(ExprParser.ModContext ctx) { return visitChildren(ctx); }
48+
@Override public T visitMulDivMod(ExprParser.MulDivModContext ctx) { return visitChildren(ctx); }
7049
/**
7150
* {@inheritDoc}
7251
*
@@ -80,7 +59,7 @@ public class ExprBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements E
8059
* <p>The default implementation returns the result of calling
8160
* {@link #visitChildren} on {@code ctx}.</p>
8261
*/
83-
@Override public T visitMul(ExprParser.MulContext ctx) { return visitChildren(ctx); }
62+
@Override public T visitAddSub(ExprParser.AddSubContext ctx) { return visitChildren(ctx); }
8463
/**
8564
* {@inheritDoc}
8665
*

src/main/java/xyz/javecs/tools/expr/parser/ExprParser.java

Lines changed: 55 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -219,34 +219,6 @@ public void copyFrom(ExprContext ctx) {
219219
super.copyFrom(ctx);
220220
}
221221
}
222-
public static class DivContext extends ExprContext {
223-
public List<ExprContext> expr() {
224-
return getRuleContexts(ExprContext.class);
225-
}
226-
public ExprContext expr(int i) {
227-
return getRuleContext(ExprContext.class,i);
228-
}
229-
public DivContext(ExprContext ctx) { copyFrom(ctx); }
230-
@Override
231-
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
232-
if ( visitor instanceof ExprVisitor ) return ((ExprVisitor<? extends T>)visitor).visitDiv(this);
233-
else return visitor.visitChildren(this);
234-
}
235-
}
236-
public static class AddContext extends ExprContext {
237-
public List<ExprContext> expr() {
238-
return getRuleContexts(ExprContext.class);
239-
}
240-
public ExprContext expr(int i) {
241-
return getRuleContext(ExprContext.class,i);
242-
}
243-
public AddContext(ExprContext ctx) { copyFrom(ctx); }
244-
@Override
245-
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
246-
if ( visitor instanceof ExprVisitor ) return ((ExprVisitor<? extends T>)visitor).visitAdd(this);
247-
else return visitor.visitChildren(this);
248-
}
249-
}
250222
public static class FunctionContext extends ExprContext {
251223
public TerminalNode ID() { return getToken(ExprParser.ID, 0); }
252224
public List<ExprContext> expr() {
@@ -262,31 +234,18 @@ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
262234
else return visitor.visitChildren(this);
263235
}
264236
}
265-
public static class SubContext extends ExprContext {
237+
public static class MulDivModContext extends ExprContext {
238+
public Token op;
266239
public List<ExprContext> expr() {
267240
return getRuleContexts(ExprContext.class);
268241
}
269242
public ExprContext expr(int i) {
270243
return getRuleContext(ExprContext.class,i);
271244
}
272-
public SubContext(ExprContext ctx) { copyFrom(ctx); }
245+
public MulDivModContext(ExprContext ctx) { copyFrom(ctx); }
273246
@Override
274247
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
275-
if ( visitor instanceof ExprVisitor ) return ((ExprVisitor<? extends T>)visitor).visitSub(this);
276-
else return visitor.visitChildren(this);
277-
}
278-
}
279-
public static class ModContext extends ExprContext {
280-
public List<ExprContext> expr() {
281-
return getRuleContexts(ExprContext.class);
282-
}
283-
public ExprContext expr(int i) {
284-
return getRuleContext(ExprContext.class,i);
285-
}
286-
public ModContext(ExprContext ctx) { copyFrom(ctx); }
287-
@Override
288-
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
289-
if ( visitor instanceof ExprVisitor ) return ((ExprVisitor<? extends T>)visitor).visitMod(this);
248+
if ( visitor instanceof ExprVisitor ) return ((ExprVisitor<? extends T>)visitor).visitMulDivMod(this);
290249
else return visitor.visitChildren(this);
291250
}
292251
}
@@ -299,17 +258,18 @@ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
299258
else return visitor.visitChildren(this);
300259
}
301260
}
302-
public static class MulContext extends ExprContext {
261+
public static class AddSubContext extends ExprContext {
262+
public Token op;
303263
public List<ExprContext> expr() {
304264
return getRuleContexts(ExprContext.class);
305265
}
306266
public ExprContext expr(int i) {
307267
return getRuleContext(ExprContext.class,i);
308268
}
309-
public MulContext(ExprContext ctx) { copyFrom(ctx); }
269+
public AddSubContext(ExprContext ctx) { copyFrom(ctx); }
310270
@Override
311271
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
312-
if ( visitor instanceof ExprVisitor ) return ((ExprVisitor<? extends T>)visitor).visitMul(this);
272+
if ( visitor instanceof ExprVisitor ) return ((ExprVisitor<? extends T>)visitor).visitAddSub(this);
313273
else return visitor.visitChildren(this);
314274
}
315275
}
@@ -404,7 +364,7 @@ private ExprContext expr(int _p) throws RecognitionException {
404364
consume();
405365
}
406366
setState(19);
407-
expr(11);
367+
expr(8);
408368
}
409369
break;
410370
case 2:
@@ -480,93 +440,75 @@ private ExprContext expr(int _p) throws RecognitionException {
480440
break;
481441
}
482442
_ctx.stop = _input.LT(-1);
483-
setState(61);
443+
setState(52);
484444
_errHandler.sync(this);
485445
_alt = getInterpreter().adaptivePredict(_input,5,_ctx);
486446
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
487447
if ( _alt==1 ) {
488448
if ( _parseListeners!=null ) triggerExitRuleEvent();
489449
_prevctx = _localctx;
490450
{
491-
setState(59);
451+
setState(50);
492452
_errHandler.sync(this);
493453
switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
494454
case 1:
495455
{
496456
_localctx = new PowContext(new ExprContext(_parentctx, _parentState));
497457
pushNewRecursionContext(_localctx, _startState, RULE_expr);
498458
setState(41);
499-
if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)");
459+
if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)");
500460
setState(42);
501461
match(T__1);
502462
setState(43);
503-
expr(12);
463+
expr(9);
504464
}
505465
break;
506466
case 2:
507467
{
508-
_localctx = new MulContext(new ExprContext(_parentctx, _parentState));
468+
_localctx = new MulDivModContext(new ExprContext(_parentctx, _parentState));
509469
pushNewRecursionContext(_localctx, _startState, RULE_expr);
510470
setState(44);
511-
if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)");
471+
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
512472
setState(45);
513-
match(T__4);
473+
((MulDivModContext)_localctx).op = _input.LT(1);
474+
_la = _input.LA(1);
475+
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__5) | (1L << T__6))) != 0)) ) {
476+
((MulDivModContext)_localctx).op = (Token)_errHandler.recoverInline(this);
477+
}
478+
else {
479+
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
480+
_errHandler.reportMatch(this);
481+
consume();
482+
}
514483
setState(46);
515-
expr(11);
484+
expr(8);
516485
}
517486
break;
518487
case 3:
519488
{
520-
_localctx = new DivContext(new ExprContext(_parentctx, _parentState));
489+
_localctx = new AddSubContext(new ExprContext(_parentctx, _parentState));
521490
pushNewRecursionContext(_localctx, _startState, RULE_expr);
522491
setState(47);
523-
if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)");
492+
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
524493
setState(48);
525-
match(T__5);
526-
setState(49);
527-
expr(10);
528-
}
529-
break;
530-
case 4:
531-
{
532-
_localctx = new ModContext(new ExprContext(_parentctx, _parentState));
533-
pushNewRecursionContext(_localctx, _startState, RULE_expr);
534-
setState(50);
535-
if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)");
536-
setState(51);
537-
match(T__6);
538-
setState(52);
539-
expr(9);
494+
((AddSubContext)_localctx).op = _input.LT(1);
495+
_la = _input.LA(1);
496+
if ( !(_la==T__2 || _la==T__3) ) {
497+
((AddSubContext)_localctx).op = (Token)_errHandler.recoverInline(this);
540498
}
541-
break;
542-
case 5:
543-
{
544-
_localctx = new AddContext(new ExprContext(_parentctx, _parentState));
545-
pushNewRecursionContext(_localctx, _startState, RULE_expr);
546-
setState(53);
547-
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
548-
setState(54);
549-
match(T__2);
550-
setState(55);
551-
expr(8);
499+
else {
500+
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
501+
_errHandler.reportMatch(this);
502+
consume();
552503
}
553-
break;
554-
case 6:
555-
{
556-
_localctx = new SubContext(new ExprContext(_parentctx, _parentState));
557-
pushNewRecursionContext(_localctx, _startState, RULE_expr);
558-
setState(56);
559-
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
560-
setState(57);
561-
match(T__3);
562-
setState(58);
504+
setState(49);
563505
expr(7);
564506
}
565507
break;
566508
}
567509
}
568510
}
569-
setState(63);
511+
setState(54);
570512
_errHandler.sync(this);
571513
_alt = getInterpreter().adaptivePredict(_input,5,_ctx);
572514
}
@@ -593,41 +535,33 @@ public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
593535
private boolean expr_sempred(ExprContext _localctx, int predIndex) {
594536
switch (predIndex) {
595537
case 0:
596-
return precpred(_ctx, 12);
597-
case 1:
598-
return precpred(_ctx, 10);
599-
case 2:
600538
return precpred(_ctx, 9);
601-
case 3:
602-
return precpred(_ctx, 8);
603-
case 4:
539+
case 1:
604540
return precpred(_ctx, 7);
605-
case 5:
541+
case 2:
606542
return precpred(_ctx, 6);
607543
}
608544
return true;
609545
}
610546

611547
public static final String _serializedATN =
612-
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\20C\4\2\t\2\4\3\t"+
548+
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\20:\4\2\t\2\4\3\t"+
613549
"\3\4\4\t\4\3\2\6\2\n\n\2\r\2\16\2\13\3\3\3\3\3\3\3\3\5\3\22\n\3\3\4\3"+
614550
"\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4\34\n\4\f\4\16\4\37\13\4\3\4\3\4\3\4\3\4"+
615-
"\3\4\3\4\3\4\3\4\3\4\5\4*\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4"+
616-
"\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4>\n\4\f\4\16\4A\13\4\3\4\2\3\6\5\2"+
617-
"\4\6\2\3\3\2\5\6\2M\2\t\3\2\2\2\4\21\3\2\2\2\6)\3\2\2\2\b\n\5\4\3\2\t"+
618-
"\b\3\2\2\2\n\13\3\2\2\2\13\t\3\2\2\2\13\f\3\2\2\2\f\3\3\2\2\2\r\22\5\6"+
619-
"\4\2\16\17\7\17\2\2\17\20\7\3\2\2\20\22\5\6\4\2\21\r\3\2\2\2\21\16\3\2"+
620-
"\2\2\22\5\3\2\2\2\23\24\b\4\1\2\24\25\t\2\2\2\25*\5\6\4\r\26\27\7\17\2"+
621-
"\2\27\30\7\n\2\2\30\35\5\6\4\2\31\32\7\13\2\2\32\34\5\6\4\2\33\31\3\2"+
622-
"\2\2\34\37\3\2\2\2\35\33\3\2\2\2\35\36\3\2\2\2\36 \3\2\2\2\37\35\3\2\2"+
623-
"\2 !\7\f\2\2!*\3\2\2\2\"*\7\r\2\2#*\7\16\2\2$*\7\17\2\2%&\7\n\2\2&\'\5"+
624-
"\6\4\2\'(\7\f\2\2(*\3\2\2\2)\23\3\2\2\2)\26\3\2\2\2)\"\3\2\2\2)#\3\2\2"+
625-
"\2)$\3\2\2\2)%\3\2\2\2*?\3\2\2\2+,\f\16\2\2,-\7\4\2\2->\5\6\4\16./\f\f"+
626-
"\2\2/\60\7\7\2\2\60>\5\6\4\r\61\62\f\13\2\2\62\63\7\b\2\2\63>\5\6\4\f"+
627-
"\64\65\f\n\2\2\65\66\7\t\2\2\66>\5\6\4\13\678\f\t\2\289\7\5\2\29>\5\6"+
628-
"\4\n:;\f\b\2\2;<\7\6\2\2<>\5\6\4\t=+\3\2\2\2=.\3\2\2\2=\61\3\2\2\2=\64"+
629-
"\3\2\2\2=\67\3\2\2\2=:\3\2\2\2>A\3\2\2\2?=\3\2\2\2?@\3\2\2\2@\7\3\2\2"+
630-
"\2A?\3\2\2\2\b\13\21\35)=?";
551+
"\3\4\3\4\3\4\3\4\3\4\5\4*\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4"+
552+
"\65\n\4\f\4\16\48\13\4\3\4\2\3\6\5\2\4\6\2\4\3\2\5\6\3\2\7\t\2A\2\t\3"+
553+
"\2\2\2\4\21\3\2\2\2\6)\3\2\2\2\b\n\5\4\3\2\t\b\3\2\2\2\n\13\3\2\2\2\13"+
554+
"\t\3\2\2\2\13\f\3\2\2\2\f\3\3\2\2\2\r\22\5\6\4\2\16\17\7\17\2\2\17\20"+
555+
"\7\3\2\2\20\22\5\6\4\2\21\r\3\2\2\2\21\16\3\2\2\2\22\5\3\2\2\2\23\24\b"+
556+
"\4\1\2\24\25\t\2\2\2\25*\5\6\4\n\26\27\7\17\2\2\27\30\7\n\2\2\30\35\5"+
557+
"\6\4\2\31\32\7\13\2\2\32\34\5\6\4\2\33\31\3\2\2\2\34\37\3\2\2\2\35\33"+
558+
"\3\2\2\2\35\36\3\2\2\2\36 \3\2\2\2\37\35\3\2\2\2 !\7\f\2\2!*\3\2\2\2\""+
559+
"*\7\r\2\2#*\7\16\2\2$*\7\17\2\2%&\7\n\2\2&\'\5\6\4\2\'(\7\f\2\2(*\3\2"+
560+
"\2\2)\23\3\2\2\2)\26\3\2\2\2)\"\3\2\2\2)#\3\2\2\2)$\3\2\2\2)%\3\2\2\2"+
561+
"*\66\3\2\2\2+,\f\13\2\2,-\7\4\2\2-\65\5\6\4\13./\f\t\2\2/\60\t\3\2\2\60"+
562+
"\65\5\6\4\n\61\62\f\b\2\2\62\63\t\2\2\2\63\65\5\6\4\t\64+\3\2\2\2\64."+
563+
"\3\2\2\2\64\61\3\2\2\2\658\3\2\2\2\66\64\3\2\2\2\66\67\3\2\2\2\67\7\3"+
564+
"\2\2\28\66\3\2\2\2\b\13\21\35)\64\66";
631565
public static final ATN _ATN =
632566
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
633567
static {

0 commit comments

Comments
 (0)