是否可以使用bison / yacc为使用反向波兰表示法(以及类似Postscript的语法)的脚本语言生成解析器?
解析器应该能够解析类似于以下代码的代码:
/fib
{
dup dup 1 eq exch 0 eq or not
{
dup 1 sub fib
exch 2 sub fib
add
} if
} def
答案 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 '}'
%%