Jison:区分数字和数字
Jison: Distinguishing between digits and numbers
我有以下最简单的语法示例,我想与 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 ;}
;
d
: DIGIT
{$$ = Number(yytext);}
;
e
: NUMBER
{$$ = Number(yytext);}
;
这里我定义了 NUMBER
和 DIGIT
以便根据上下文允许数字和数字。我不知道的是我如何定义上下文。上面的例子总是returns
Expecting 'DIGIT', got 'NUMBER'
当我尝试 运行 它时 Jison debugger。我怎样才能定义语法以便总是在分隔符之后有一个数字?我尝试了以下也不起作用
/* 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 ;}
;
d
: [0-9]
{$$ = Number(yytext);}
;
e
: [0-9]+("."[0-9]+)?\b
{$$ = Number(yytext);}
;
经典的 scanner/parser 模型(最初来自 lex/yacc,也由 jison 实现)将扫描器放在解析器之前。换句话说,扫描器应该在不考虑解析上下文.
的情况下标记输入流
大多数词法扫描器生成器,包括 jison,都为扫描器提供了一种适应上下文的机制(参见 "start conditions"),但扫描器负责自行跟踪上下文,这变得非常难看。
在这种情况下,最简单的解决方案是只定义一个 NUMBER
标记,并让解析器检查规则的语义操作的有效性,而这些规则实际上需要 DIGIT
。这将起作用,因为 DIGIT
和 NUMBER
之间的差异除了使某些解析非法之外不会影响解析。如果 NUMBER
和 DIGIT
之间的差异决定了使用哪个产品,那将是不同的,但这可能是模棱两可的,因为所有数字实际上也是数字。
另一种解决方案是在允许数字的地方允许 NUMBER
或 DIGIT
。这将需要更改 e
以便它接受 NUMBER
或 DIGIT
,并确保 DIGIT
在 NUMBER
和 [=12] 都存在的情况下获胜=] 是可能的。这需要将其规则放在语法文件的前面,并在末尾添加 \b
:
[0-9]\b return 'DIGIT'
[0-9]+("."[0-9]+)?\b return 'NUMBER'
我有以下最简单的语法示例,我想与 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 ;}
;
d
: DIGIT
{$$ = Number(yytext);}
;
e
: NUMBER
{$$ = Number(yytext);}
;
这里我定义了 NUMBER
和 DIGIT
以便根据上下文允许数字和数字。我不知道的是我如何定义上下文。上面的例子总是returns
Expecting 'DIGIT', got 'NUMBER'
当我尝试 运行 它时 Jison debugger。我怎样才能定义语法以便总是在分隔符之后有一个数字?我尝试了以下也不起作用
/* 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 ;}
;
d
: [0-9]
{$$ = Number(yytext);}
;
e
: [0-9]+("."[0-9]+)?\b
{$$ = Number(yytext);}
;
经典的 scanner/parser 模型(最初来自 lex/yacc,也由 jison 实现)将扫描器放在解析器之前。换句话说,扫描器应该在不考虑解析上下文.
的情况下标记输入流大多数词法扫描器生成器,包括 jison,都为扫描器提供了一种适应上下文的机制(参见 "start conditions"),但扫描器负责自行跟踪上下文,这变得非常难看。
在这种情况下,最简单的解决方案是只定义一个 NUMBER
标记,并让解析器检查规则的语义操作的有效性,而这些规则实际上需要 DIGIT
。这将起作用,因为 DIGIT
和 NUMBER
之间的差异除了使某些解析非法之外不会影响解析。如果 NUMBER
和 DIGIT
之间的差异决定了使用哪个产品,那将是不同的,但这可能是模棱两可的,因为所有数字实际上也是数字。
另一种解决方案是在允许数字的地方允许 NUMBER
或 DIGIT
。这将需要更改 e
以便它接受 NUMBER
或 DIGIT
,并确保 DIGIT
在 NUMBER
和 [=12] 都存在的情况下获胜=] 是可能的。这需要将其规则放在语法文件的前面,并在末尾添加 \b
:
[0-9]\b return 'DIGIT'
[0-9]+("."[0-9]+)?\b return 'NUMBER'