Jison:区分数字和数字



我有一个最小的语法示例,我想在Jison中使用。

/* lexical grammar */
%lex
%%
s+                   /* skip whitespace */
[0-9]+("."[0-9]+)?b  return 'NUMBER'
[0-9]                 return 'DIGIT'
[,-]                  return 'SEPARATOR'
// EOF means "end of file"
<<EOF>>               return 'EOF'
.                     return 'INVALID'
/lex
%start expressions
%% /* language grammar */
expressions
    : e SEPARATOR d EOF
        {return $1;}
    ;
d
    : DIGIT
        {$$ = Number(yytext);}
    ;
e
    : NUMBER
        {$$ = Number(yytext);}
    ;

这里我定义了NUMBERDIGIT,以便根据上下文同时允许数字和数字。我不知道的是,我如何定义上下文。上面的例子总是返回

Expecting 'DIGIT', got 'NUMBER'

当我尝试在Jison调试器中运行它时。如何定义语法,以便总是期望分隔符后面有一个数字?我尝试了以下不工作

/* lexical grammar */
%lex
%%
s+                   /* skip whitespace */
[,-]                  return 'SEPARATOR'
// EOF means "end of file"
<<EOF>>               return 'EOF'
.                     return 'INVALID'
/lex
%start expressions
%% /* language grammar */
expressions
    : e SEPARATOR d EOF
        {return $1;}
    ;
d
    : [0-9]
        {$$ = Number(yytext);}
    ;
e
    : [0-9]+("."[0-9]+)?b
        {$$ = Number(yytext);}
    ;

经典的扫描器/解析器模型(最初来自lex/yacc,也由jison实现)将扫描器置于解析器之前。换句话说,期望扫描器对输入流进行标记,而不考虑解析上下文

大多数词法扫描器生成器,包括jison,都为扫描器提供了一种适应上下文的机制(参见"开始条件"),但是扫描器要自己负责跟踪上下文,这就变得相当难看了。

在这种情况下,最简单的解决方案是只定义一个NUMBER令牌,并让解析器检查实际需要DIGIT的规则的语义动作的有效性。这将起作用,因为DIGITNUMBER之间的差异除了使某些解析非法之外不会影响解析。如果NUMBERDIGIT之间的差异决定了使用哪个产品,则会有所不同,但这可能是不明确的,因为所有数字实际上也是数字。

另一个解决方案是允许NUMBERDIGIT,其中一个数字是允许的。这将需要更改e,使其接受NUMBERDIGIT,并确保DIGITNUMBERDIGIT都可能的情况下胜出。这需要将其规则放在语法文件的前面,并在末尾添加b:

[0-9]b               return 'DIGIT'
[0-9]+("."[0-9]+)?b  return 'NUMBER'

相关内容

  • 没有找到相关文章

最新更新