Лекс: несколько файлов, разные правила - PullRequest
1 голос
/ 03 мая 2011

Мне нужно проанализировать более одного файла с разными правилами для каждого случая. То есть: мне нужны некоторые правила, чтобы работать при обработке файла и впоследствии быть отключенным.

Я мог бы просто использовать глобальную переменную для отслеживания состояния программы, и мои правила решали бы внутри себя, делать ли что-нибудь полезное или нет, например:

%{
    static int state;
%}

%%
{something} {
    if (state == SOMETHING_STATE) ...
}

{something_else} {
    if (state == SOMETHING_ELSE_STATE) ...
}
%%

Полагаю, есть лучший способ сделать это. Есть ли?

Ответы [ 3 ]

1 голос
/ 03 мая 2011

Если вы используете что-то вроде Flex, а не оригинальный lex, вы можете использовать start states.Когда вы анализируете что-то, что меняет способ анализа, вы вводите состояние для этого анализа и помечаете соответствующие правила этим состоянием.Когда вы анализируете все, что отмечает конец этого состояния, вы делаете другое:

{state_signal} { BEGIN(STATE2); }

<STATE2>{something} { handle_something(); }

<STATE2>{state3_signal} { BEGIN(STATE3); }

<STATE3>{something} {handle_something2(); }
<STATE3>{whatever} { BEGIN(START); }
1 голос
/ 03 мая 2011

Вы хотите стартовые состояния - в основном, у lex есть встроенная переменная state, и вы можете аннотировать правила как срабатывание только в определенных состояниях

%s state1
%s state2
%s state3

%%

<state1>{something}    { // this rule matches only in state1
                         // change to state2
                         BEGIN(state2); }

<state1,state3>{something_else}   { // this rule matches in state1 or state 3 }

{more_stuff}        { // this rule matches in all states }

Документацию по этому вопросу можно найти в любой книге по lex или flexили в онлайн-документации по флексу

0 голосов
/ 03 мая 2011

Используя Flex и Yacc, вы также можете создавать разные отдельные парсеры и настраивать make-файл, чтобы скомпилировать их в один исполняемый файл.Я полагаю, что вы используете только Flex, но это тоже возможно.

Я не могу точно определить, как это сделать сейчас, но я уже фактически сделал это, довольно давно, поэтому, если вы посмотрите вокруг, вы найдете способ.По сути, вам придется скомпилировать каждый анализатор с префиксом (-P), который будет генерировать функции анализа с разными именами и глобальные переменные с различными именами для использования анализаторами.

...