如何捕获没有引号字符的字符串

时间:2011-11-21 18:11:28

标签: parsing f# lexical-analysis fsyacc fslex

我试图在没有引号的情况下捕获带引号的字符串。我有这个终端

%token <string> STRING

和这个制作

constant:
    | QUOTE STRING QUOTE { String($2) }

以及这些词法规则

| '\''       { QUOTE }
| [^ '\'']*  { STRING (lexeme lexbuf) } //final regex before eof

它似乎正在解释导致QUOTE作为单个词汇的所有内容,它无法解析。所以也许我的问题在语法的其他地方 - 不确定。我是以正确的方式来做这件事的吗?在我尝试从字符串中排除引号之前,它解析得很好。

更新

我认为以下词法分析器规则可能存在一些歧义

let name = alpha (alpha | digit | '_')*
let identifier = name ('.' name)*

以下规则优先于STRING

| identifier    { ID (lexeme lexbuf) }

有没有办法消除这些歧义而不在STRING正则表达式中包含引号?

3 个答案:

答案 0 :(得分:5)

在词法分析器中对字符串和数字文字这样的常量进行语义分析是很正常的,所以你可以考虑使用字符串常量的lex规则,如

| '\'' [^ '\'']* '\'' 
    { STRING (let s = lexeme lexbuf in s.Substring(1, s.Length - 2)) }

答案 1 :(得分:1)

您可以将lexeme与引号一起使用,但在解析器中修剪引号

Lexer:

let constant       = ("'" ([^ '\''])* "'")
...
| constant         { STRING(lexeme lexbuf) } 

分析器:

%token <string> STRING

...
constant:
    | STRING { ($1).Trim([|'''|]) }

如果您想从字符串中提取引号:

词法:

let name = alpha (alpha | digit | '_')*
let identifier = name ('.' name)*
...

| '\''       { QUOTE }
| identifier { ID (lexeme lexbuf) }
| _          { STRING (lexeme lexbuf) } 

标识符会从STRING中删除符号,所以 你的lexeme流可以是: QUOTE ID STRING ID .. QUOTE ,你必须在解析器中处理它:

分析器:

constant:
     | QUOTE content QUOTE     { String($2) }

content:
     | ID content      { $1+$2 }
     | STRING content  { $1+$2 }
     | ID              { $1 }
     | STRING          { $1 }

答案 2 :(得分:0)

我有类似的问题。我使用状态在“lexic.l”文件中捕获它们。 Here my autoanswer