flex-lexer - 处理 yyless 在 yacc 的开始条件内返回的字符
问题描述
对于下面的代码片段,“CC=gcc\n”的输入不会触发 {EQ} 的“ASSN:=”块 - 我不明白为什么会这样,因为它正在传递等号字符正在由 {CHAR} 的下一条规则处理。
当等号字符被 yyless '推回'时,如何确保处理 {EQ} 规则?
byacc 代码几乎是空的,只有一个虚拟规则,但有相关的 %token 行。
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include "y.tab.h"
extern YYSTYPE yylval;
%}
%x ASSIGNMENT
%option noyywrap
DIGIT [0-9]
ALPHA [A-Za-z]
SPACE [ ]
TAB [\t]
WS [ \t]+
NEWLINE (\n|\r|\r\n)
IDENT [A-Za-z_][A-Za-z_0-9]+
EQ =
CHAR [^\r\n]+
%%
<*>"#"{CHAR}{NEWLINE}
({IDENT}{EQ})|({IDENT}{WS}{EQ}) {
yylval.strval = strndup(yytext,
strlen(yytext)-1);
printf("NORM: %s\n", yylval.strval);
yyless(strlen(yytext)-1);
BEGIN(ASSIGNMENT);
return TOK_IDENT;
}
<ASSIGNMENT>{
{EQ} {
printf("ASSN: =\n");
return TOK_ASSIGN;
}
{CHAR} {
printf("ASSN: %s\n", yytext);
return TOK_STRING;
}
{NEWLINE} {
BEGIN(INITIAL);
}
}
{WS}
{NEWLINE}
. {
printf("DOT : %s\n", yytext);
}
<*><<EOF>> {
printf("EOF\n");
return 0;
}
%%
int main()
{
printf("Start\n\n");
int ret;
while( (ret = yylex()) ) {
printf("LEX : %u\n", ret);
}
printf("\nEnd\n");
}
示例输出:
Start
NORM: CC
LEX : 257
ASSN: =gcc
LEX : 259
EOF
End
解决方案
我的问题是 flex首先匹配最长的规则,所以 {CHAR} 总是胜过 {EQ}。我通过引入另一个开始条件来使用 {EQ}{WS}? 在传递给之前
推荐阅读
- function - 递归函数何时优于其迭代版本?
- python - Pynmea2 AttributeError `NoneType` 对象没有属性 `num_sats`
- mysql - 有没有办法使用 sql 获取最佳记录
- ruby - Travis CI SonarCloud - 如何选择要启用的质量配置文件?
- php - php新手并坚持错误(解析错误:语法错误,意外$'message'(T_VARIABLE)
- build.gradle - Gradle Kotlin Build Script 无法获取 SpringBoot Lib
- python - 我可以使用 onkey 事件将值打印到带有海龟图形的控制台吗?
- terraform - Terraform Unsupported block error for selector in kubernetes_service resource
- android - IONIC 4 - How to release apk for Android 4.1.x (API level 16)?
- php - mysqli_connect() mysqli_connect(): (HY000/2002): 从其他php文件调用时没有这样的文件或目录错误