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

发布于 2024-09-16 04:56:52 字数 221 浏览 9 评论 0原文

是否可以使用 bison/yacc 为使用逆波兰表示法(和类似 Postscript 的语法)的脚本语言生成解析器?

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

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

Is it possible to generate a parser for a scripting language that uses the Reverse Polish notation (and a Postscript-like syntax) using bison/yacc?

The parser should be able to parse code similar to the following one:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

昨迟人 2024-09-23 04:56:52

鉴于上面的简短描述和维基百科上的注释:
http://en.wikipedia.org/wiki/Stack-orient_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 '}'


%%

Given the short description above and the notes on Wikipedia:
http://en.wikipedia.org/wiki/Stack-oriented_programming_language#PostScript_stacks

A simple bison grammer for the above could be:

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


%%
你又不是我 2024-09-23 04:56:52

是的。假设您的意思是也使用后记符号,则意味着您将定义类似以下的表达式:

expression: operand operand operator

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

expression: operand operator operand

但这几乎不是什么大问题。如果您所说的“类似后记”是指其他内容,您可能必须先澄清才能给出更好的答案。

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

operand_list: 
            | operand_list operand
            ;

operator_list: 
             | operator_list operator
             ;

expression: operand_list operator_list
          ;

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

我应该补充一点,虽然你当然可以用 yacc 之类的东西编写这样的解析器,但使用 postscript 表示法的语言通常需要最少的解析,以至于你经常将它们直接提供给某种直接执行它们的虚拟机解释器,使用最少的解析(大多数情况下,如果您尝试使用尚未定义的名称,则解析会引发错误)。

Yes. Assuming you mean one that also uses postscript notation, it means you'd define your expressions something like:

expression: operand operand operator

Rather than the more common infix notation:

expression: operand operator operand

but that hardly qualifies as a big deal. If you mean something else by "Postcript-like", you'll probably have to clarify before a better answer can be given.

Edit: Allowing an arbitrary number of operands and operators is also pretty easy:

operand_list: 
            | operand_list operand
            ;

operator_list: 
             | operator_list operator
             ;

expression: operand_list operator_list
          ;

As it stands, this doesn't attempt to enforce the proper number of operators being present for any particular operand -- you'd have to add those checks separately. In a typical case, a postscript notation is executed on a stack machine, so most such checks become simple stack checks.

I should add that although you certainly can write such parsers in something like yacc, languages using postscript notation generally require such minimal parsing that you frequently feed them directly to some sort of virtual machine interpreter that executes them quite directly, with minimal parsing (mostly, the parsing comes down to throwing an error if you attempt to use a name that hasn't been defined).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文