Повторяя одни и те же правила для нескольких строк ANTLR - PullRequest
0 голосов
/ 25 мая 2018

Я хотел знать, как правильно применять правила синтаксического анализа для нескольких строк с использованием ANTLR.Я использую приведенное ниже правило, которое отлично работает для однострочных операторов.Я хотел просто повторить это в следующих строках:

    grammar Condition;


/* Parser Rules */

condition : (expr+)? EOF;
expr
    : expr And expr         # andExpr
    | expr Or expr          # orExpr
    | LPar expr RPar        # parExpr
    | prop MIN Numerical expr       # eqExpr
    | prop some expr        # someExpr
    | prop only expr        # onlyExpr
    | prop value dataValue      # valueExpr
    | id                    # idExpr
    | not id                    # idExpr
    ;

id : Identifier;
prop:Identifier;
dataValue:Identifier;

/* Lexical Tokens */

And : 'AND';
Or : 'OR';
LPar : '(';
RPar : ')';
Equals : '=';
some : 'some';
only : 'only';
MIN : 'MIN';
value:'value';
not:'not';
NEWLINE: ('\n') { skip(); };

Numerical : [1-9] [0-9]*;
Data
    : [true]
    | [false]
    | [A]
    | [B]
    | [C]
    | [D]
    ;

// Using generic identifier tokens so that better warnings can be given in later passes.
Identifier : [a-zA-Z_] [a-zA-Z0-9_]*;

// Skip parsing of whitespace but save on hidden channel to enable retrieval of original string.
WhiteSpace : [ \t\r\n]+ -> channel(HIDDEN);

// Invalid character rule is used so that the lexer pass never fails.
InvalidChar : .;

Приведенная выше грамматика дает правильные результаты при тестировании, но когда я пытаюсь использовать посетителя, он потребляет каждый токен, он выдает следующую ошибку:

строка 2: 0 посторонний ввод «SafetyGoal», ожидающий {, 'И', 'ИЛИ}}

Есть предложения?

РЕДАКТИРОВАТЬ Ниже приведен код, который я использую для чтения входного файла и вызова кода посетителя:

Stream<String> stream = Files.lines( Paths.get("C:\\test\\RulesTest.txt"), StandardCharsets.UTF_8);
stream.forEach(s -> contentBuilder.append(s).append("\n"));
String input=contentBuilder.toString();
InputStream inStream = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8));
org.antlr.v4.runtime.ANTLRInputStream in=new org.antlr.v4.runtime.ANTLRInputStream(inStream);
System.out.println("These are the lines:"+contentBuilder);
ConditionLexer lexer=new ConditionLexer(in);
org.antlr.v4.runtime.CommonTokenStream tokens= new org.antlr.v4.runtime.CommonTokenStream(lexer);
ConditionParser parser=new ConditionParser(tokens);
ParseTree tree=parser.expr();
MyVisitor vis=new MyVisitor();
vis.visit(tree);

MyVisitor в основном содержит тот же код, что и сгенерированный ANTLR, где я сохраняю результаты в видеразбирает.

Ответы [ 2 ]

0 голосов
/ 25 мая 2018
ParseTree tree=parser.expr();

Вы используете правило expr, которое соответствует только одному выражению.Ваше правило condition совпадает с несколькими выражениями, поэтому вы должны вызывать это правило.

0 голосов
/ 25 мая 2018

Правило Data неверно: [true] соответствует одному символу (t, r, u или e).Сделайте это вместо этого:

Data
    : 'true'
    | 'false'
    | [A]
    | [B]
    | [C]
    | [D]
    ;

И testResult value true не соответствует вашей альтернативе prop value dataValue, потому что dataValue выглядит так:

dataValue : Identifier;

, где это должно выглядеть так (Я догадываюсь):

dataValue : Identifier | Data;

Когда я изменяю вашу грамматику, как указано выше, и анализирую ввод:

(FSR AND testedBy some (testResult value true)) 
SafetyGoal AND (fulfills some (not NR) OR fulfilledBy some NR)

, я получаю следующее дерево разбора:

enter image description here

...