Lex:收集规则中未定义的所有文本
Lex: Gather all text not defined in rules
我正在尝试将先前规则未定义的所有文本收集到一个字符串中,并使用 lex 为其添加格式化字符串前缀。我想知道是否有这样做的标准方法。
例如,假设我有规则:
word1|word2|word3|word4 {printf("%s%s", "<>", yytext);}
[0-9]+ {printf("%s%s", "{}", yytext);}
everything else {printf("%s%s", "[]", yytext);}
然后我尝试对字符串进行词法分析:
word1 this is some other text ; word2 98 foo bar .
我希望它在 运行 通过词法分析器时产生以下结果:
<>word1[] this is some other text ; <>word2[] {}98[] foo bar .
我尝试使用状态来执行此操作,但意识到我无法确定何时停止检查,例如:
%x OTHER
%%
. {yymore(); BEGIN OTHER;}
<OTHER>.|\n yymore();
<OTHER>how to determine when to end? {printf("%s%s", "[]", yytex); BEGIN INITIAL;}
执行此操作的好方法是什么?只要不满足另一条规则,是否有某种方式可以继续?
AFAIK,没有 "standard" 解决方案,但一个简单的方法是保留一些上下文(最后打印的前缀)并使用它来决定是否打印新前缀。例如,您可以使用这样的自定义打印机:
enum OutputType { NO_TOKEN = 0, WORD, NUMBER, OTHER };
void print_with_prefix(enum OutputType type, const char* token) {
static enum OutputType prev = NO_TOKEN;
const char* prefix = "";
switch (type) {
case WORD: prefix = "<>"; break;
case NUMBER: prefix = "{}"; break;
case OTHER: if (prev != OTHER) prefix = "[]"; break;
default: assert(false);
}
prev = type;
printf("%s%s", prefix, token);
}
然后您只需将对 printf
的调用更改为调用 print_with_prefix
(并且,如所写,提供枚举值而不是字符串)。
对于 OTHER
的情况,您不需要做任何特殊的事情来积累令牌。刚刚
. { print_with_prefix(OTHER, yytext); }
(我对空格和换行符的处理略过,但这只是概念上的。)
我正在尝试将先前规则未定义的所有文本收集到一个字符串中,并使用 lex 为其添加格式化字符串前缀。我想知道是否有这样做的标准方法。
例如,假设我有规则:
word1|word2|word3|word4 {printf("%s%s", "<>", yytext);}
[0-9]+ {printf("%s%s", "{}", yytext);}
everything else {printf("%s%s", "[]", yytext);}
然后我尝试对字符串进行词法分析:
word1 this is some other text ; word2 98 foo bar .
我希望它在 运行 通过词法分析器时产生以下结果:
<>word1[] this is some other text ; <>word2[] {}98[] foo bar .
我尝试使用状态来执行此操作,但意识到我无法确定何时停止检查,例如:
%x OTHER
%%
. {yymore(); BEGIN OTHER;}
<OTHER>.|\n yymore();
<OTHER>how to determine when to end? {printf("%s%s", "[]", yytex); BEGIN INITIAL;}
执行此操作的好方法是什么?只要不满足另一条规则,是否有某种方式可以继续?
AFAIK,没有 "standard" 解决方案,但一个简单的方法是保留一些上下文(最后打印的前缀)并使用它来决定是否打印新前缀。例如,您可以使用这样的自定义打印机:
enum OutputType { NO_TOKEN = 0, WORD, NUMBER, OTHER };
void print_with_prefix(enum OutputType type, const char* token) {
static enum OutputType prev = NO_TOKEN;
const char* prefix = "";
switch (type) {
case WORD: prefix = "<>"; break;
case NUMBER: prefix = "{}"; break;
case OTHER: if (prev != OTHER) prefix = "[]"; break;
default: assert(false);
}
prev = type;
printf("%s%s", prefix, token);
}
然后您只需将对 printf
的调用更改为调用 print_with_prefix
(并且,如所写,提供枚举值而不是字符串)。
对于 OTHER
的情况,您不需要做任何特殊的事情来积累令牌。刚刚
. { print_with_prefix(OTHER, yytext); }
(我对空格和换行符的处理略过,但这只是概念上的。)