📄 expression4.y
字号:
%{{* 计算支持简单变量的数学表达式的yacc程序 编译:yacc Expression4 ExpressionY4 *}unit ExpressionY4;interfaceuses SysUtils, LexLib, YaccLib, Classes, ExpressionL4;{指定不同于整数的类型时,一定要使用%type <Real> expression 指定表达式的类型}{同时要使用 %token <Real> Number来指定token的类型}{注意, tp lex yacc不支持%union 标签,我们直接指定类型就可以了}var SymList:TStringList;{查找符号是否在符号表中}function symlook(symp:string):TSymtab;%}%token <integer> NAME%token <Real> NUMBER%type <Real> expression %left '-' '+'%left '*' '/'%nonassoc UMINUS%%statement_list: statement '\n' | statement_list statement '\n' ;statement: NAME '=' expression { TSymtab($1).Value := $3; } | expression { writeln(format('= %f', [$1])); } ;expression: expression '+' expression { $$ := $1 + $3; } | expression '-' expression { $$ := $1 - $3; } | expression '*' expression { $$ := $1 * $3; } | expression '/' expression { if($3 = 0.0) then yyerror('除零错误') else $$ := $1 / $3; } | '-' expression %prec UMINUS { $$ := -$2; } | '(' expression ')' { $$ := $2; } | NUMBER | NAME { $$ := TSymtab($1).value; } | NAME '(' expression ')' { if Assigned(TSymtab($1).funcptr) then $$ := TSymtab($1).funcptr($3) else begin writeln(format('%s 不是函数', [TSymtab($1).name])); $$ := 0.0; end; } ;%%function symlook(symp:string):TSymtab;var I:integer; sym:TSymtab;begin I:=SymList.Indexof(symp); if I>-1 then result:=TSymtab(SymList.Objects[I]) else begin sym:=TSymtab.Create; sym.name:=symp; Symlist.addObject(symp, sym); result:=sym; end;end;//添加函数定义procedure addfunc(name:string;func:TOneParamFunc);var sym:TSymtab;begin sym:= symlook(name); sym.funcptr := func;end;//由于sqrt是魔术函数,所以无法获得它的地址//不得以重新定义一个newSqrt作为代理function newSqrt(argc:extended):Extended;begin Result:=sqrt(argc);end;initialization SymList:=TStringList.Create; //添加函数定义 addfunc('sqrt', newSqrt);finalization // todo: 释放同字符串绑定的TSymtab对象 SymList.free;end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -