在lex / yacc中为可打印字符创建规则

时间:2016-12-19 02:34:15

标签: regex parsing compilation bison flex-lexer

我想为可打印字符创建一个语法规则(任何使用C true函数返回isprint()的字符。

为此,我在我的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个字符规则,所以显然我正在寻找更优雅的解决方案。

1 个答案:

答案 0 :(得分:1)

唯一的解决方案是你建议的解决方案:创建一个非终端,它是所有相关终端的联合。

就个人而言,如果将单字符令牌作为自己编写,我发现语法更易读,所以我会写:

printable: '+' | '-' | '=' | CHAR

在野牛文件和扫描仪中:

[-+=]        { yylval.ch = yytext[0]; return yylval.ch; } 
[[:print:]]  { yylval.ch = yytext[0]; return CHAR; }

(这反过来要求语义类型是char和char *字段的并集;优点是您不必担心释放为运算符字符创建的字符串。)

这很优雅,我很害怕。