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

时间:2010-08-24 06:08:08

标签: 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

2 个答案:

答案 0 :(得分:1)

是。假设你的意思是也使用postscript表示法,这意味着你要定义你的表达式:

expression: operand operand operator

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

expression: operand operator operand

但这很难成为一件大事。如果你的意思是“Postcript-like”,你可能需要澄清才能给出更好的答案。

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

operand_list: 
            | operand_list operand
            ;

operator_list: 
             | operator_list operator
             ;

expression: operand_list operator_list
          ;

就目前而言,这并不会尝试为任何特定操作数强制执行适当数量的运算符 - 您必须单独添加这些检查。在典型的情况下,在堆栈计算机上执行postscript表示法,因此大多数此类检查变为简单的堆栈检查。

我应该补充一点,虽然你肯定可以在yacc之类的东西中编写这样的解析器,但是使用postscript符号的语言通常需要这样的最小解析,你经常将它们直接提供给某种执行的虚拟机解释器它们非常直接,只需要很少的解析(大多数情况下,如果你试图使用一个尚未定义的名称,解析就会抛出错误。)

答案 1 :(得分:1)

鉴于以上简短描述和维基百科上的说明:
http://en.wikipedia.org/wiki/Stack-oriented_programming_language#PostScript_stacks

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

%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 '}'


%%