определить грамматику в Antlr - PullRequest
0 голосов
/ 28 декабря 2010

Я определил следующую грамматику.

grammar Sample_1;


@header {
  package a;
}

@lexer::header {
  package a;
}

program
    :   
        define*
        implement*
    ;


define
    :   IDENT '=(' INTEGER',' INTEGER ')'
    ;

implement
    :IDENT '=(' (IDENT ','?)* ')'
    ;

fragment LETTER : ('a'..'z' | 'A'..'Z') ;
fragment DIGIT : '0'..'9';
INTEGER : DIGIT+ ;
IDENT : LETTER (LETTER | DIGIT)*;
WS : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;};
COMMENT : '//' .* ('\n'|'\r') {$channel = HIDDEN;};

Как проверить эту грамматику, чтобы при наличии примера

A=(1,1)
B=(1,2)

G=(A,B)

результат был успешным, но если я напишу

A=(1,1)
B=(1,2)

G=(A,E)

выдает ошибку, что E не определено благодаря

результат: у меня все получилось благодаря большое:

grammar Sample_1;

@members{
    int level=0;
}

@header {
  package a;
}

@lexer::header {
  package a;
}

program
    :   
        block
    ;
block   
scope {
    List symbols;
}
@init {
    $block::symbols=new ArrayList();
    level++;
}
@after { 
     System.err.println("Hello");
     level--;
 }
    : (define* implement+)
    ;

define
    :   IDENT {$block::symbols.add($IDENT.text);} '=(' INTEGER',' INTEGER ')' 
    ;

implement
    :IDENT '=(' (a=IDENT 
    {if (!$block::symbols.contains($a.text)){
    System.err.println("undefined");
    }}','?)* ')'
    ;

fragment LETTER : ('a'..'z' | 'A'..'Z') ;
fragment DIGIT : '0'..'9';
INTEGER : DIGIT+ ;
IDENT : LETTER (LETTER | DIGIT)*;
WS : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;};
COMMENT : '//' .* ('\n'|'\r') {$channel = HIDDEN;};

1 Ответ

3 голосов
/ 28 декабря 2010

Antlr поддерживает действия , небольшие фрагменты кода, встроенные в файл грамматики.

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

Глава 6 Терренса Парра "Полное руководство по ANTLR" охватывает действия.

...