我想用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?
答案 0 :(得分:1)
我本身并不熟悉PEG,但看起来你所拥有的是一种归因语法,你可以直接在语义动作中执行执行逻辑。
如果您在定义之前使用,那将无效。
您可以使用相同的解析器生成器,但您可能必须定义某种抽象语法树来捕获语义并推迟评估,直到您解析所有输入。
答案 1 :(得分:0)
是的,可以用PEG语法解析它。 PEG是有效贪婪的LL(*),具有无限的前瞻性。这样的表达很容易。
但你写的语法是递归的,而不是PEG。虽然一些PEG解析器可以处理左递归,但是在您成为专家之前,最好避免它,并且如果需要,只使用正确的递归。