Antlr не соответствует «›» для включения макроса

Я начал работать с antlr несколько дней назад. Я хотел бы использовать его для анализа макросов #include в c. Меня интересуют только включения, все остальные части не имеют значения. здесь я написал простой файл грамматики:

... parser part omitted...

INCLUDE : '#include';
INCLUDE_FILE_QUOTE:  '"'FILE_NAME'"';
INCLUDE_FILE_ANGLE:  '<'FILE_NAME'>';

fragment
FILE_NAME: ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.'|' ')+;

MACROS: '#'('if' | 'ifdef' | 'define' | 'endif' | 'undef' | 'elif' | 'else' );
//MACROS: '#'('a'..'z'|'A'..'Z')+;

OPERATORS: ('+'|'-'|'*'|'/'|'='|'=='|'!='|'>'|'>='|'<'|'<='|'>>'|'<<'|'<<<'|'|'|'&'|','|';'|'.'|'->'|'#');

... other supporting tokens like ID, WS and COMMENT ...

Эта грамматика создает двусмысленность, когда встречаются такие утверждения:

(;i<listLength;i++)

output: mismatched character ';' expecting '>'

Кажется, он пытается сопоставить INCLUDE_FILE_ANGLE вместо обработки ";" как ОПЕРАТОРЫ.

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

Как я могу решить эту проблему с помощью Antlr?


person Defd    schedule 12.12.2013    source источник


Ответы (1)


Похоже, здесь не так много активности по поводу antlr.

Во всяком случае, я понял это.

INCLUDE_MACRO: ('#include')=>'#include';
VERSION_MACRO: ('#version')=>'#version';
OTHER_MACRO:   
     (
     |('#if')=>'#if'
     |('#ifndef')=>'#ifndef'
     |('#ifdef')=>'#ifdef'
     |('#else')=>'#else'
     |('#elif')=>'#elif'
     |('#endif')=>'#endif'
     );

Это решает только первую половину проблемы. Во-вторых, нельзя использовать INCLUDE_FILE_ANGLE для сопоставления с нужной строкой в ​​директиве #include. Материалы '‹'FILE_NAME'>' создают двусмысленность и должны быть разбиты на базовые токены из лексера или использовать более сложные контекстно-зависимые проверки. Я не знаком с более поздней техникой, поэтому я написал это в правиле парсера:

include_statement : 
    INCLUDE_MACRO include_file
    -> ^(INCLUDE_MACRO include_file);

include_file 
    : STRING
    | LEFT_ANGLE(INT|ID|OPERATORS)+RIGHT_ANGLE
    ;

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

person Defd    schedule 13.12.2013