这是什么?寻找正确的术语这里发生了什么

时间:2015-05-16 17:20:55

标签: grammar terminology lexical-analysis chomsky-hierarchy

查看以下语法,就解析器生成器而言,它有一个明显的缺陷:

"Start Symbol" = <Foo>
"Case Sensitive" = True
"Character Mapping" = 'Unicode'

{A} = {Digit}
{B} = [abcdefABCDEF]
{C} = {A} + {B}

Integer = {A}+
HexNumber = {C}+


<ContextA> ::= '[' HexNumber ']'
<ContextB> ::= '{' Integer '}'                      
<Number> ::= <ContextA> | <ContextB>
<Foo> ::= <Number> <Foo>
       | <>

这种语法有缺陷的原因是,扫描仪无法区分终端[Integer;HexNumber]。 (1234是整数还是十六进制数??)。

在本例中编写的作品中,这与位无关,但可能存在语法,其中制作的上下文将阐明是否需要整数或十六进制数,并且扫描程序仍然拒绝协作。 / p>

因此,扫描程序需要知道解析器状态,以便能够对十六进制或整数标记做出正确的决定。

现在是术语的问题。这是怎么回事......呃......语法?词法?然后?一个上下文敏感的词法分析器?或者有人会说这是一个上下文敏感的语法,即使它显然是一个扫描仪问题?还有其他术语用于描述这种现象吗?

2 个答案:

答案 0 :(得分:2)

上下文敏感意味着完全不同的东西。

如果你使用更正式的符号,你会发现你的原始语法含糊不清,正如Ignacio Vazquez-Abrams所说,你编辑的语法可以通过LR(1)(甚至是LL)处理得很好( 1))解析器生成器。这是一个没有问题的野牛语法:

%start number
%%
digit : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
hex   : digit
      | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' 
      | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
decnum: digit | decnum digit
hexnum: hex   | hexnum hex
number: '[' decnum ']'
      | '{' hexnum '}'

当然,使用野牛制作扫描仪并不常见,但这当然是可能的。

我认为您正在考虑的问题是:如果我们使用flex构建扫描程序,它将如下所示:

[[:digit:]]+  { yylval.string = strdup(yytext); return DECNUM; }
[[:xdigit:]]+ { yylval.string = strdup(yytext); return HEXNUM; }

Flex无法返回模糊标记,因此在输入(下一部分)1234的情况下,flex需要返回DECNUM或HEXNUM。第一个最长(“最大munch”)规则意味着在可以以任一方式解析的令牌的情况下,在flex定义中首先出现的哪个模式将获胜。这意味着DECNUM模式需要首先出现,否则它将无法触发(并且flex将在这种情况下提供警告)。

但是现在语法存在一个小问题,因为当语法期待一个HEXNUM时,需要准备好找到一个DECNUM。这不是问题,如果语法是明确的。我们只需要创建几个非终端:

decnum: DECNUM           { $$ = strtol($1, NULL, 10); free($1); }
hexnum: DECNUM | HEXNUM  { $$ = strtol($1, NULL, 16); free($1); }

这不会产生歧义,甚至不会产生语法中尚未存在的转移/减少冲突

如果你想尝试这个,你需要在你的野牛序言中声明一些类型:

%union {
   char* string;
   long  integer;
}
%token <string> HEXNUM DECNUM
%type <integer> hexnum decnum

答案 1 :(得分:0)

该语法可以描述为ambiguous