PEG语法接受后期定义

时间:2015-12-03 22:27:48

标签: parsing grammar peg

我想用PackCC写一个PEG解析器(但也可能是peg / leg或其他库),它能够计算一些随机位置变量的字段。 第一种简化方法是以下语法:

%source {                                                                      
  int vars[256];                                                                
}                                                            

statement <- e:term EOL      { printf("answer=%d\n", e); }                     

term <- l:primary 
      ( '+' r:primary        { l += r; }                                   
      / '-' r:primary        { l -= r; }
      )*                     { $$ = l; }                               
      / i:var '=' s:term     { $$ = vars[i] = s; }                             
      / e:primary            { $$ = e; }             

primary <- < [0-9]+ >        { $$ = atoi($1); }              
         / i:var !'='        { $$ = vars[i]; }                                    

var <- < [a-z] >             { $$ = $1[0]; }                                      

EOL    <- '\n' / ';'                                              

%%     

使用连续顺序进行测试时,它可以正常工作:

a=42;a+1
answer=42
answer=43

但是当使用后面的变量定义时,它会失败:

a=42;a+b;b=1
answer=42
answer=42
answer=1

甚至更深层链接的后期定义也应该起作用,如:

a=42;a+b;b=c;c=1
answer=42
answer=42
answer=0
answer=1

让我们考虑输入不是作为顺序编程语言,而是更像Excel之类的电子表格,例如:

A1: 42
A2: =A1+A3
A3: 1

是否可以使用PEG语法解析和处理此类文本?

这里是双通还是多通选项?

或者我是否需要切换到旧式lex / yacc flex / bison?

2 个答案:

答案 0 :(得分:1)

我本身并不熟悉PEG,但看起来你所拥有的是一种归因语法,你可以直接在语义动作中执行执行逻辑。

如果您在定义之前使用,那将无效。

您可以使用相同的解析器生成器,但您可能必须定义某种抽象语法树来捕获语义并推迟评估,直到您解析所有输入。

答案 1 :(得分:0)

是的,可以用PEG语法解析它。 PEG是有效贪婪的LL(*),具有无限的前瞻性。这样的表达很容易。

但你写的语法是递归的,而不是PEG。虽然一些PEG解析器可以处理左递归,但是在您成为专家之前,最好避免它,并且如果需要,只使用正确的递归。