Parsing 吉森:区分数字和数字

Parsing 吉森:区分数字和数字,parsing,grammar,bison,jison,Parsing,Grammar,Bison,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" <&

下面是我想与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);}
    ;
当我试着运行它的时候。如何定义语法,以便始终在分隔符后包含数字?我尝试了以下方法,但也不起作用

/* 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);}
    ;
/*词汇语法*/
%莱克斯
%%
\s+/*跳过空格*/
[,-]返回“分隔符”
//EOF表示“文件结束”
返回“EOF”
.                     返回“无效”
/莱克斯
%起始表达式
%%/*语言语法*/
表达
:e分离器d EOF
{返回$1;}
;
D
: [0-9]
{$$=Number(yytext);}
;
E
:[0-9]+(“[0-9]+)?\b
{$$=Number(yytext);}
;

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

大多数词汇扫描生成器,包括jison,都为扫描程序提供了一种适应上下文的机制(请参见“开始条件”),但是扫描程序自己负责跟踪上下文,这会变得非常糟糕

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

另一种解决方案是在允许数字的情况下,允许使用
数字
数字
。这将需要更改
e
,以便它接受
数字
数字
,并确保在
数字
数字
都可能的情况下,
数字
获胜。这需要将其规则放在语法文件的前面,并在末尾添加
\b

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

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

大多数词汇扫描生成器,包括jison,都为扫描程序提供了一种适应上下文的机制(请参见“开始条件”),但是扫描程序自己负责跟踪上下文,这会变得非常糟糕

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

另一种解决方案是在允许数字的情况下,允许使用
数字
数字
。这将需要更改
e
,以便它接受
数字
数字
,并确保在
数字
数字
都可能的情况下,
数字
获胜。这需要将其规则放在语法文件的前面,并在末尾添加
\b

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