1

到目前为止,我正在尝试为 javascript 标识符编写一个解析器,这就是我所拥有的:

// All this rules have string as attribute.
identifier_ = identifier_start
    >> 
    *(
        identifier_part >> -(qi::char_(".") > identifier_part)                      
     )
;
identifier_part = +(qi::alnum | qi::char_("_"));
identifier_start = qi::char_("a-zA-Z$_");

此解析器适用于我的测试中的“良好标识符”列表:

"x__",
"__xyz",
"_",
"$",
"foo4_.bar_3",
"$foo.bar",
"$foo",
"_foo_bar.foo",
"_foo____bar.foo"

但我在使用其中一个错误标识符时遇到了问题:foo$bar. 这应该是失败的,但它成功了!!并且 sintetized 属性具有值"foo"

这是调试输出foo$bar

<identifier_>
    <try>foo$bar</try>
    <identifier_start>
        <try>foo$bar</try>
        <success>oo$bar</success>
        <attributes>[[f]]</attributes>
    </identifier_start>
    <identifier_part>
        <try>oo$bar</try>
        <success>$bar</success>
        <attributes>[[f, o, o]]</attributes>
    </identifier_part>
    <identifier_part>
        <try>$bar</try>
        <fail/>
    </identifier_part>
  <success>$bar</success>
  <attributes>[[f, o, o]]</attributes>
</identifier_>

我想要的是解析器在解析时失败,foo$bar但在解析时没有$foobar

我错过了什么?

4

1 回答 1

2

您不需要解析器需要消耗所有输入。

当规则在$符号之前停止匹配时,它会返回成功,因为没有任何东西说它不能跟在$符号后面。因此,您想断言它后面没有可能是标识符一部分的字符:

identifier_ = identifier_start
    >> 
    *(
        identifier_part >> -(qi::char_(".") > identifier_part)                      
     ) >> !identifier_start
;

相关指令distinct来自 Qi 存储库: http: //www.boost.org/doc/libs/1_55_0/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html

于 2014-07-03T21:19:05.793 回答