C++ 是否可以使用bison/yacc的反向波兰语表示法为语言生成解析器?

C++ 是否可以使用bison/yacc的反向波兰语表示法为语言生成解析器?,c++,yacc,bison,C++,Yacc,Bison,是否可以使用bison/yacc为使用反向波兰符号(和类似Postscript的语法)的脚本语言生成解析器 解析器应该能够解析与以下代码类似的代码: /fib { dup dup 1 eq exch 0 eq or not { dup 1 sub fib exch 2 sub fib add } if } def 对。假设您指的是一个也使用postscript符号的表达式,这意味着您将定义表达式如下: expression: operand operand

是否可以使用bison/yacc为使用反向波兰符号(和类似Postscript的语法)的脚本语言生成解析器

解析器应该能够解析与以下代码类似的代码:

/fib
{
  dup dup 1 eq exch 0 eq or not
  {
    dup 1 sub fib
    exch 2 sub fib
    add
  } if
} def

对。假设您指的是一个也使用postscript符号的表达式,这意味着您将定义表达式如下:

expression: operand operand operator
而不是更常见的中缀符号:

expression: operand operator operand
但这几乎算不上什么大事。如果你所说的“PostScript like”是指其他内容,那么在给出更好的答案之前,你可能需要澄清

编辑:允许任意数量的操作数和运算符也很容易:

operand_list: 
            | operand_list operand
            ;

operator_list: 
             | operator_list operator
             ;

expression: operand_list operator_list
          ;
目前,这并不试图强制任何特定操作数存在适当数量的运算符——您必须单独添加这些检查。在典型的情况下,postscript表示法是在堆栈机器上执行的,因此大多数这样的检查都变成了简单的堆栈检查


我应该补充一点,虽然您当然可以用类似于yacc的语言编写这样的解析器,但是使用postscript符号的语言通常需要非常小的解析,您经常直接将它们提供给某种虚拟机解释器,该解释器非常直接地执行它们,只需进行最小的解析(大多数情况下,如果您试图使用尚未定义的名称,解析归结为抛出错误)。

鉴于上面的简短描述和维基百科上的注释:

上述简单的野牛语法可以是:

%token          ADD
%token          DUP
%token          DEF
%token          EQ
%token          EXCH
%token          IF
%token          NOT
%token          OR
%token          SUB
%token          NUMBER
%token          IDENTIFIER

%%


program         :   action_list_opt
action_list_opt :   action_list
                |                           /* No Action */
action_list     :   action
                |   action_list action
action          :   param_list_opt operator
param_list_opt  :   param_list
                |                           /* No Parameters */
param_list      :   param
                |   param_list param
param           :   literal
                |   name
                |   action_block

operator        :   ADD
                |   DUP
                |   DEF
                |   EQ
                |   EXCH
                |   IF
                |   NOT
                |   OR
                |   SUB

literal         :   NUMBER
name            :   '/' IDENTIFIER
action_block    :   '{' program '}'


%%

你说的
Postscript
是什么意思?你指的是Postscript语言还是其他稍微抽象一点的语言?对于类似Postscript的编程语言,我指的是类似Postscript的面向堆栈的编程语言。当你说“Postscript”时,我想到的是打印机语言。但我认为你的意思是“什么?”我会称之为基于堆栈的反向波兰语(reverse polish language)”:但不要认为这意味着“我认为你的描述是错误的”这正是我思考的方式,我想澄清(我自己).我现在明白了。我在wikipedia上找到了你的例子。有时包含链接比尝试描述链接更容易。事实上,使用Bison的例子是RPN计算器:)问题是也允许使用
操作数操作数运算符。我认为使用yacc生成解析器是可能的,但对于语法类似于Postscript的脚本语言来说,这将是一种过分的杀伤力。谢谢您的回复。@Kiamaluno:不。如果它适用于编译语言,那么它应该同样适用于解释语言(脚本语言)。我认为这并不过分(实际上我认为这是必要的,因为手写既难又容易出错)。@马丁:事实上,不,在这种情况下,手写相对容易。基本上,操作数和运算符是混合的。操作数将值推送到堆栈中,运算符从堆栈中取出一定数量的操作数,组合它们,然后将结果放回堆栈。因此,“解析”基本上只是在字典中查找一个标记,看看它是否已定义。如果没有,你就拒绝它。@Jerry Coffin:好的。我给你这个。它看起来很简单,可以写一个手写的。