为 lex/yacc 中的可打印字符创建规则
Creating a rule for a printable character in lex/yacc
我想为可打印字符(使用 C isprint()
函数 returns true
的任何字符创建语法规则。
为此,我在 lex 文件中创建了以下正则表达式规则:
[\x20-\x7E] { yylval.ch = strdup(yytext); return CHARACTER; }
正则表达式包含基于 ASCII 十六进制值的所有可打印字符。
在我第一次尝试时,这条规则位于底部,但显然没有包括之前已经说明的任何可打印字符,例如,如果我输入的是字符 '+'
并且我之前有一个规则:
"+" { return PLUS_OPERATOR; }
解析器接受它作为 PLUS_OPERATOR
而不是 CHARACTER
。
然后我尝试将字符规则放在我的扫描仪顶部,出于与以前相同的原因 - 以下所有字符在可打印范围内的规则都无法匹配。
我的问题是如何创建既匹配所有可打印字符又匹配特定字符的规则。
我唯一能想到的就是把它放在底部,并使用所有单字符正则表达式规则和字符规则的语法规则(例如CHAR : PLUS_OPERATOR | MINUS_OPERATOR | EQUAL_OPERATOR | CHARACTER
)
我的 lex 文件中有超过 3 个单字符规则,所以显然我正在寻找更优雅的解决方案。
唯一的解决方案是您提出的解决方案:创建一个非终端,它是所有相关终端的联合。
就我个人而言,如果将单字符标记写成它们自己,我发现语法更易读,所以我会写:
printable: '+' | '-' | '=' | CHAR
在 bison 文件和扫描仪中:
[-+=] { yylval.ch = yytext[0]; return yylval.ch; }
[[:print:]] { yylval.ch = yytext[0]; return CHAR; }
(这又要求语义类型是 char 和 char* 字段的联合;优点是您无需担心释放为运算符字符创建的字符串。)
恐怕这已经是最优雅的了。
我想为可打印字符(使用 C isprint()
函数 returns true
的任何字符创建语法规则。
为此,我在 lex 文件中创建了以下正则表达式规则:
[\x20-\x7E] { yylval.ch = strdup(yytext); return CHARACTER; }
正则表达式包含基于 ASCII 十六进制值的所有可打印字符。
在我第一次尝试时,这条规则位于底部,但显然没有包括之前已经说明的任何可打印字符,例如,如果我输入的是字符 '+'
并且我之前有一个规则:
"+" { return PLUS_OPERATOR; }
解析器接受它作为 PLUS_OPERATOR
而不是 CHARACTER
。
然后我尝试将字符规则放在我的扫描仪顶部,出于与以前相同的原因 - 以下所有字符在可打印范围内的规则都无法匹配。
我的问题是如何创建既匹配所有可打印字符又匹配特定字符的规则。
我唯一能想到的就是把它放在底部,并使用所有单字符正则表达式规则和字符规则的语法规则(例如CHAR : PLUS_OPERATOR | MINUS_OPERATOR | EQUAL_OPERATOR | CHARACTER
)
我的 lex 文件中有超过 3 个单字符规则,所以显然我正在寻找更优雅的解决方案。
唯一的解决方案是您提出的解决方案:创建一个非终端,它是所有相关终端的联合。
就我个人而言,如果将单字符标记写成它们自己,我发现语法更易读,所以我会写:
printable: '+' | '-' | '=' | CHAR
在 bison 文件和扫描仪中:
[-+=] { yylval.ch = yytext[0]; return yylval.ch; }
[[:print:]] { yylval.ch = yytext[0]; return CHAR; }
(这又要求语义类型是 char 和 char* 字段的联合;优点是您无需担心释放为运算符字符创建的字符串。)
恐怕这已经是最优雅的了。