-1

我正在尝试将 flex 读取的代码插入到我的 .tex 文件中,这个控制台应用程序应该采用 .pascal 并对其进行分析,然后生成一个 .tex 文件,但我无法将代码传递给 . tex 文件,然后我需要为它读取的每个标记添加颜色,我需要帮助!编译它的命令 flex file.l, g++ lex.yy.c, ./a.out, test.pascal, pdflatex PDF.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;
}
4

1 回答 1

0
  1. (F)lex 旨在将输入拆分为一系列标记。输入中的每个字符都将是某些已识别标记的一部分。你对令牌做什么取决于——如果它们不感兴趣,你可以忽略它们——但 (F)lex 仍然会识别它们。

    像您展示的那样的模式列表显然不能满足这一要求。默认情况下,如果您给 (F)lex 一组非详尽的模式,它会在末尾添加一个回退模式,该模式匹配任何单个字符,并为其分配默认操作,即将字符发送到yyout(默认情况下, stdout)。这通常不是你想要的,也绝对不是你想要的。

    没有 (F)lex 配置选项可以更改默认操作。您所能做的就是确保它永远不会触发,方法是为 (F)lex 提供一组保证永远不会失败的模式。你可以告诉 Flex 你不想要它的默认模式(使用%option nodefault);如果您这样做并且您的模式不是详尽无遗的,那么 Flex 将产生警告,并且如果在扫描中的某个点无法匹配,扫描仪将立即终止。

    %option nodefault强烈推荐,正是因为很少需要默认操作。如果您使用该选项,则需要确保您的模式是完整的;最简单的方法是将您自己的后备模式放在模式列表的末尾,并采取任何看起来合适的操作。如果,正如我所想的那样,您不想对令牌做任何事情,您可以使用类似{ }or的操作;

    .|\n        ;
    
  2. 请注意, (F)lex 不对您的输入模式做出任何假设。例如,它不会假设您想忽略空格(也许您不想),也不会假设您只对if作为完整单词的字符串感兴趣。这一切都取决于你。正如所写的那样,您的模式将很高兴地将其识别为 Pascal 条件的实例Eiffelsemifredo这肯定不是您想要的,我怀疑您也不想识别if它何时出现在评论或字符串文字中。所以你在你的模式上还有很多工作要做。(仅当关键字是完整单词时才匹配关键字的通常解决方案是也匹配完整单词,使用类似的模式[[:alpha:]][[:alnum:]]*。该模式在所有关键字模式之后,带有关键字(因为 (F)lex 总是在输入中的每个点选择最长的匹配项),但如果标记恰好是关键字,则不会匹配(因为 Flex 总是选择匹配相同最长标记的模式中的第一个。 ) 至少值得阅读Flex 手册的两个部分:模式输入匹配方式。

  3. 如果我正确理解了您要查找的内容,您想知道如何在 Flex 处理输入时将输入转储到文件中。一种明显的方法是将每个标记写入文件,因为您识别它,这意味着将样板代码添加到每个操作(甚至是什么都不做的操作。)如果您尝试做的是对每个标记进行颜色编码,那就是你将不得不做。

    如果您只想将解析后的文件复制到输出,那么所有样板文件都有些乏味,因此您最好使用YY_USER_ACTION,它在每个规则操作的开头隐式扩展(即使对于具有空操作的规则) )。请注意,您必须在调用之前打开输出文件yylex,并在程序文本之前写出您需要的任何代码。您可以选择在 Flex 读取文件时复制文件,而不是写出每个令牌。为此,您需要定义YY_INPUT。(链接的手册部分中有一些示例代码。)

于 2021-12-07T22:27:17.900 回答