Можно ли понять, когда работают семантические предикаты, а когда нет?JAVA

Программисты JAVA общаются здесь
Anonymous
Можно ли понять, когда работают семантические предикаты, а когда нет?

Сообщение Anonymous »

Ниже приведены две грамматики. < /p>
В этой грамматике семантические предикаты выполняют «работу». Т.е. Если они ложные, правила не совпадают, и если они правда, правила соответствуют: < /p>
expr
: term
| expr asterisk expr (asterisk expr)*
| expr plus expr (plus expr)*
;

plus: {_input.LT(1).getText().equals("+")}? SPECID;
asterisk: {_input.LT(1).getText().equals("*")}? SPECID;

term
: ALNUMID
| STRID
| LPAREN expr RPAREN
;
< /code>
И в этой грамматике семантические предикаты не работают. Т.е. Если они ложны, правила по -прежнему совпадают с ошибкой BU. < /p>
expr
: add
| mult
| term
;

mult
: term (asterisk) term ((asterisk) term)*
;

add
: (term|mult) plus (term|mult) (plus (term|mult))*
;

plus: {_input.LT(1).getText().equals("+")}? SPECID;
asterisk: {_input.LT(1).getText().equals("*")}? SPECID;

term
: ALNUMID
| STRID
| LPAREN expr RPAREN
;

В обоих случаях я пытаюсь запустить простые тесты для анализа 2 + 2 и 2 * 2 .
Можно ли понять заранее, определение работы или нет? Какая логика здесь? Вот моя грамматика < /p>
expr
: add
| mult
| term
;

mult
: term asterisk term ((asterisk) term)*
;

add
: (term|mult) plus (term|mult) (plus (term|mult))*
;

plus
: {_input.LT(1).getText().equals("+")}? SPECID
| // Empty by design
;

asterisk
:
{_input.LT(1).getText().equals("*")}? SPECID
| // Empty by design
;

term
: ALNUMID
| STRID
| LPAREN expr RPAREN
;
< /code>
Вот код тестирования < /p>
public class MyParserTest {

private static MyParser parse(String input) {
CharStream charStream = CharStreams.fromString(input);

// Create lexer
MyLexer lexer = new MyLexer(charStream);

// Create token stream
CommonTokenStream tokens = new CommonTokenStream(lexer);

// Create parser
MyParser parser = new MyParser(tokens);

parser.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(Recognizer recognizer, Object offendingSymbol,
int line, int charPositionInLine, String msg,
RecognitionException e) {
System.err.println("Rule stack: " + ((Parser)recognizer).getRuleInvocationStack());
System.err.println("line " + line + ":" + charPositionInLine + " " + msg);

// Get and print all tokens
CommonTokenStream tokens = (CommonTokenStream) ((Parser)recognizer).getTokenStream();
tokens.fill();
System.err.println("Tokens:");
for (Token token : tokens.getTokens()) {
System.err.println(token);
}
}
});

// Parse starting at 'expr' rule
return parser;
}

private static String parseToLisp(String input) {
MyParser parser = parse(input);
return parser.expr().toStringTree(parser);
}

@Test
public void testSimpleMultiplication() throws Exception {
String value = "1 * 2";
String actual = parseToLisp(value);
String expected = "(expr (expr (term 1)) (mul *) (expr (term 2)))";

assertEquals(expected, actual);
}

@Test
public void testSimpleAddition() throws Exception {
String value = "1 + 2";
String actual = parseToLisp(value);
String expected = "(expr (add (term 1) (plus +) (term 2)))";

assertEquals(expected, actual);
}
< /code>
Вывод для умножения - < /p>
line 1:2 no viable alternative at input '*'
Rule stack: [plus, add, expr]
line 1:2 no viable alternative at input '*'
Tokens:
[@0,0:0='1',,1:0]
[@1,2:2='*',,1:2]
[@2,4:4='2',,1:4]
[@3,5:4='',,1:5]

Expected :(expr (expr (term 1)) (mul *) (expr (term 2)))
Actual :(expr (add (term 1) (plus *) (term 2)))


Подробнее здесь: https://stackoverflow.com/questions/794 ... n-they-don

Вернуться в «JAVA»