Flex 扫描,区分字符串(单个 spaces)和填充(多个 space)
Flex scanning, differentiating between string (with single spaces) and padding (more than one space)
我在使用 flex 扫描看起来像这样的线时遇到问题
DESCRIPTION This is the device description
我希望扫描行时 DESCRIPTION 是一个标记,“This is the device description”是另一个.
我一直在无休止地玩我的规则,但似乎无法让它发挥作用。
根据文档,我认为我想使用
实施规则
`r/s'
an r but only if it is followed by an s
其中 space 仅被接受的是它们后面跟的不是 while space 的东西。我不知道如何用 flex 的语法来写这个规则。在我看来,规则应该是这样的
[a-zA-Z](" "/[a-zA-Z0-9]|[a-zA-Z0-9])* return IDENTIFIER;
但这是无效的。
我可以得到分割每个单词的行,但我无法得到区分 1 space 和 1 < space 的规则。哈尔普
这不太适合 flex,因为标记的识别是上下文相关的。您可以使用 start conditions 实现依赖于上下文的扫描,但过度使用启动条件通常表明其他扫描机制会更好。
不管你怎么做,关键是弄清楚确切地如何决定令牌划分。例如,考虑以下四行:
DEVICE This is the device
MODE This is the mode
DESCRIPTION This is the device description
UNDOCUMENTED FIELD
当然,有可能第三行和第四行所代表的极端情况永远不会出现在您的任何输入中。
如果第一个标记不能包含白色space,那么问题就相对简单了,尽管你仍然需要一个开始条件(我假设你阅读了上面链接的文档):
%x WHITE WORDS
%%
/* Possibly should be [[:alpha:]] instead of [[:upper:]] */
[[:upper:]]+ { /* copy yytext */; BEGIN(WHITE); return KEYWORD; }
/* Handle other possible line beginnings */
<WHITE>\n { /* Blank descriptive text */; BEGIN(INITIAL); }
<WHITE>[ \t]+ { BEGIN(WORDS); }
<WHITE>. { /* Something not correct in this line */; ... }
<WORDS>.+ { /* copy yytext */; BEGIN(INITIAL); return DESCRIPTION; }
<WORDS>\n { BEGIN(INITIAL); }
如果第一个标记中可能有白色space,但绝不会连续出现两个 space,您可以将上面的第一个模式替换为:
[[:alpha:]]+( [[:alpha:]]+)*
这将匹配任何单词序列(仅由字母组成),其中连续单词之间恰好有一个 space。与上面的原始模式一样,这将在找到的第一个非字母字符处结束。该错误将被 <WHITE>
中的规则检测到,因为当该开始条件变为活动状态时遇到的任何非白色 space 字符都将由开始条件的默认规则(<WHITE>.
规则处理).
我的意见是你在这里用错了马。 lex(flex)应该只用于词法分析,而 yacc(或 bison)用于句法分析。说一个字符不是分隔符而是多个字符是不适合词法分析器的。
我的意见是 lex 应该只报告单词和填充,而 yacc 稍后应该重新组合没有被填充元素分隔的单词。
lex 部分将简单如下:
[[:alnum:]_]+ {
// printf("WORD: >%s<\n", yytext); // for debugging
return WORD;
}
[[:blank:]]{2,} {
// printf("PADDING: >%s<\n", yytext);
return PADDING;
}
而 yacc 部分将包含:
elt: PADDING
| ident
ident: WORD
| ident WORD
action 此处省略,因为它们太依赖于您的实际处理。
我在使用 flex 扫描看起来像这样的线时遇到问题
DESCRIPTION This is the device description
我希望扫描行时 DESCRIPTION 是一个标记,“This is the device description”是另一个.
我一直在无休止地玩我的规则,但似乎无法让它发挥作用。
根据文档,我认为我想使用
实施规则`r/s' an r but only if it is followed by an s
其中 space 仅被接受的是它们后面跟的不是 while space 的东西。我不知道如何用 flex 的语法来写这个规则。在我看来,规则应该是这样的
[a-zA-Z](" "/[a-zA-Z0-9]|[a-zA-Z0-9])* return IDENTIFIER;
但这是无效的。
我可以得到分割每个单词的行,但我无法得到区分 1 space 和 1 < space 的规则。哈尔普
这不太适合 flex,因为标记的识别是上下文相关的。您可以使用 start conditions 实现依赖于上下文的扫描,但过度使用启动条件通常表明其他扫描机制会更好。
不管你怎么做,关键是弄清楚确切地如何决定令牌划分。例如,考虑以下四行:
DEVICE This is the device
MODE This is the mode
DESCRIPTION This is the device description
UNDOCUMENTED FIELD
当然,有可能第三行和第四行所代表的极端情况永远不会出现在您的任何输入中。
如果第一个标记不能包含白色space,那么问题就相对简单了,尽管你仍然需要一个开始条件(我假设你阅读了上面链接的文档):
%x WHITE WORDS
%%
/* Possibly should be [[:alpha:]] instead of [[:upper:]] */
[[:upper:]]+ { /* copy yytext */; BEGIN(WHITE); return KEYWORD; }
/* Handle other possible line beginnings */
<WHITE>\n { /* Blank descriptive text */; BEGIN(INITIAL); }
<WHITE>[ \t]+ { BEGIN(WORDS); }
<WHITE>. { /* Something not correct in this line */; ... }
<WORDS>.+ { /* copy yytext */; BEGIN(INITIAL); return DESCRIPTION; }
<WORDS>\n { BEGIN(INITIAL); }
如果第一个标记中可能有白色space,但绝不会连续出现两个 space,您可以将上面的第一个模式替换为:
[[:alpha:]]+( [[:alpha:]]+)*
这将匹配任何单词序列(仅由字母组成),其中连续单词之间恰好有一个 space。与上面的原始模式一样,这将在找到的第一个非字母字符处结束。该错误将被 <WHITE>
中的规则检测到,因为当该开始条件变为活动状态时遇到的任何非白色 space 字符都将由开始条件的默认规则(<WHITE>.
规则处理).
我的意见是你在这里用错了马。 lex(flex)应该只用于词法分析,而 yacc(或 bison)用于句法分析。说一个字符不是分隔符而是多个字符是不适合词法分析器的。
我的意见是 lex 应该只报告单词和填充,而 yacc 稍后应该重新组合没有被填充元素分隔的单词。
lex 部分将简单如下:
[[:alnum:]_]+ {
// printf("WORD: >%s<\n", yytext); // for debugging
return WORD;
}
[[:blank:]]{2,} {
// printf("PADDING: >%s<\n", yytext);
return PADDING;
}
而 yacc 部分将包含:
elt: PADDING
| ident
ident: WORD
| ident WORD
action 此处省略,因为它们太依赖于您的实际处理。