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

"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是整数还是十六进制数字?!)。

在此示例中编写的产品中,这与位无关,但是可能存在语法,其中产品的上下文将阐明是否期望整数或十六进制数,并且扫描程序仍将拒绝协作。

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

现在是术语的问题。 这是什么使……错误……语法? 词法? 然后? 上下文敏感的词法分析器? 还是会说这是上下文相关的语法,即使它显然是扫描仪问题? 还有其他用于描述此类现象的术语吗?

===============>>#1 票数: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。 第一条最长的规则(“最大嚼数”)意味着,在令牌中可以采用任何一种方式进行解析的情况下,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

===============>>#2 票数:0

这种语法可谓是模棱两可的

  ask by BitTickler translate from so

未解决问题?本站智能推荐: