精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

手寫編程語言-遞歸函數是如何實現的?

開發 前端
本篇文章主要是記錄一下在 GScript 中實現遞歸調用時所遇到的坑,類似的問題在中文互聯網上我幾乎沒有找到相關的內容,所以還是很有必要記錄一下。

前言

本篇文章主要是記錄一下在 GScript 中實現遞歸調用時所遇到的坑,類似的問題在中文互聯網上我幾乎沒有找到相關的內容,所以還是很有必要記錄一下。

在開始之前還是簡單介紹下本次更新的 GScript v0.0.9 所包含的內容:

  • 支持可變參數
  • 優化append 函數語義
  • 優化編譯錯誤信息
  • 最后一個就是支持遞歸調用

先看第一個可變參數:

printf(string format, any ...a){}
string sprintf(string format, any ...a){}

以上是隨著本次更新新增的兩個標準函數,均支持可變參數,其中使用 ... 表示可變參數,調用時如下:

printf("hello %s ","123");
printf("hello-%s-%s ","123","abc");
printf("hello-%s-%d ","123",123);
string format = "this is %s ";
printf(format, "gscript");
string s = sprintf("nice to meet %s", "you");
assertEqual(s,"nice to meet you");

與大部分語言類似,可變參數本質上就是一個數組,所以可以拿來循環遍歷:

int add(string s, int ...num){
println(s);
int sum = 0;
for(int i=0;i<len(num);i++){
int v = num[i];
sum = sum+v;
}
return sum;
}
int x = add("abc", 1,2,3,4);
println(x);
assertEqual(x, 10);
append(any[] a, any v){}

之后是優化了內置函數 append() 的語義,本次優化來自于 issue12 的建議:https://github.com/crossoverJie/gscript/issues/12。

int[] a={1,2,3};
println(a);
println();
a = append(a,4);
println(a);
int[] a={1,2,3};
println(a);
println();
append(a,4);
int b = a[3];
assertEqual(4, b);
println(a);

現在 append 之后不需要再重新賦值,也會追加數據,優化后這里看起來是一個值/引用傳遞的問題,但其實底層也是值傳遞,只是在語法上增加了這樣的語法糖,幫使用者重新做了一次賦值。

之后是新增了編譯錯誤信息提示,比如下面這段代碼:

a+2;
b+c;

使用沒有聲明的變量,現在會直接編譯失敗:

1:0: undefined: a
2:0: undefined: b
2:2: undefined: c
class T{}
class T{}
2:0: class T redeclared in this block

重復聲明之類的語法錯誤也有相關提示。

最后一個才是本次討論的重點,也就是遞歸函數的支持。

int num(int x,int y){
if (y==1 || y ==x) {
return 1;
}
int v1 = num(x - 1, y - 1);
return c;
}

再上一個版本中 int v1 = num(x - 1, y - 1); 這行代碼是不會執行的,具體原因后文會分析。

現在利用遞歸便可以實現類似于打印楊輝三角之類的程序了:

int num(int x,int y){
if (y==1 || y ==x) {
return 1;
}
int v1 = num(x - 1, y - 1);
int v2 = num(x - 1, y);
int c = v1+v2;
return c;
}
printTriangle(int row){
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= row - i; j++) {
print(" ");
}
for (int j = 1; j <= i; j++) {
print(num(i, j) + " ");
}
println("");
}
}
printTriangle(7);
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1

函數中的 return

int num(int x,int y){
if (y==1 || y ==x) {
return 1;
}
int v1 = num(x - 1, y - 1);
return c;
}

現在我們來看看這樣的代碼為什么執行完 return 1 之后就不會執行后邊的語句了。

其實在此之前我首先解決的時候函數 return 后不能執行后續 statement 的需求,其實正好就是上文提到的邏輯,只是這里是遞歸而已。

先把代碼簡化一下方便分析:

int f1(int a){
if (a==10){
return 10;
}
println("abc");
}

當參數 a 等于 10 的時候確實不能執行后續的打印語句了,那么如何實現該需求呢?

以正常人類的思考方式:當我們執行完 return 語句的時候,就應該標記該語句所屬的函數直接返回,不能在執行后續的 statement。

可是這應該如何實操呢?

其實看看 AST 就能明白了:

圖片

當碰到 return 語句的時,會遞歸向上遍歷語法樹,標記上所有 block 節點表明這個 block 后續的語句不再執行了,同時還得把返回值記錄下來。

這樣當執行到下一個 statement 時,也就是 println("abc"); 則會判斷他所屬的 block 是否有被標記,如果有則直接返回,這樣便實現了 return 語句不執行后續代碼。

部分實現代碼如下:

func (v *Visitor) scanBlockStatementCtx(tree antlr.ParseTree, value interface{}) {
context, ok := tree.(*parser.BlockContext)
if ok {
if v.blockCtx2Mark == nil {
v.blockCtx2Mark = make(map[*parser.BlockContext]interface{})
}
v.blockCtx2Mark[context] = value
}
if tree.GetParent() != nil {
v.scanBlockStatementCtx(tree.GetParent().(antlr.ParseTree), value)
}
}

圖片

源碼地址:https://github.com/crossoverJie/gscript/blob/793d196244416574bd6be641534742e57c54db7a/visitor.go#L182。

遞歸的問題

但同時問題也來了,就是遞歸的時候也不會執行后續的遞歸代碼了。

其實解決問題的方法也很簡單,就是在判斷是否需要直接返回那里新增一個條件,這個 block 中不存在遞歸調用。

所以我們就得先知道這個 block 中是否存在遞歸調用。

整個過程有以下幾步:

  • 編譯期:在函數聲明處記錄下函數與當前context 的映射關系。
  • 編譯期:掃描statement 時,取出該 statement 的 context 所對應的函數。
  • 編譯期:掃描到的statement 如果是一個函數調用,則判斷該函數是否為該 block 中的函數,也就是第二步取出的函數。
  • 編譯期:如果兩個函數相等,則將當前block 標記為遞歸調用。
  • 運行期:在剛才判斷return 語句處,額外多出判斷當前 block 是否為遞歸調用,如果是則不能返回。

部分代碼如下:

圖片圖片

https://github.com/crossoverJie/gscript/blob/3e179f27cb30ca5c3af57b3fbf2e46075baa266b/resolver/ref_resolver.go#L70。

總結

這里的遞歸調用其實卡了我挺長時間的,思路是有的,但是寫出來的代碼總是和預期不符,當天晚上坐在電腦面前到凌晨兩三點,百思不得其解。

最后受不了上床休息的時候,突然一個靈光乍現讓我想到了解決方案,于是第二天起了個早床趕忙實踐,還真給解決了。

所以有些時候碰到棘手問題時給自己放松一下,往往會有出其不意的效果。

最后是目前的遞歸在某些情況下性能還有些問題,后續會盡量將這些標記過程都放在編譯期,編譯慢點沒事,但運行時慢那就有問題了。

之后還會繼續優化運行時的異常,目前是直接 ??panic??,堆棧也沒有,體感非常不好;歡迎感興趣的朋友試用反饋bug。

責任編輯:姜華 來源: crossoverJie
相關推薦

2022-09-19 08:10:37

運算符函數語言

2022-10-17 09:08:01

2021-07-20 15:42:05

編程語言PythonJava

2024-07-10 08:22:42

2021-05-28 05:34:06

Golang語言編程

2021-08-30 15:47:34

編程技能開發

2011-06-20 08:48:17

編程語言

2020-11-12 07:00:50

JavaScript前端編程語言

2021-08-23 15:05:21

PyretJavaScript編程

2017-11-28 16:57:18

2017-09-12 11:02:51

Python編程語言

2019-07-17 13:45:42

網絡安全防火墻軟件

2015-10-29 09:36:31

高端編程語言

2018-11-21 09:33:01

2013-02-18 09:20:10

2015-10-19 09:23:44

新編編程女人

2017-12-27 14:52:21

JSGo編程語言

2020-12-09 09:33:16

編程語言C語言匯編語言

2018-11-11 15:29:13

大數據語言Java

2009-11-18 16:39:51

PHP遞歸刪除目錄
點贊
收藏

51CTO技術棧公眾號

