Почему Antlr считает, что отсутствует скобка? - PullRequest
1 голос
/ 14 июля 2011

Я создал грамматику для разбора простого синтаксиса запроса ldap. Грамматика:

expression   :   LEFT_PAREN! ('&' | '||' | '!')^ (atom | expression)* RIGHT_PAREN! EOF ;

atom    :   LEFT_PAREN! left '='^ right RIGHT_PAREN! ;

left    :   ITEM;
right   :   ITEM;

ITEM        :   ALPHANUMERIC+; 
LEFT_PAREN  :   '(';
RIGHT_PAREN :   ')';

fragment ALPHANUMERIC
    :   ('a'..'z' | 'A'..'Z' | '0'..'9'); 

WHITESPACE : (' ' | '\t' | '\r' | '\n') { skip(); };

Теперь эта грамматика отлично работает для:

(!(attr=hello2))
(&(attr=hello2)(attr2=12))
(||(attr=hello2)(attr2=12))

Однако, когда я пытаюсь запустить:

(||(attr=hello2)(!(attr2=12)))

Ошибка: строка 1:29 постороннего ввода ')', ожидающая EOF

Если я удаляю EOF из грамматики выражения, все проходит, но тогда неправильные числа скобок не распознаются как синтаксическая ошибка. (Это разбирается на дерево, отсюда ^ и! После токенов) Что я пропустил?

Ответы [ 2 ]

4 голосов
/ 14 июля 2011

Как уже упоминалось другими, ваше выражение должно заканчиваться EOF, но вложенное выражение, конечно, не может заканчиваться EOF.

Удалите EOF из expression и создайте правильную "точку входа" для вашего анализатора, которая заканчивается на EOF.

файл: T.g

grammar T;

options {
  output=AST;
}

parse
  :  expression EOF!
  ;

expression
  :  '('! ('&' | '||' | '!')^ (atom | expression)* ')'!
  ;

atom
  :  '('! ITEM '='^ ITEM ')'!
  ;

ITEM        
  :  ALPHANUMERIC+
  ;

fragment ALPHANUMERIC
  :  ('a'..'z' | 'A'..'Z' | '0'..'9')
  ;

WHITESPACE 
  :  (' ' | '\t' | '\r' | '\n') { skip(); }
  ;

файл: Main.java

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;

public class Main {
  public static void main(String[] args) throws Exception {
    String source = "(||(attr=hello2)(!(attr2=12)))";
    TLexer lexer = new TLexer(new ANTLRStringStream(source));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    CommonTree tree = (CommonTree)parser.parse().getTree();
    DOTTreeGenerator gen = new DOTTreeGenerator();
    StringTemplate st = gen.toDOT(tree);
    System.out.println(st);
  }
}

Чтобы запустить демонстрацию, выполните:

* NIX / MacOS:

java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main

Windows

java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .;antlr-3.3.jar Main

, который выдает код DOT, представляющий следующий AST:

enter image description here

изображение, созданное с использованием graphviz-dev.appspot.com

1 голос
/ 14 июля 2011

В вашем определении выражения могут быть круглые скобки, содержащие вложенное выражение, но вложенное выражение должно заканчиваться EOF.В вашем примере ввода вложенное выражение не заканчивается EOF.

...