我需要为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();
}
}
答案 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();
在规则末尾包含此内容,以便正确识别所有其他已定义的规则,而不是始终作为标识符打印。