如何使用lex与C源文件?

时间:2014-02-28 21:20:18

标签: c parsing token lex

我需要为C语言编写一个简单的标记化器。它不必对事物进行分类,也不必使用任何语法。它需要做的就是单独打印单词,字符,括号和其他内容。我正在使用lex。但我需要读取一个C源文件,然后对其进行标记。您可以在下面找到我当前的代码。我有三个问题。

1)如何更正编译时收到的错误消息:

  

parser.l:47:1:警告:未知转换类型字符'='in   格式[-Wformat]

2)如何让lexer在作为参数传递的源文件上运行?

3)如何让tokenizer打印变量和其他未指定的东西的名称?这意味着如果我有,int测试,它将打印int,因为它是在词法分析器中指定的,我也想单独打印测试,因为它没有在lex中指定。

这是我的代码:

%{
#include <stdio.h>
#include <stdlib.h>
%}

%%

"auto"          { printf("auto\t"); }
"break"         { printf("break\t"); }
"case"          { printf("case\t"); }
"char"          { printf("char\t"); }
"const"         { printf("const\t"); }
"continue"      { printf("continue\t"); }
"default"       { printf("default\t"); }
"do"            { printf("do\t"); }
"double"        { printf("double\t"); }
"else"          { printf("else\t"); }
"enum"          { printf("enum\t"); }
"extern"        { printf("extern\t"); }
"float"         { printf("float\t"); }
"for"           { printf("for\t"); }
"goto"          { printf("goto\t"); }
"if"            { printf("if\t"); }
"inline"        { printf("inline\t"); }
"int"           { printf("int\t"); }
"long"          { printf("long\t"); }
"printf"        { printf("printf\t"); }
"register"      { printf("register\t"); }
"restrict"      { printf("restrict\t"); }
"return"        { printf("return\t"); }
"short"         { printf("short\t"); }
"signed"        { printf("signed\t"); }
"sizeof"        { printf("sizeof\t"); }
"static"        { printf("static\t"); }
"struct"        { printf("struct\t"); }
"switch"        { printf("switch\t"); }
"typedef"       { printf("typedef\t"); }
"union"         { printf("union\t"); }
"unsigned"      { printf("unsigned\t"); }
"void"          { printf("void\t"); }
"volatile"      { printf("volatile\t"); }
"while"         { printf("while\t"); }
"+="            { printf("+=\t"); }
"-="            { printf("-=\t"); }
"*="            { printf("*=\t"); }
"/="            { printf("/=\t"); }
"%="            { printf("%=\t"); }
"&="            { printf("&=\t"); }
"^="            { printf("^=\t"); }
"|="            { printf("|=\t"); }
"++"            { printf("++\t"); }
"--"            { printf("--\t"); }
"->"            { printf("->\t"); }
"&&"            { printf("&&\t"); }
"||"            { printf("||\t"); }
"<="            { printf("<=\t"); }
">="            { printf(">=\t"); }
"=="            { printf("==\t"); }
"!="            { printf("!=\t"); }
"{"         { printf("{\t"); }
"}"         { printf("}\t"); }
"="         { printf("=\t"); }
"("         { printf("(\t"); }
")"         { printf(")\t"); }
"["         { printf("[\t"); }
"]"         { printf("]\t"); }
"<"         { printf("<\t"); }
">"         { printf(">\t"); }

%%

void main(int argc, char** argv)
{
    if(argc != 2)
    {
        printf("Usage: %s filename\n", argv[0]);
        exit(1);
    }

    char *filename = argv[1];
    FILE *f = fopen(filename, "r");

    if(f == NULL)
    {
        fprintf(stderr, "Unable to open %s\n", filename);
    }
    else
    {
        yylex();
    }
}

3 个答案:

答案 0 :(得分:1)

Q1。您的警告来自这一行:

"%="            { printf("%=\t"); }

你想:

"%="            { printf("%%=\t"); }

因为你需要逃避'%'。

Q2。要让lex从给定文件中读取,您需要使用yyin - 有关详细信息,请参阅in lex how to make yyin point to a file with the main function in yacc?

Q3。您需要使用正则表达式来匹配它们。例如,请参阅https://www.cs.princeton.edu/~appel/modern/c/software/flex/flex.html

答案 1 :(得分:0)

void main(int argc, char** argv)
{
    if (argc > 1)
    {
        FILE *file;
        file = fopen(argv[1], "r");      
        if (!file)
        {
            fprintf(stderr, "Could not open %s\n", argv[1]);
            exit(1);
        }
        yyin = file;
    }
    yylex();
}

答案 2 :(得分:0)

要打印标识符,您可以使用下面的正则表达式

public static byte[] tiles;
//...
//here you add some tiles
//...
PrintWriter writer = new PrintWriter("mytxtdocument.txt", "UTF-8");
for(int i = 0; i < tiles.length; i++) {
        writer.println("BYTE: " + tiles[i]);
}
writer.close();

在规则末尾包含此内容,以便正确识别所有其他已定义的规则,而不是始终作为标识符打印。