Flex C++ печатает код в сгенерированном файле и добавляет цвет

Я пытаюсь вставить код, который читает flex, в мой файл .tex, это консольное приложение должно взять .pascal и проанализировать его, а затем сгенерировать файл .tex, но я не могу передать код в. tex, а затем мне нужно добавить цвет к каждому читаемому токену, мне нужна помощь !!

      %{ 
#include <iostream>   
#include <fstream>   
#include <string>   
using namespace std;   

int token_if = 0;   
%}


%%

if  ++token_if;
then|begin|end|procedure|function        {
                printf( "A keyword: %s\n", yytext );
                }
%%

int main(int argc, char *argv[]) 
{

    //read file
    FILE *fp;
    char filename[50], c;
    printf("Enter the filename: \n");
    scanf("%s",filename);
    fp = fopen(filename,"r");
    if (fp == NULL)
    {
        printf("file null");
        exit(0);
    } else 
    {
    yyin = fp;
    //start of lex
    yylex();    
    
    // counter
    //get_token(token_if);
    
    //create latex file
    ofstream myPDF("PDF.tex");

    myPDF  << " \\documentclass{article} "
            << "\\title{Scanner}"
            << "\\author{Andres}"
            << "\\date{III}"
            << " \\begin{document} "
            << "\\maketitle"
            << "\\newpage"
            << "\\section{¿Q?}"
            << " number of if's " 
            << token_if
            << " \\end{document} ";

        myPDF.close();

    }

    // printf("# of if's = %d",  token_if);   

    return 0;
}

1 ответ

  1. (F)lex предназначен для разделения ввода на последовательность токенов. Каждый символ на входе будет частью некоторого идентифицированного токена. То, что вы делаете с токенами, зависит от вас — вы можете просто игнорировать их, если они вас не интересуют — но (F)lex все равно их распознает.

    Список шаблонов, подобный тому, который вы показываете, явно не удовлетворяет этому требованию. По умолчанию, если вы даете (F)lex неисчерпывающий набор шаблонов, он добавляет в конце резервный шаблон, который соответствует любому отдельному символу, и назначает ему действие по умолчанию, то есть отправку символа в yyout(по умолчанию, stdout). Обычно это не то, что нужно, и это определенно не то, чего вы хотите.

    Нет параметра конфигурации (F)lex, который изменяет действие по умолчанию. Все, что вы можете сделать, это гарантировать, что он никогда не сработает, предоставив (F)lex набор шаблонов, которые гарантированно никогда не сработают. Вы можете сказать Flex, что вам не нужен шаблон по умолчанию (используя ); если вы это сделаете, и ваши шаблоны не являются исчерпывающими, тогда Flex выдаст предупреждение, и сканер немедленно прекратит работу, если он не сможет совпасть в какой-то момент сканирования.

    %option nodefaultнастоятельно рекомендуется именно потому, что действие по умолчанию редко требуется. Если вы используете эту опцию, вам нужно будет убедиться, что ваши шаблоны завершены; Самый простой способ сделать это — поместить свой собственный резервный шаблон в конец списка шаблонов с любым действием, которое кажется подходящим. Если, как я полагаю, вы не хотите ничего делать с токеном, вы можете использовать такое действие, как { }или же ;:

            .|\n        ;
    
  2. Обратите внимание, что (F)lex не делает никаких предположений о ваших шаблонах ввода. Например, он не предполагает, что вы хотите игнорировать пробелы (а может, и нет), и не предполагает, что вас интересует только строка как полное слово. Все это зависит от вас. Ваши скороговорки, как написано, с радостью узнают Eiffelа также semifredoкак экземпляры условного выражения Паскаля. Это, конечно, не то, чего вы хотите, и я подозреваю, что вы также не хотите признавать ifкогда он находится в комментарии или строковом литерале. Так что у вас еще есть над чем поработать над вашими шаблонами. (Обычное решение для сопоставления ключевых слов только тогда, когда они являются полными словами, состоит в том, чтобы также сопоставлять полные слова, используя такой шаблон, как [[:alpha:]][[:alnum:]]*. Этот шаблон идет после всех шаблонов ключевых слов, поэтому он будет срабатывать, если токен начинается с ключевого слова (поскольку (F)lex всегда выбирает самое длинное совпадение в каждой точке ввода), но не будет соответствовать, если токен точно соответствует ключевому слову. (поскольку Flex всегда выбирает первый из шаблонов, которые соответствуют одному и тому же самому длинному токену.) Стоит прочитать по крайней мере два раздела руководства Flex : Patterns и How input is matched.

  3. Если я правильно понимаю, что вы ищете, вы хотите знать, как вывести ввод в файл, пока Flex работает над ним. Одним из очевидных способов было бы записать каждый токен в файл, как вы его узнаете, что означает добавление шаблонного кода к каждому действию (даже к действиям, которые ничего не делают). вам придется сделать.

    Если вы просто хотите скопировать проанализированный файл в вывод, весь этот шаблон немного утомителен, поэтому вам, вероятно, лучше использоватьYY_USER_ACTIONmacro , который неявно раскрывается в начале каждого действия правила (даже для правил с пустыми действиями). Обратите внимание, что вам придется открыть выходной файл перед вызовом yylex, а также выпишите любые коды, которые вам нужны, перед текстом программы. Вместо того, чтобы записывать каждый токен, вы можете копировать файл по мере его чтения Flex. Для этого вам нужно определитьYY_INPUTмакрос . (В связанном разделе руководства есть пример кода.)

Другие вопросы по тегам