国产原创剧情av| 在线观看不卡视频| 亚洲自拍偷拍区| 日韩免费一二三区| 国产一区二区区别| 正在播放亚洲一区| 一区二区三区国产福利| 日本视频免费观看| 亚洲精品电影| 亚洲乱码一区二区| 麻豆网站免费观看| 搜成人激情视频| 又紧又大又爽精品一区二区| 欧美成人第一区| 性一交一乱一精一晶| 首页国产欧美日韩丝袜| 欧美激情精品久久久久久大尺度| 男插女视频网站| 欧美理论电影| 欧美激情一区二区三区全黄| 国产精品久久久久久久app| www.亚洲人.com| 污污污污污污www网站免费| 日本成人一区| 高清不卡在线观看| 成人精品视频在线| 亚洲伦理一区二区三区| 香蕉久久精品| 精品国产在天天线2019| 91高清国产视频| 手机在线免费看av| 国产精品麻豆久久久| 久久成人资源| 人妻与黑人一区二区三区| 久久成人久久爱| 国产不卡精品视男人的天堂| 韩国av免费观看| 很黄很黄激情成人| 亚洲欧美中文字幕在线一区| 精品熟女一区二区三区| 在线视频亚洲欧美中文| 欧美一区二区私人影院日本| 中文字幕色呦呦| 求av网址在线观看| 人妻视频一区二区三区| 日本免费新一区视频| 91sa在线看| 99视频在线看| 亚洲影视在线| 欧洲成人免费视频| 天堂中文在线网| 午夜综合激情| 欧美专区国产专区| 久久久久久不卡| 免费在线亚洲欧美| 日韩av三级在线观看| 亚洲天堂男人av| 婷婷综合伊人| 久久成人18免费网站| 日本精品在线免费观看| 综合伊思人在钱三区| 国产丝袜一区二区| 在线观看福利片| 精品国产中文字幕第一页 | 欧美精品在线观看播放| 亚洲一区二区视频在线| 欧美激情videos| 久草免费新视频| 精品不卡视频| 91极品女神在线| 国产又大又粗又爽| 七七婷婷婷婷精品国产| 国产一区在线播放| а√天堂资源在线| 99国产精品久久久久久久久久 | 国产91精品一区| 免费在线成人| 97av在线视频| www.com亚洲| 精品一二线国产| av蓝导航精品导航| 国产精品久久综合青草亚洲AV| 午夜亚洲激情| 国产美女直播视频一区| 国产婷婷在线视频| 99视频精品在线| 99国产一区二区三精品乱码| 91精品国产99| 亚洲中文一区二区| 奇米色一区二区三区四区| 国产在线日韩在线| 三级小视频在线观看| 国产午夜精品久久久久久免费视| 国产伦精品一区二区三区免费视频| 国产又粗又猛又黄又爽无遮挡| 日韩电影免费在线观看网站| 91最新国产视频| 四虎影视在线观看2413| 中文字幕一区二区三区精华液 | 九色视频成人自拍| 国产精品第13页| 久久久久久久久久久99| 美女视频一区| 日韩精品视频在线观看网址| 午夜精品一区二区三级视频| 久久国产精品亚洲人一区二区三区 | 毛片在线免费播放| 国产在线麻豆精品观看| 欧美精品一区二区三区在线四季| 人人九九精品| 亚洲码国产岛国毛片在线| 男人的天堂视频在线| 高潮一区二区| 亚洲精品一线二线三线无人区| 午夜不卡久久精品无码免费| 视频在线不卡免费观看| 国产91|九色| 亚洲第一视频在线| 国产精品国产自产拍高清av| 免费高清在线观看免费| 中文字幕一区二区三区四区久久| 亚洲国产成人精品久久| 成人高潮免费视频| 七七婷婷婷婷精品国产| 欧美精品一区三区在线观看| japanese色国产在线看视频| 91精品国产麻豆国产自产在线| 欧美图片自拍偷拍| 99视频精品全部免费在线视频| yw.尤物在线精品视频| 午夜视频在线观看一区二区| 国产素人在线观看| 国产 日韩 欧美| 在线观看日韩视频| 麻豆成人免费视频| 91丝袜美腿高跟国产极品老师| 视频一区二区在线观看| 中文字幕在线视频久| 亚洲精品成人久久电影| 国产无遮无挡120秒| 国产精品99久久久久久久vr| 在线视频不卡一区二区| 青青国产精品| 久久精品国产电影| 一级爱爱免费视频| 亚洲欧洲www| 中文字幕日韩综合| 91视频精品| 欧美成人国产va精品日本一级| 国产www在线| 久久综合色综合88| 国产性xxxx18免费观看视频| 人妖一区二区三区| 久久资源免费视频| 国产婷婷在线视频| 日本视频中文字幕一区二区三区| 国产精一区二区三区| 精品国产乱码久久久久久丨区2区| av在线播放免费| 欧美主播一区二区三区| 成年人小视频在线观看| 国产精选一区| 色综合色综合网色综合| 亚洲欧美激情在线观看| 亚洲国产欧美在线人成| 国产精品无码专区| 久久狠狠婷婷| 亚洲三区四区| 日韩激情欧美| 欧美性做爰毛片| 丁香婷婷在线观看| 91麻豆精品国产自产在线观看一区| 超碰97人人干| 在线欧美一区| 茄子视频成人在线观看| 国产精成人品2018| 久色乳综合思思在线视频| 黄色污污视频软件| 中文字幕在线不卡| 东京热av一区| 欧美视频在线观看| 成人免费福利视频| 精品人妻一区二区三区蜜桃视频| av电影在线观看| 午夜精品国产更新| av中文字幕免费观看| 久久av中文字幕片| 日本一区午夜艳熟免费| 国产传媒欧美日韩成人精品大片| 全球成人中文在线| 国产日产一区二区| 日韩av一区二区在线观看| 最近中文字幕免费在线观看| 一区二区三区四区不卡视频| 污视频在线观看免费网站| 97视频热人人精品免费| 国产三级精品在线不卡| 国产精品高潮久久| 国产最新精品视频| 男女啪啪在线观看| 日韩精品中文字| 国产视频一区二区三区四区五区| 亚洲桃色在线一区| 国产精品极品美女在线观看免费| 中文字幕第22页| 91精品国产91久久久久久黑人| 国产狼人综合免费视频| 超碰在线最新网址| 色777狠狠综合秋免鲁丝| 天天干天天做天天操| 3d动漫精品啪啪| 91午夜精品亚洲一区二区三区| 国产亚洲欧美在线| 手机看片福利日韩| 亚洲福利免费| 一区二区三区四区免费观看| 99这里只有精品视频| 国产日韩在线免费| 台湾佬成人网| 91tv亚洲精品香蕉国产一区7ujn| 成人免费一区二区三区视频网站| 欧美区一区二区三区| 少妇太紧太爽又黄又硬又爽| 亚洲一区二区三区视频在线播放 | 日韩亚洲在线观看| 国内老熟妇对白xxxxhd| 精品视频全国免费看| 欧美一级特黄视频| 午夜视频一区二区三区| 欧美精品一级片| 自拍视频在线观看一区二区| 日韩av片在线| 丁香天五香天堂综合| 在线a免费观看| 亚洲制服av| 91成人在线观看喷潮教学| 成人免费在线观看av| 日本午夜精品一区二区| 在线视频这里只有精品| 国产剧情一区在线| 伊人五月天婷婷| 亚洲国产综合在线看不卡| 正在播放久久| 天天色天天射综合网| 影音欧美亚洲| 欧美激情偷拍自拍| 一区视频二区视频| 希岛爱理一区二区三区| 亚洲成人动漫在线| 欧美日本在线| 91免费黄视频| 亚洲欧美日本日韩| 国产精品igao激情视频| 国产一区三区在线播放| 青青草原亚洲| 日韩欧美精品综合| 中文字幕免费高| 午夜电影亚洲| 欧美深夜福利视频| 99精品视频在线观看播放| 激情一区二区三区| 日本天堂一区| 日本一区二区久久精品| 成人区精品一区二区婷婷| 夜夜春亚洲嫩草影视日日摸夜夜添夜| 老牛影视av一区二区在线观看| 成人亚洲激情网| 日本亚州欧洲精品不卡| 国产伦精品一区二区三区四区视频 | www.久久精品| 亚洲av片不卡无码久久| 国产成人精品1024| 日批在线观看视频| 久久丝袜美腿综合| 国产三级aaa| 亚洲国产精品一区二区www在线| 国产午夜手机精彩视频| 亚洲一区二区视频在线| 日韩精品一区不卡| 在线成人免费视频| 人妻丰满熟妇av无码区hd| 亚洲欧美制服另类日韩| 欧美日韩视频在线播放| 欧美黑人xxxx| 中韩乱幕日产无线码一区| 99国精产品一二二线| 日韩三级久久| 欧美日韩亚洲免费| 欧美在线日韩| 一本久道中文无码字幕av| 国产一区中文字幕| 在线免费观看a级片| 国产精品高潮呻吟| 国产精品第108页| 欧美日本一区二区在线观看| 中文字幕一区2区3区| 色狠狠一区二区| wwwav在线播放| 国产一区二区三区在线观看网站 | 国产麻豆精品久久| www.成人av.com| 欧美亚洲激情| 日韩精品在线中文字幕| 麻豆91在线看| 国产精品无码一区二区三区免费| 成人av影院在线| 亚洲欧洲综合网| 亚洲欧美日韩一区二区三区在线观看 | 国产视频网站一区二区三区| 久久久影院一区二区三区| 中文字幕一区二区av| 成人午夜免费在线视频| 美女国产一区二区| 成人免费无码大片a毛片| 亚洲摸摸操操av| 中日精品一色哟哟| 国产丝袜一区二区三区| 黄色美女视频在线观看| 国产欧美精品久久久| 国产精品欧美日韩一区| 奇米影视亚洲色图| 狠狠色丁香久久婷婷综合丁香| 日本少妇一区二区三区| 国产精品色婷婷| 日韩在线 中文字幕| 亚洲第一精品电影| 亚洲夜夜综合| 91精品在线播放| 日韩精品久久久久久久电影99爱| 8x8ⅹ国产精品一区二区二区| 在线国产日韩| 久久中国妇女中文字幕| 精品免费囯产一区二区三区| 日韩欧美一二三区| a级在线观看| 91九色视频在线| 97精品国产| 亚洲熟妇无码av在线播放| 美女在线观看视频一区二区| 丰满少妇高潮一区二区| 欧美性生活大片免费观看网址| 一级特黄特色的免费大片视频| 欧美va天堂va视频va在线| 黄色免费在线观看| 欧美一区三区三区高中清蜜桃| 亚洲综合伊人| 日本一区二区三区四区五区六区| 国产精品永久| 国产精品jizz| 色视频欧美一区二区三区| 精品久久久中文字幕人妻| 亚洲欧洲激情在线| 久久久一本精品| 婷婷四月色综合| 久久99久久99小草精品免视看| 国产老熟女伦老熟妇露脸| 亚洲444eee在线观看| 先锋av资源站| 国产精品久久久一区| 久久在线播放| 久久久久亚洲av无码麻豆| 亚洲一区二区五区| 亚洲三级中文字幕| 国产精品6699| 99久久精品费精品国产| 欧美少妇性生活视频| 丁香婷婷综合色啪| 日本特黄a级片| 99re6这里只有精品| 亚洲欧美日韩网站| 亚洲国产综合在线| 日本私人网站在线观看| 久久精品亚洲一区| 日韩漫画puputoon| 国内外成人激情免费视频| 成人午夜电影网站| 无码人妻精品一区二区50| 亚洲成人av资源网| 久久野战av| 亚洲一区 在线播放| 99re热视频精品| 在线观看中文字幕2021| 色综合久综合久久综合久鬼88| 日韩中文在线| 亚洲精品无码久久久久久| 国产精品久久久久一区| 日韩在线视频免费| 色综合91久久精品中文字幕| 日韩深夜影院| 亚洲日本黄色片| 狠狠躁夜夜躁人人躁婷婷91| 天堂视频中文在线| 国产色视频一区| 天天色天天射综合网| 噜噜噜在线视频| 91精品国产全国免费观看| 男人天堂亚洲天堂| 三区精品视频观看| 成人av在线观| 精品国产免费无码久久久|