【发布时间】:2015-12-17 21:22:27
【问题描述】:
我正在编写一个词法分析器来扫描 INI 文件的修改版本。
我需要识别要分配给变量的变量、cmets 和字符串(在双引号之间)的声明。例如,这是正确的:
# this is a comment
var1 = "string value"
我已经成功地识别出这些标记,它们在评论正则表达式的乞求处强制使用#,在字符串正则表达式的末尾强制使用",但我不想这样做,因为稍后会,使用 Bison,我得到的令牌正好是 # this is a comment 和 "string value"。相反,我想要this is a comment(没有#)和string value(没有")
这些是我目前使用的正则表达式:
[a-zA-Z][a-zA-Z0-9]* { return TOKEN_VAR_NAME; }
["][^\n\r]*["] { return TOKEN_STRING; }
[#][^\n\r]* { return TOKEN_COMMENT; }
显然,在字符串、注释以及变量名和=之间可以有任意数量的空格和制表符。
我怎样才能达到我想要的结果?
如果我向您展示一个正确输入文件的完整示例以及我在 Flex 和 Bison 中使用的语法规则,也许会更容易。
正确的输入文件示例:
[section1]
var1 = "string value"
var2 = "var1 = text"
# this is a comment
# var5 = "some text" this is also a valid comment
这些是词法分析器的正则表达式:
"[" { return TOKEN::SECTION_START; }
"]" { return TOKEN::SECTION_END; }
"=" { return TOKEN::ASSIGNMENT; }
[#][^\n\r]* { return TOKEN::COMMENT; }
[a-zA-Z][a-zA-Z0-9]* { *m_yylval = yytext; return TOKEN::ID; }
["][^\n\r]*["] { *m_yylval = yytext; return TOKEN::STRING; }
这些是语法规则:
input : input line
| line
;
line : section
| value
| comment
;
section : SECTION_START ID SECTION_END { createNewSection($2); }
;
value : ID ASSIGNMENT STRING { addStringValue($1, $3); }
;
comment : COMMENT { addComment($1); }
;
【问题讨论】:
-
似乎使用词法分析器必须解析每个字符。我不知道使用环视断言是否可行。因此,您可能必须使用
["]和使用[#]的COMMENT_START 来维持STRING_START(和结束)状态。此外,要获取简单字符串的内容(对转义引号一无所知),您将使用[^"]*跨行(即,不是[^\n\r]*)
标签: regex string flex-lexer