diff --git a/crates/apollo-parser/benches/benches.rs b/crates/apollo-parser/benches/benches.rs index dae28b5a3..204666ef9 100644 --- a/crates/apollo-parser/benches/benches.rs +++ b/crates/apollo-parser/benches/benches.rs @@ -30,5 +30,11 @@ fn bench_parser_peek_n(c: &mut Criterion) { c.bench_function("parser_peek_n", move |b| b.iter(|| parse_query(query))); } -criterion_group!(benches, bench_parser_peek_n); +fn bench_parser_many_aliases(c: &mut Criterion) { + let query = include_str!("testdata/alias.graphql"); + + c.bench_function("many_aliases", move |b| b.iter(|| parse_query(query))); +} + +criterion_group!(benches, bench_parser_peek_n, bench_parser_many_aliases); criterion_main!(benches); diff --git a/crates/apollo-parser/benches/testdata/alias.graphql b/crates/apollo-parser/benches/testdata/alias.graphql new file mode 100644 index 000000000..7f45dd799 --- /dev/null +++ b/crates/apollo-parser/benches/testdata/alias.graphql @@ -0,0 +1,3005 @@ +query($var0: String!, $var1: String!, $var2: String!, $var3: String!, $var4: String!, $var5: String!, $var6: String!, $var7: String!, $var8: String!, $var9: String!, $var10: String!, $var11: String!, $var12: String!, $var13: String!, $var14: String!, $var15: String!, $var16: String!, $var17: String!, $var18: String!, $var19: String!, $var20: String!, $var21: String!, $var22: String!, $var23: String!, $var24: String!, $var25: String!, $var26: String!, $var27: String!, $var28: String!, $var29: String!, $var30: String!, $var31: String!, $var32: String!, $var33: String!, $var34: String!, $var35: String!, $var36: String!, $var37: String!, $var38: String!, $var39: String!, $var40: String!, $var41: String!, $var42: String!, $var43: String!, $var44: String!, $var45: String!, $var46: String!, $var47: String!, $var48: String!, $var49: String!, $var50: String!, $var51: String!, $var52: String!, $var53: String!, $var54: String!, $var55: String!, $var56: String!, $var57: String!, $var58: String!, $var59: String!, $var60: String!, $var61: String!, $var62: String!, $var63: String!, $var64: String!, $var65: String!, $var66: String!, $var67: String!, $var68: String!, $var69: String!, $var70: String!, $var71: String!, $var72: String!, $var73: String!, $var74: String!, $var75: String!, $var76: String!, $var77: String!, $var78: String!, $var79: String!, $var80: String!, $var81: String!, $var82: String!, $var83: String!, $var84: String!, $var85: String!, $var86: String!, $var87: String!, $var88: String!, $var89: String!, $var90: String!, $var91: String!, $var92: String!, $var93: String!, $var94: String!, $var95: String!, $var96: String!, $var97: String!, $var98: String!, $var99: String!, $var100: String!, $var101: String!, $var102: String!, $var103: String!, $var104: String!, $var105: String!, $var106: String!, $var107: String!, $var108: String!, $var109: String!, $var110: String!, $var111: String!, $var112: String!, $var113: String!, $var114: String!, $var115: String!, $var116: String!, $var117: String!, $var118: String!, $var119: String!, $var120: String!, $var121: String!, $var122: String!, $var123: String!, $var124: String!, $var125: String!, $var126: String!, $var127: String!, $var128: String!, $var129: String!, $var130: String!, $var131: String!, $var132: String!, $var133: String!, $var134: String!, $var135: String!, $var136: String!, $var137: String!, $var138: String!, $var139: String!, $var140: String!, $var141: String!, $var142: String!, $var143: String!, $var144: String!, $var145: String!, $var146: String!, $var147: String!, $var148: String!, $var149: String!, $var150: String!, $var151: String!, $var152: String!, $var153: String!, $var154: String!, $var155: String!, $var156: String!, $var157: String!, $var158: String!, $var159: String!, $var160: String!, $var161: String!, $var162: String!, $var163: String!, $var164: String!, $var165: String!, $var166: String!, $var167: String!, $var168: String!, $var169: String!, $var170: String!, $var171: String!, $var172: String!, $var173: String!, $var174: String!, $var175: String!, $var176: String!, $var177: String!, $var178: String!, $var179: String!, $var180: String!, $var181: String!, $var182: String!, $var183: String!, $var184: String!, $var185: String!, $var186: String!, $var187: String!, $var188: String!, $var189: String!, $var190: String!, $var191: String!, $var192: String!, $var193: String!, $var194: String!, $var195: String!, $var196: String!, $var197: String!, $var198: String!, $var199: String!, $var200: String!, $var201: String!, $var202: String!, $var203: String!, $var204: String!, $var205: String!, $var206: String!, $var207: String!, $var208: String!, $var209: String!, $var210: String!, $var211: String!, $var212: String!, $var213: String!, $var214: String!, $var215: String!, $var216: String!, $var217: String!, $var218: String!, $var219: String!, $var220: String!, $var221: String!, $var222: String!, $var223: String!, $var224: String!, $var225: String!, $var226: String!, $var227: String!, $var228: String!, $var229: String!, $var230: String!, $var231: String!, $var232: String!, $var233: String!, $var234: String!, $var235: String!, $var236: String!, $var237: String!, $var238: String!, $var239: String!, $var240: String!, $var241: String!, $var242: String!, $var243: String!, $var244: String!, $var245: String!, $var246: String!, $var247: String!, $var248: String!, $var249: String!, $var250: String!, $var251: String!, $var252: String!, $var253: String!, $var254: String!, $var255: String!, $var256: String!, $var257: String!, $var258: String!, $var259: String!, $var260: String!, $var261: String!, $var262: String!, $var263: String!, $var264: String!, $var265: String!, $var266: String!, $var267: String!, $var268: String!, $var269: String!, $var270: String!, $var271: String!, $var272: String!, $var273: String!, $var274: String!, $var275: String!, $var276: String!, $var277: String!, $var278: String!, $var279: String!, $var280: String!, $var281: String!, $var282: String!, $var283: String!, $var284: String!, $var285: String!, $var286: String!, $var287: String!, $var288: String!, $var289: String!, $var290: String!, $var291: String!, $var292: String!, $var293: String!, $var294: String!, $var295: String!, $var296: String!, $var297: String!, $var298: String!, $var299: String!, $var300: String!, $var301: String!, $var302: String!, $var303: String!, $var304: String!, $var305: String!, $var306: String!, $var307: String!, $var308: String!, $var309: String!, $var310: String!, $var311: String!, $var312: String!, $var313: String!, $var314: String!, $var315: String!, $var316: String!, $var317: String!, $var318: String!, $var319: String!, $var320: String!, $var321: String!, $var322: String!, $var323: String!, $var324: String!, $var325: String!, $var326: String!, $var327: String!, $var328: String!, $var329: String!, $var330: String!, $var331: String!, $var332: String!, $var333: String!, $var334: String!, $var335: String!, $var336: String!, $var337: String!, $var338: String!, $var339: String!, $var340: String!, $var341: String!, $var342: String!, $var343: String!, $var344: String!, $var345: String!, $var346: String!, $var347: String!, $var348: String!, $var349: String!, $var350: String!, $var351: String!, $var352: String!, $var353: String!, $var354: String!, $var355: String!, $var356: String!, $var357: String!, $var358: String!, $var359: String!, $var360: String!, $var361: String!, $var362: String!, $var363: String!, $var364: String!, $var365: String!, $var366: String!, $var367: String!, $var368: String!, $var369: String!, $var370: String!, $var371: String!, $var372: String!, $var373: String!, $var374: String!, $var375: String!, $var376: String!, $var377: String!, $var378: String!, $var379: String!, $var380: String!, $var381: String!, $var382: String!, $var383: String!, $var384: String!, $var385: String!, $var386: String!, $var387: String!, $var388: String!, $var389: String!, $var390: String!, $var391: String!, $var392: String!, $var393: String!, $var394: String!, $var395: String!, $var396: String!, $var397: String!, $var398: String!, $var399: String!, $var400: String!, $var401: String!, $var402: String!, $var403: String!, $var404: String!, $var405: String!, $var406: String!, $var407: String!, $var408: String!, $var409: String!, $var410: String!, $var411: String!, $var412: String!, $var413: String!, $var414: String!, $var415: String!, $var416: String!, $var417: String!, $var418: String!, $var419: String!, $var420: String!, $var421: String!, $var422: String!, $var423: String!, $var424: String!, $var425: String!, $var426: String!, $var427: String!, $var428: String!, $var429: String!, $var430: String!, $var431: String!, $var432: String!, $var433: String!, $var434: String!, $var435: String!, $var436: String!, $var437: String!, $var438: String!, $var439: String!, $var440: String!, $var441: String!, $var442: String!, $var443: String!, $var444: String!, $var445: String!, $var446: String!, $var447: String!, $var448: String!, $var449: String!, $var450: String!, $var451: String!, $var452: String!, $var453: String!, $var454: String!, $var455: String!, $var456: String!, $var457: String!, $var458: String!, $var459: String!, $var460: String!, $var461: String!, $var462: String!, $var463: String!, $var464: String!, $var465: String!, $var466: String!, $var467: String!, $var468: String!, $var469: String!, $var470: String!, $var471: String!, $var472: String!, $var473: String!, $var474: String!, $var475: String!, $var476: String!, $var477: String!, $var478: String!, $var479: String!, $var480: String!, $var481: String!, $var482: String!, $var483: String!, $var484: String!, $var485: String!, $var486: String!, $var487: String!, $var488: String!, $var489: String!, $var490: String!, $var491: String!, $var492: String!, $var493: String!, $var494: String!, $var495: String!, $var496: String!, $var497: String!, $var498: String!, $var499: String!, $var500: String!, $var501: String!, $var502: String!, $var503: String!, $var504: String!, $var505: String!, $var506: String!, $var507: String!, $var508: String!, $var509: String!, $var510: String!, $var511: String!, $var512: String!, $var513: String!, $var514: String!, $var515: String!, $var516: String!, $var517: String!, $var518: String!, $var519: String!, $var520: String!, $var521: String!, $var522: String!, $var523: String!, $var524: String!, $var525: String!, $var526: String!, $var527: String!, $var528: String!, $var529: String!, $var530: String!, $var531: String!, $var532: String!, $var533: String!, $var534: String!, $var535: String!, $var536: String!, $var537: String!, $var538: String!, $var539: String!, $var540: String!, $var541: String!, $var542: String!, $var543: String!, $var544: String!, $var545: String!, $var546: String!, $var547: String!, $var548: String!, $var549: String!, $var550: String!, $var551: String!, $var552: String!, $var553: String!, $var554: String!, $var555: String!, $var556: String!, $var557: String!, $var558: String!, $var559: String!, $var560: String!, $var561: String!, $var562: String!, $var563: String!, $var564: String!, $var565: String!, $var566: String!, $var567: String!, $var568: String!, $var569: String!, $var570: String!, $var571: String!, $var572: String!, $var573: String!, $var574: String!, $var575: String!, $var576: String!, $var577: String!, $var578: String!, $var579: String!, $var580: String!, $var581: String!, $var582: String!, $var583: String!, $var584: String!, $var585: String!, $var586: String!, $var587: String!, $var588: String!, $var589: String!, $var590: String!, $var591: String!, $var592: String!, $var593: String!, $var594: String!, $var595: String!, $var596: String!, $var597: String!, $var598: String!, $var599: String!, $var600: String!, $var601: String!, $var602: String!, $var603: String!, $var604: String!, $var605: String!, $var606: String!, $var607: String!, $var608: String!, $var609: String!, $var610: String!, $var611: String!, $var612: String!, $var613: String!, $var614: String!, $var615: String!, $var616: String!, $var617: String!, $var618: String!, $var619: String!, $var620: String!, $var621: String!, $var622: String!, $var623: String!, $var624: String!, $var625: String!, $var626: String!, $var627: String!, $var628: String!, $var629: String!, $var630: String!, $var631: String!, $var632: String!, $var633: String!, $var634: String!, $var635: String!, $var636: String!, $var637: String!, $var638: String!, $var639: String!, $var640: String!, $var641: String!, $var642: String!, $var643: String!, $var644: String!, $var645: String!, $var646: String!, $var647: String!, $var648: String!, $var649: String!, $var650: String!, $var651: String!, $var652: String!, $var653: String!, $var654: String!, $var655: String!, $var656: String!, $var657: String!, $var658: String!, $var659: String!, $var660: String!, $var661: String!, $var662: String!, $var663: String!, $var664: String!, $var665: String!, $var666: String!, $var667: String!, $var668: String!, $var669: String!, $var670: String!, $var671: String!, $var672: String!, $var673: String!, $var674: String!, $var675: String!, $var676: String!, $var677: String!, $var678: String!, $var679: String!, $var680: String!, $var681: String!, $var682: String!, $var683: String!, $var684: String!, $var685: String!, $var686: String!, $var687: String!, $var688: String!, $var689: String!, $var690: String!, $var691: String!, $var692: String!, $var693: String!, $var694: String!, $var695: String!, $var696: String!, $var697: String!, $var698: String!, $var699: String!, $var700: String!, $var701: String!, $var702: String!, $var703: String!, $var704: String!, $var705: String!, $var706: String!, $var707: String!, $var708: String!, $var709: String!, $var710: String!, $var711: String!, $var712: String!, $var713: String!, $var714: String!, $var715: String!, $var716: String!, $var717: String!, $var718: String!, $var719: String!, $var720: String!, $var721: String!, $var722: String!, $var723: String!, $var724: String!, $var725: String!, $var726: String!, $var727: String!, $var728: String!, $var729: String!, $var730: String!, $var731: String!, $var732: String!, $var733: String!, $var734: String!, $var735: String!, $var736: String!, $var737: String!, $var738: String!, $var739: String!, $var740: String!, $var741: String!, $var742: String!, $var743: String!, $var744: String!, $var745: String!, $var746: String!, $var747: String!, $var748: String!, $var749: String!, $var750: String!, $var751: String!, $var752: String!, $var753: String!, $var754: String!, $var755: String!, $var756: String!, $var757: String!, $var758: String!, $var759: String!, $var760: String!, $var761: String!, $var762: String!, $var763: String!, $var764: String!, $var765: String!, $var766: String!, $var767: String!, $var768: String!, $var769: String!, $var770: String!, $var771: String!, $var772: String!, $var773: String!, $var774: String!, $var775: String!, $var776: String!, $var777: String!, $var778: String!, $var779: String!, $var780: String!, $var781: String!, $var782: String!, $var783: String!, $var784: String!, $var785: String!, $var786: String!, $var787: String!, $var788: String!, $var789: String!, $var790: String!, $var791: String!, $var792: String!, $var793: String!, $var794: String!, $var795: String!, $var796: String!, $var797: String!, $var798: String!, $var799: String!, $var800: String!, $var801: String!, $var802: String!, $var803: String!, $var804: String!, $var805: String!, $var806: String!, $var807: String!, $var808: String!, $var809: String!, $var810: String!, $var811: String!, $var812: String!, $var813: String!, $var814: String!, $var815: String!, $var816: String!, $var817: String!, $var818: String!, $var819: String!, $var820: String!, $var821: String!, $var822: String!, $var823: String!, $var824: String!, $var825: String!, $var826: String!, $var827: String!, $var828: String!, $var829: String!, $var830: String!, $var831: String!, $var832: String!, $var833: String!, $var834: String!, $var835: String!, $var836: String!, $var837: String!, $var838: String!, $var839: String!, $var840: String!, $var841: String!, $var842: String!, $var843: String!, $var844: String!, $var845: String!, $var846: String!, $var847: String!, $var848: String!, $var849: String!, $var850: String!, $var851: String!, $var852: String!, $var853: String!, $var854: String!, $var855: String!, $var856: String!, $var857: String!, $var858: String!, $var859: String!, $var860: String!, $var861: String!, $var862: String!, $var863: String!, $var864: String!, $var865: String!, $var866: String!, $var867: String!, $var868: String!, $var869: String!, $var870: String!, $var871: String!, $var872: String!, $var873: String!, $var874: String!, $var875: String!, $var876: String!, $var877: String!, $var878: String!, $var879: String!, $var880: String!, $var881: String!, $var882: String!, $var883: String!, $var884: String!, $var885: String!, $var886: String!, $var887: String!, $var888: String!, $var889: String!, $var890: String!, $var891: String!, $var892: String!, $var893: String!, $var894: String!, $var895: String!, $var896: String!, $var897: String!, $var898: String!, $var899: String!, $var900: String!, $var901: String!, $var902: String!, $var903: String!, $var904: String!, $var905: String!, $var906: String!, $var907: String!, $var908: String!, $var909: String!, $var910: String!, $var911: String!, $var912: String!, $var913: String!, $var914: String!, $var915: String!, $var916: String!, $var917: String!, $var918: String!, $var919: String!, $var920: String!, $var921: String!, $var922: String!, $var923: String!, $var924: String!, $var925: String!, $var926: String!, $var927: String!, $var928: String!, $var929: String!, $var930: String!, $var931: String!, $var932: String!, $var933: String!, $var934: String!, $var935: String!, $var936: String!, $var937: String!, $var938: String!, $var939: String!, $var940: String!, $var941: String!, $var942: String!, $var943: String!, $var944: String!, $var945: String!, $var946: String!, $var947: String!, $var948: String!, $var949: String!, $var950: String!, $var951: String!, $var952: String!, $var953: String!, $var954: String!, $var955: String!, $var956: String!, $var957: String!, $var958: String!, $var959: String!, $var960: String!, $var961: String!, $var962: String!, $var963: String!, $var964: String!, $var965: String!, $var966: String!, $var967: String!, $var968: String!, $var969: String!, $var970: String!, $var971: String!, $var972: String!, $var973: String!, $var974: String!, $var975: String!, $var976: String!, $var977: String!, $var978: String!, $var979: String!, $var980: String!, $var981: String!, $var982: String!, $var983: String!, $var984: String!, $var985: String!, $var986: String!, $var987: String!, $var988: String!, $var989: String!, $var990: String!, $var991: String!, $var992: String!, $var993: String!, $var994: String!, $var995: String!, $var996: String!, $var997: String!, $var998: String!, $var999: String!, $var1000: String!) { + hum0: human(id: $var0) { + name + } + hum1: human(id: $var1) { + name + } + hum2: human(id: $var2) { + name + } + hum3: human(id: $var3) { + name + } + hum4: human(id: $var4) { + name + } + hum5: human(id: $var5) { + name + } + hum6: human(id: $var6) { + name + } + hum7: human(id: $var7) { + name + } + hum8: human(id: $var8) { + name + } + hum9: human(id: $var9) { + name + } + hum10: human(id: $var10) { + name + } + hum11: human(id: $var11) { + name + } + hum12: human(id: $var12) { + name + } + hum13: human(id: $var13) { + name + } + hum14: human(id: $var14) { + name + } + hum15: human(id: $var15) { + name + } + hum16: human(id: $var16) { + name + } + hum17: human(id: $var17) { + name + } + hum18: human(id: $var18) { + name + } + hum19: human(id: $var19) { + name + } + hum20: human(id: $var20) { + name + } + hum21: human(id: $var21) { + name + } + hum22: human(id: $var22) { + name + } + hum23: human(id: $var23) { + name + } + hum24: human(id: $var24) { + name + } + hum25: human(id: $var25) { + name + } + hum26: human(id: $var26) { + name + } + hum27: human(id: $var27) { + name + } + hum28: human(id: $var28) { + name + } + hum29: human(id: $var29) { + name + } + hum30: human(id: $var30) { + name + } + hum31: human(id: $var31) { + name + } + hum32: human(id: $var32) { + name + } + hum33: human(id: $var33) { + name + } + hum34: human(id: $var34) { + name + } + hum35: human(id: $var35) { + name + } + hum36: human(id: $var36) { + name + } + hum37: human(id: $var37) { + name + } + hum38: human(id: $var38) { + name + } + hum39: human(id: $var39) { + name + } + hum40: human(id: $var40) { + name + } + hum41: human(id: $var41) { + name + } + hum42: human(id: $var42) { + name + } + hum43: human(id: $var43) { + name + } + hum44: human(id: $var44) { + name + } + hum45: human(id: $var45) { + name + } + hum46: human(id: $var46) { + name + } + hum47: human(id: $var47) { + name + } + hum48: human(id: $var48) { + name + } + hum49: human(id: $var49) { + name + } + hum50: human(id: $var50) { + name + } + hum51: human(id: $var51) { + name + } + hum52: human(id: $var52) { + name + } + hum53: human(id: $var53) { + name + } + hum54: human(id: $var54) { + name + } + hum55: human(id: $var55) { + name + } + hum56: human(id: $var56) { + name + } + hum57: human(id: $var57) { + name + } + hum58: human(id: $var58) { + name + } + hum59: human(id: $var59) { + name + } + hum60: human(id: $var60) { + name + } + hum61: human(id: $var61) { + name + } + hum62: human(id: $var62) { + name + } + hum63: human(id: $var63) { + name + } + hum64: human(id: $var64) { + name + } + hum65: human(id: $var65) { + name + } + hum66: human(id: $var66) { + name + } + hum67: human(id: $var67) { + name + } + hum68: human(id: $var68) { + name + } + hum69: human(id: $var69) { + name + } + hum70: human(id: $var70) { + name + } + hum71: human(id: $var71) { + name + } + hum72: human(id: $var72) { + name + } + hum73: human(id: $var73) { + name + } + hum74: human(id: $var74) { + name + } + hum75: human(id: $var75) { + name + } + hum76: human(id: $var76) { + name + } + hum77: human(id: $var77) { + name + } + hum78: human(id: $var78) { + name + } + hum79: human(id: $var79) { + name + } + hum80: human(id: $var80) { + name + } + hum81: human(id: $var81) { + name + } + hum82: human(id: $var82) { + name + } + hum83: human(id: $var83) { + name + } + hum84: human(id: $var84) { + name + } + hum85: human(id: $var85) { + name + } + hum86: human(id: $var86) { + name + } + hum87: human(id: $var87) { + name + } + hum88: human(id: $var88) { + name + } + hum89: human(id: $var89) { + name + } + hum90: human(id: $var90) { + name + } + hum91: human(id: $var91) { + name + } + hum92: human(id: $var92) { + name + } + hum93: human(id: $var93) { + name + } + hum94: human(id: $var94) { + name + } + hum95: human(id: $var95) { + name + } + hum96: human(id: $var96) { + name + } + hum97: human(id: $var97) { + name + } + hum98: human(id: $var98) { + name + } + hum99: human(id: $var99) { + name + } + hum100: human(id: $var100) { + name + } + hum101: human(id: $var101) { + name + } + hum102: human(id: $var102) { + name + } + hum103: human(id: $var103) { + name + } + hum104: human(id: $var104) { + name + } + hum105: human(id: $var105) { + name + } + hum106: human(id: $var106) { + name + } + hum107: human(id: $var107) { + name + } + hum108: human(id: $var108) { + name + } + hum109: human(id: $var109) { + name + } + hum110: human(id: $var110) { + name + } + hum111: human(id: $var111) { + name + } + hum112: human(id: $var112) { + name + } + hum113: human(id: $var113) { + name + } + hum114: human(id: $var114) { + name + } + hum115: human(id: $var115) { + name + } + hum116: human(id: $var116) { + name + } + hum117: human(id: $var117) { + name + } + hum118: human(id: $var118) { + name + } + hum119: human(id: $var119) { + name + } + hum120: human(id: $var120) { + name + } + hum121: human(id: $var121) { + name + } + hum122: human(id: $var122) { + name + } + hum123: human(id: $var123) { + name + } + hum124: human(id: $var124) { + name + } + hum125: human(id: $var125) { + name + } + hum126: human(id: $var126) { + name + } + hum127: human(id: $var127) { + name + } + hum128: human(id: $var128) { + name + } + hum129: human(id: $var129) { + name + } + hum130: human(id: $var130) { + name + } + hum131: human(id: $var131) { + name + } + hum132: human(id: $var132) { + name + } + hum133: human(id: $var133) { + name + } + hum134: human(id: $var134) { + name + } + hum135: human(id: $var135) { + name + } + hum136: human(id: $var136) { + name + } + hum137: human(id: $var137) { + name + } + hum138: human(id: $var138) { + name + } + hum139: human(id: $var139) { + name + } + hum140: human(id: $var140) { + name + } + hum141: human(id: $var141) { + name + } + hum142: human(id: $var142) { + name + } + hum143: human(id: $var143) { + name + } + hum144: human(id: $var144) { + name + } + hum145: human(id: $var145) { + name + } + hum146: human(id: $var146) { + name + } + hum147: human(id: $var147) { + name + } + hum148: human(id: $var148) { + name + } + hum149: human(id: $var149) { + name + } + hum150: human(id: $var150) { + name + } + hum151: human(id: $var151) { + name + } + hum152: human(id: $var152) { + name + } + hum153: human(id: $var153) { + name + } + hum154: human(id: $var154) { + name + } + hum155: human(id: $var155) { + name + } + hum156: human(id: $var156) { + name + } + hum157: human(id: $var157) { + name + } + hum158: human(id: $var158) { + name + } + hum159: human(id: $var159) { + name + } + hum160: human(id: $var160) { + name + } + hum161: human(id: $var161) { + name + } + hum162: human(id: $var162) { + name + } + hum163: human(id: $var163) { + name + } + hum164: human(id: $var164) { + name + } + hum165: human(id: $var165) { + name + } + hum166: human(id: $var166) { + name + } + hum167: human(id: $var167) { + name + } + hum168: human(id: $var168) { + name + } + hum169: human(id: $var169) { + name + } + hum170: human(id: $var170) { + name + } + hum171: human(id: $var171) { + name + } + hum172: human(id: $var172) { + name + } + hum173: human(id: $var173) { + name + } + hum174: human(id: $var174) { + name + } + hum175: human(id: $var175) { + name + } + hum176: human(id: $var176) { + name + } + hum177: human(id: $var177) { + name + } + hum178: human(id: $var178) { + name + } + hum179: human(id: $var179) { + name + } + hum180: human(id: $var180) { + name + } + hum181: human(id: $var181) { + name + } + hum182: human(id: $var182) { + name + } + hum183: human(id: $var183) { + name + } + hum184: human(id: $var184) { + name + } + hum185: human(id: $var185) { + name + } + hum186: human(id: $var186) { + name + } + hum187: human(id: $var187) { + name + } + hum188: human(id: $var188) { + name + } + hum189: human(id: $var189) { + name + } + hum190: human(id: $var190) { + name + } + hum191: human(id: $var191) { + name + } + hum192: human(id: $var192) { + name + } + hum193: human(id: $var193) { + name + } + hum194: human(id: $var194) { + name + } + hum195: human(id: $var195) { + name + } + hum196: human(id: $var196) { + name + } + hum197: human(id: $var197) { + name + } + hum198: human(id: $var198) { + name + } + hum199: human(id: $var199) { + name + } + hum200: human(id: $var200) { + name + } + hum201: human(id: $var201) { + name + } + hum202: human(id: $var202) { + name + } + hum203: human(id: $var203) { + name + } + hum204: human(id: $var204) { + name + } + hum205: human(id: $var205) { + name + } + hum206: human(id: $var206) { + name + } + hum207: human(id: $var207) { + name + } + hum208: human(id: $var208) { + name + } + hum209: human(id: $var209) { + name + } + hum210: human(id: $var210) { + name + } + hum211: human(id: $var211) { + name + } + hum212: human(id: $var212) { + name + } + hum213: human(id: $var213) { + name + } + hum214: human(id: $var214) { + name + } + hum215: human(id: $var215) { + name + } + hum216: human(id: $var216) { + name + } + hum217: human(id: $var217) { + name + } + hum218: human(id: $var218) { + name + } + hum219: human(id: $var219) { + name + } + hum220: human(id: $var220) { + name + } + hum221: human(id: $var221) { + name + } + hum222: human(id: $var222) { + name + } + hum223: human(id: $var223) { + name + } + hum224: human(id: $var224) { + name + } + hum225: human(id: $var225) { + name + } + hum226: human(id: $var226) { + name + } + hum227: human(id: $var227) { + name + } + hum228: human(id: $var228) { + name + } + hum229: human(id: $var229) { + name + } + hum230: human(id: $var230) { + name + } + hum231: human(id: $var231) { + name + } + hum232: human(id: $var232) { + name + } + hum233: human(id: $var233) { + name + } + hum234: human(id: $var234) { + name + } + hum235: human(id: $var235) { + name + } + hum236: human(id: $var236) { + name + } + hum237: human(id: $var237) { + name + } + hum238: human(id: $var238) { + name + } + hum239: human(id: $var239) { + name + } + hum240: human(id: $var240) { + name + } + hum241: human(id: $var241) { + name + } + hum242: human(id: $var242) { + name + } + hum243: human(id: $var243) { + name + } + hum244: human(id: $var244) { + name + } + hum245: human(id: $var245) { + name + } + hum246: human(id: $var246) { + name + } + hum247: human(id: $var247) { + name + } + hum248: human(id: $var248) { + name + } + hum249: human(id: $var249) { + name + } + hum250: human(id: $var250) { + name + } + hum251: human(id: $var251) { + name + } + hum252: human(id: $var252) { + name + } + hum253: human(id: $var253) { + name + } + hum254: human(id: $var254) { + name + } + hum255: human(id: $var255) { + name + } + hum256: human(id: $var256) { + name + } + hum257: human(id: $var257) { + name + } + hum258: human(id: $var258) { + name + } + hum259: human(id: $var259) { + name + } + hum260: human(id: $var260) { + name + } + hum261: human(id: $var261) { + name + } + hum262: human(id: $var262) { + name + } + hum263: human(id: $var263) { + name + } + hum264: human(id: $var264) { + name + } + hum265: human(id: $var265) { + name + } + hum266: human(id: $var266) { + name + } + hum267: human(id: $var267) { + name + } + hum268: human(id: $var268) { + name + } + hum269: human(id: $var269) { + name + } + hum270: human(id: $var270) { + name + } + hum271: human(id: $var271) { + name + } + hum272: human(id: $var272) { + name + } + hum273: human(id: $var273) { + name + } + hum274: human(id: $var274) { + name + } + hum275: human(id: $var275) { + name + } + hum276: human(id: $var276) { + name + } + hum277: human(id: $var277) { + name + } + hum278: human(id: $var278) { + name + } + hum279: human(id: $var279) { + name + } + hum280: human(id: $var280) { + name + } + hum281: human(id: $var281) { + name + } + hum282: human(id: $var282) { + name + } + hum283: human(id: $var283) { + name + } + hum284: human(id: $var284) { + name + } + hum285: human(id: $var285) { + name + } + hum286: human(id: $var286) { + name + } + hum287: human(id: $var287) { + name + } + hum288: human(id: $var288) { + name + } + hum289: human(id: $var289) { + name + } + hum290: human(id: $var290) { + name + } + hum291: human(id: $var291) { + name + } + hum292: human(id: $var292) { + name + } + hum293: human(id: $var293) { + name + } + hum294: human(id: $var294) { + name + } + hum295: human(id: $var295) { + name + } + hum296: human(id: $var296) { + name + } + hum297: human(id: $var297) { + name + } + hum298: human(id: $var298) { + name + } + hum299: human(id: $var299) { + name + } + hum300: human(id: $var300) { + name + } + hum301: human(id: $var301) { + name + } + hum302: human(id: $var302) { + name + } + hum303: human(id: $var303) { + name + } + hum304: human(id: $var304) { + name + } + hum305: human(id: $var305) { + name + } + hum306: human(id: $var306) { + name + } + hum307: human(id: $var307) { + name + } + hum308: human(id: $var308) { + name + } + hum309: human(id: $var309) { + name + } + hum310: human(id: $var310) { + name + } + hum311: human(id: $var311) { + name + } + hum312: human(id: $var312) { + name + } + hum313: human(id: $var313) { + name + } + hum314: human(id: $var314) { + name + } + hum315: human(id: $var315) { + name + } + hum316: human(id: $var316) { + name + } + hum317: human(id: $var317) { + name + } + hum318: human(id: $var318) { + name + } + hum319: human(id: $var319) { + name + } + hum320: human(id: $var320) { + name + } + hum321: human(id: $var321) { + name + } + hum322: human(id: $var322) { + name + } + hum323: human(id: $var323) { + name + } + hum324: human(id: $var324) { + name + } + hum325: human(id: $var325) { + name + } + hum326: human(id: $var326) { + name + } + hum327: human(id: $var327) { + name + } + hum328: human(id: $var328) { + name + } + hum329: human(id: $var329) { + name + } + hum330: human(id: $var330) { + name + } + hum331: human(id: $var331) { + name + } + hum332: human(id: $var332) { + name + } + hum333: human(id: $var333) { + name + } + hum334: human(id: $var334) { + name + } + hum335: human(id: $var335) { + name + } + hum336: human(id: $var336) { + name + } + hum337: human(id: $var337) { + name + } + hum338: human(id: $var338) { + name + } + hum339: human(id: $var339) { + name + } + hum340: human(id: $var340) { + name + } + hum341: human(id: $var341) { + name + } + hum342: human(id: $var342) { + name + } + hum343: human(id: $var343) { + name + } + hum344: human(id: $var344) { + name + } + hum345: human(id: $var345) { + name + } + hum346: human(id: $var346) { + name + } + hum347: human(id: $var347) { + name + } + hum348: human(id: $var348) { + name + } + hum349: human(id: $var349) { + name + } + hum350: human(id: $var350) { + name + } + hum351: human(id: $var351) { + name + } + hum352: human(id: $var352) { + name + } + hum353: human(id: $var353) { + name + } + hum354: human(id: $var354) { + name + } + hum355: human(id: $var355) { + name + } + hum356: human(id: $var356) { + name + } + hum357: human(id: $var357) { + name + } + hum358: human(id: $var358) { + name + } + hum359: human(id: $var359) { + name + } + hum360: human(id: $var360) { + name + } + hum361: human(id: $var361) { + name + } + hum362: human(id: $var362) { + name + } + hum363: human(id: $var363) { + name + } + hum364: human(id: $var364) { + name + } + hum365: human(id: $var365) { + name + } + hum366: human(id: $var366) { + name + } + hum367: human(id: $var367) { + name + } + hum368: human(id: $var368) { + name + } + hum369: human(id: $var369) { + name + } + hum370: human(id: $var370) { + name + } + hum371: human(id: $var371) { + name + } + hum372: human(id: $var372) { + name + } + hum373: human(id: $var373) { + name + } + hum374: human(id: $var374) { + name + } + hum375: human(id: $var375) { + name + } + hum376: human(id: $var376) { + name + } + hum377: human(id: $var377) { + name + } + hum378: human(id: $var378) { + name + } + hum379: human(id: $var379) { + name + } + hum380: human(id: $var380) { + name + } + hum381: human(id: $var381) { + name + } + hum382: human(id: $var382) { + name + } + hum383: human(id: $var383) { + name + } + hum384: human(id: $var384) { + name + } + hum385: human(id: $var385) { + name + } + hum386: human(id: $var386) { + name + } + hum387: human(id: $var387) { + name + } + hum388: human(id: $var388) { + name + } + hum389: human(id: $var389) { + name + } + hum390: human(id: $var390) { + name + } + hum391: human(id: $var391) { + name + } + hum392: human(id: $var392) { + name + } + hum393: human(id: $var393) { + name + } + hum394: human(id: $var394) { + name + } + hum395: human(id: $var395) { + name + } + hum396: human(id: $var396) { + name + } + hum397: human(id: $var397) { + name + } + hum398: human(id: $var398) { + name + } + hum399: human(id: $var399) { + name + } + hum400: human(id: $var400) { + name + } + hum401: human(id: $var401) { + name + } + hum402: human(id: $var402) { + name + } + hum403: human(id: $var403) { + name + } + hum404: human(id: $var404) { + name + } + hum405: human(id: $var405) { + name + } + hum406: human(id: $var406) { + name + } + hum407: human(id: $var407) { + name + } + hum408: human(id: $var408) { + name + } + hum409: human(id: $var409) { + name + } + hum410: human(id: $var410) { + name + } + hum411: human(id: $var411) { + name + } + hum412: human(id: $var412) { + name + } + hum413: human(id: $var413) { + name + } + hum414: human(id: $var414) { + name + } + hum415: human(id: $var415) { + name + } + hum416: human(id: $var416) { + name + } + hum417: human(id: $var417) { + name + } + hum418: human(id: $var418) { + name + } + hum419: human(id: $var419) { + name + } + hum420: human(id: $var420) { + name + } + hum421: human(id: $var421) { + name + } + hum422: human(id: $var422) { + name + } + hum423: human(id: $var423) { + name + } + hum424: human(id: $var424) { + name + } + hum425: human(id: $var425) { + name + } + hum426: human(id: $var426) { + name + } + hum427: human(id: $var427) { + name + } + hum428: human(id: $var428) { + name + } + hum429: human(id: $var429) { + name + } + hum430: human(id: $var430) { + name + } + hum431: human(id: $var431) { + name + } + hum432: human(id: $var432) { + name + } + hum433: human(id: $var433) { + name + } + hum434: human(id: $var434) { + name + } + hum435: human(id: $var435) { + name + } + hum436: human(id: $var436) { + name + } + hum437: human(id: $var437) { + name + } + hum438: human(id: $var438) { + name + } + hum439: human(id: $var439) { + name + } + hum440: human(id: $var440) { + name + } + hum441: human(id: $var441) { + name + } + hum442: human(id: $var442) { + name + } + hum443: human(id: $var443) { + name + } + hum444: human(id: $var444) { + name + } + hum445: human(id: $var445) { + name + } + hum446: human(id: $var446) { + name + } + hum447: human(id: $var447) { + name + } + hum448: human(id: $var448) { + name + } + hum449: human(id: $var449) { + name + } + hum450: human(id: $var450) { + name + } + hum451: human(id: $var451) { + name + } + hum452: human(id: $var452) { + name + } + hum453: human(id: $var453) { + name + } + hum454: human(id: $var454) { + name + } + hum455: human(id: $var455) { + name + } + hum456: human(id: $var456) { + name + } + hum457: human(id: $var457) { + name + } + hum458: human(id: $var458) { + name + } + hum459: human(id: $var459) { + name + } + hum460: human(id: $var460) { + name + } + hum461: human(id: $var461) { + name + } + hum462: human(id: $var462) { + name + } + hum463: human(id: $var463) { + name + } + hum464: human(id: $var464) { + name + } + hum465: human(id: $var465) { + name + } + hum466: human(id: $var466) { + name + } + hum467: human(id: $var467) { + name + } + hum468: human(id: $var468) { + name + } + hum469: human(id: $var469) { + name + } + hum470: human(id: $var470) { + name + } + hum471: human(id: $var471) { + name + } + hum472: human(id: $var472) { + name + } + hum473: human(id: $var473) { + name + } + hum474: human(id: $var474) { + name + } + hum475: human(id: $var475) { + name + } + hum476: human(id: $var476) { + name + } + hum477: human(id: $var477) { + name + } + hum478: human(id: $var478) { + name + } + hum479: human(id: $var479) { + name + } + hum480: human(id: $var480) { + name + } + hum481: human(id: $var481) { + name + } + hum482: human(id: $var482) { + name + } + hum483: human(id: $var483) { + name + } + hum484: human(id: $var484) { + name + } + hum485: human(id: $var485) { + name + } + hum486: human(id: $var486) { + name + } + hum487: human(id: $var487) { + name + } + hum488: human(id: $var488) { + name + } + hum489: human(id: $var489) { + name + } + hum490: human(id: $var490) { + name + } + hum491: human(id: $var491) { + name + } + hum492: human(id: $var492) { + name + } + hum493: human(id: $var493) { + name + } + hum494: human(id: $var494) { + name + } + hum495: human(id: $var495) { + name + } + hum496: human(id: $var496) { + name + } + hum497: human(id: $var497) { + name + } + hum498: human(id: $var498) { + name + } + hum499: human(id: $var499) { + name + } + hum500: human(id: $var500) { + name + } + hum501: human(id: $var501) { + name + } + hum502: human(id: $var502) { + name + } + hum503: human(id: $var503) { + name + } + hum504: human(id: $var504) { + name + } + hum505: human(id: $var505) { + name + } + hum506: human(id: $var506) { + name + } + hum507: human(id: $var507) { + name + } + hum508: human(id: $var508) { + name + } + hum509: human(id: $var509) { + name + } + hum510: human(id: $var510) { + name + } + hum511: human(id: $var511) { + name + } + hum512: human(id: $var512) { + name + } + hum513: human(id: $var513) { + name + } + hum514: human(id: $var514) { + name + } + hum515: human(id: $var515) { + name + } + hum516: human(id: $var516) { + name + } + hum517: human(id: $var517) { + name + } + hum518: human(id: $var518) { + name + } + hum519: human(id: $var519) { + name + } + hum520: human(id: $var520) { + name + } + hum521: human(id: $var521) { + name + } + hum522: human(id: $var522) { + name + } + hum523: human(id: $var523) { + name + } + hum524: human(id: $var524) { + name + } + hum525: human(id: $var525) { + name + } + hum526: human(id: $var526) { + name + } + hum527: human(id: $var527) { + name + } + hum528: human(id: $var528) { + name + } + hum529: human(id: $var529) { + name + } + hum530: human(id: $var530) { + name + } + hum531: human(id: $var531) { + name + } + hum532: human(id: $var532) { + name + } + hum533: human(id: $var533) { + name + } + hum534: human(id: $var534) { + name + } + hum535: human(id: $var535) { + name + } + hum536: human(id: $var536) { + name + } + hum537: human(id: $var537) { + name + } + hum538: human(id: $var538) { + name + } + hum539: human(id: $var539) { + name + } + hum540: human(id: $var540) { + name + } + hum541: human(id: $var541) { + name + } + hum542: human(id: $var542) { + name + } + hum543: human(id: $var543) { + name + } + hum544: human(id: $var544) { + name + } + hum545: human(id: $var545) { + name + } + hum546: human(id: $var546) { + name + } + hum547: human(id: $var547) { + name + } + hum548: human(id: $var548) { + name + } + hum549: human(id: $var549) { + name + } + hum550: human(id: $var550) { + name + } + hum551: human(id: $var551) { + name + } + hum552: human(id: $var552) { + name + } + hum553: human(id: $var553) { + name + } + hum554: human(id: $var554) { + name + } + hum555: human(id: $var555) { + name + } + hum556: human(id: $var556) { + name + } + hum557: human(id: $var557) { + name + } + hum558: human(id: $var558) { + name + } + hum559: human(id: $var559) { + name + } + hum560: human(id: $var560) { + name + } + hum561: human(id: $var561) { + name + } + hum562: human(id: $var562) { + name + } + hum563: human(id: $var563) { + name + } + hum564: human(id: $var564) { + name + } + hum565: human(id: $var565) { + name + } + hum566: human(id: $var566) { + name + } + hum567: human(id: $var567) { + name + } + hum568: human(id: $var568) { + name + } + hum569: human(id: $var569) { + name + } + hum570: human(id: $var570) { + name + } + hum571: human(id: $var571) { + name + } + hum572: human(id: $var572) { + name + } + hum573: human(id: $var573) { + name + } + hum574: human(id: $var574) { + name + } + hum575: human(id: $var575) { + name + } + hum576: human(id: $var576) { + name + } + hum577: human(id: $var577) { + name + } + hum578: human(id: $var578) { + name + } + hum579: human(id: $var579) { + name + } + hum580: human(id: $var580) { + name + } + hum581: human(id: $var581) { + name + } + hum582: human(id: $var582) { + name + } + hum583: human(id: $var583) { + name + } + hum584: human(id: $var584) { + name + } + hum585: human(id: $var585) { + name + } + hum586: human(id: $var586) { + name + } + hum587: human(id: $var587) { + name + } + hum588: human(id: $var588) { + name + } + hum589: human(id: $var589) { + name + } + hum590: human(id: $var590) { + name + } + hum591: human(id: $var591) { + name + } + hum592: human(id: $var592) { + name + } + hum593: human(id: $var593) { + name + } + hum594: human(id: $var594) { + name + } + hum595: human(id: $var595) { + name + } + hum596: human(id: $var596) { + name + } + hum597: human(id: $var597) { + name + } + hum598: human(id: $var598) { + name + } + hum599: human(id: $var599) { + name + } + hum600: human(id: $var600) { + name + } + hum601: human(id: $var601) { + name + } + hum602: human(id: $var602) { + name + } + hum603: human(id: $var603) { + name + } + hum604: human(id: $var604) { + name + } + hum605: human(id: $var605) { + name + } + hum606: human(id: $var606) { + name + } + hum607: human(id: $var607) { + name + } + hum608: human(id: $var608) { + name + } + hum609: human(id: $var609) { + name + } + hum610: human(id: $var610) { + name + } + hum611: human(id: $var611) { + name + } + hum612: human(id: $var612) { + name + } + hum613: human(id: $var613) { + name + } + hum614: human(id: $var614) { + name + } + hum615: human(id: $var615) { + name + } + hum616: human(id: $var616) { + name + } + hum617: human(id: $var617) { + name + } + hum618: human(id: $var618) { + name + } + hum619: human(id: $var619) { + name + } + hum620: human(id: $var620) { + name + } + hum621: human(id: $var621) { + name + } + hum622: human(id: $var622) { + name + } + hum623: human(id: $var623) { + name + } + hum624: human(id: $var624) { + name + } + hum625: human(id: $var625) { + name + } + hum626: human(id: $var626) { + name + } + hum627: human(id: $var627) { + name + } + hum628: human(id: $var628) { + name + } + hum629: human(id: $var629) { + name + } + hum630: human(id: $var630) { + name + } + hum631: human(id: $var631) { + name + } + hum632: human(id: $var632) { + name + } + hum633: human(id: $var633) { + name + } + hum634: human(id: $var634) { + name + } + hum635: human(id: $var635) { + name + } + hum636: human(id: $var636) { + name + } + hum637: human(id: $var637) { + name + } + hum638: human(id: $var638) { + name + } + hum639: human(id: $var639) { + name + } + hum640: human(id: $var640) { + name + } + hum641: human(id: $var641) { + name + } + hum642: human(id: $var642) { + name + } + hum643: human(id: $var643) { + name + } + hum644: human(id: $var644) { + name + } + hum645: human(id: $var645) { + name + } + hum646: human(id: $var646) { + name + } + hum647: human(id: $var647) { + name + } + hum648: human(id: $var648) { + name + } + hum649: human(id: $var649) { + name + } + hum650: human(id: $var650) { + name + } + hum651: human(id: $var651) { + name + } + hum652: human(id: $var652) { + name + } + hum653: human(id: $var653) { + name + } + hum654: human(id: $var654) { + name + } + hum655: human(id: $var655) { + name + } + hum656: human(id: $var656) { + name + } + hum657: human(id: $var657) { + name + } + hum658: human(id: $var658) { + name + } + hum659: human(id: $var659) { + name + } + hum660: human(id: $var660) { + name + } + hum661: human(id: $var661) { + name + } + hum662: human(id: $var662) { + name + } + hum663: human(id: $var663) { + name + } + hum664: human(id: $var664) { + name + } + hum665: human(id: $var665) { + name + } + hum666: human(id: $var666) { + name + } + hum667: human(id: $var667) { + name + } + hum668: human(id: $var668) { + name + } + hum669: human(id: $var669) { + name + } + hum670: human(id: $var670) { + name + } + hum671: human(id: $var671) { + name + } + hum672: human(id: $var672) { + name + } + hum673: human(id: $var673) { + name + } + hum674: human(id: $var674) { + name + } + hum675: human(id: $var675) { + name + } + hum676: human(id: $var676) { + name + } + hum677: human(id: $var677) { + name + } + hum678: human(id: $var678) { + name + } + hum679: human(id: $var679) { + name + } + hum680: human(id: $var680) { + name + } + hum681: human(id: $var681) { + name + } + hum682: human(id: $var682) { + name + } + hum683: human(id: $var683) { + name + } + hum684: human(id: $var684) { + name + } + hum685: human(id: $var685) { + name + } + hum686: human(id: $var686) { + name + } + hum687: human(id: $var687) { + name + } + hum688: human(id: $var688) { + name + } + hum689: human(id: $var689) { + name + } + hum690: human(id: $var690) { + name + } + hum691: human(id: $var691) { + name + } + hum692: human(id: $var692) { + name + } + hum693: human(id: $var693) { + name + } + hum694: human(id: $var694) { + name + } + hum695: human(id: $var695) { + name + } + hum696: human(id: $var696) { + name + } + hum697: human(id: $var697) { + name + } + hum698: human(id: $var698) { + name + } + hum699: human(id: $var699) { + name + } + hum700: human(id: $var700) { + name + } + hum701: human(id: $var701) { + name + } + hum702: human(id: $var702) { + name + } + hum703: human(id: $var703) { + name + } + hum704: human(id: $var704) { + name + } + hum705: human(id: $var705) { + name + } + hum706: human(id: $var706) { + name + } + hum707: human(id: $var707) { + name + } + hum708: human(id: $var708) { + name + } + hum709: human(id: $var709) { + name + } + hum710: human(id: $var710) { + name + } + hum711: human(id: $var711) { + name + } + hum712: human(id: $var712) { + name + } + hum713: human(id: $var713) { + name + } + hum714: human(id: $var714) { + name + } + hum715: human(id: $var715) { + name + } + hum716: human(id: $var716) { + name + } + hum717: human(id: $var717) { + name + } + hum718: human(id: $var718) { + name + } + hum719: human(id: $var719) { + name + } + hum720: human(id: $var720) { + name + } + hum721: human(id: $var721) { + name + } + hum722: human(id: $var722) { + name + } + hum723: human(id: $var723) { + name + } + hum724: human(id: $var724) { + name + } + hum725: human(id: $var725) { + name + } + hum726: human(id: $var726) { + name + } + hum727: human(id: $var727) { + name + } + hum728: human(id: $var728) { + name + } + hum729: human(id: $var729) { + name + } + hum730: human(id: $var730) { + name + } + hum731: human(id: $var731) { + name + } + hum732: human(id: $var732) { + name + } + hum733: human(id: $var733) { + name + } + hum734: human(id: $var734) { + name + } + hum735: human(id: $var735) { + name + } + hum736: human(id: $var736) { + name + } + hum737: human(id: $var737) { + name + } + hum738: human(id: $var738) { + name + } + hum739: human(id: $var739) { + name + } + hum740: human(id: $var740) { + name + } + hum741: human(id: $var741) { + name + } + hum742: human(id: $var742) { + name + } + hum743: human(id: $var743) { + name + } + hum744: human(id: $var744) { + name + } + hum745: human(id: $var745) { + name + } + hum746: human(id: $var746) { + name + } + hum747: human(id: $var747) { + name + } + hum748: human(id: $var748) { + name + } + hum749: human(id: $var749) { + name + } + hum750: human(id: $var750) { + name + } + hum751: human(id: $var751) { + name + } + hum752: human(id: $var752) { + name + } + hum753: human(id: $var753) { + name + } + hum754: human(id: $var754) { + name + } + hum755: human(id: $var755) { + name + } + hum756: human(id: $var756) { + name + } + hum757: human(id: $var757) { + name + } + hum758: human(id: $var758) { + name + } + hum759: human(id: $var759) { + name + } + hum760: human(id: $var760) { + name + } + hum761: human(id: $var761) { + name + } + hum762: human(id: $var762) { + name + } + hum763: human(id: $var763) { + name + } + hum764: human(id: $var764) { + name + } + hum765: human(id: $var765) { + name + } + hum766: human(id: $var766) { + name + } + hum767: human(id: $var767) { + name + } + hum768: human(id: $var768) { + name + } + hum769: human(id: $var769) { + name + } + hum770: human(id: $var770) { + name + } + hum771: human(id: $var771) { + name + } + hum772: human(id: $var772) { + name + } + hum773: human(id: $var773) { + name + } + hum774: human(id: $var774) { + name + } + hum775: human(id: $var775) { + name + } + hum776: human(id: $var776) { + name + } + hum777: human(id: $var777) { + name + } + hum778: human(id: $var778) { + name + } + hum779: human(id: $var779) { + name + } + hum780: human(id: $var780) { + name + } + hum781: human(id: $var781) { + name + } + hum782: human(id: $var782) { + name + } + hum783: human(id: $var783) { + name + } + hum784: human(id: $var784) { + name + } + hum785: human(id: $var785) { + name + } + hum786: human(id: $var786) { + name + } + hum787: human(id: $var787) { + name + } + hum788: human(id: $var788) { + name + } + hum789: human(id: $var789) { + name + } + hum790: human(id: $var790) { + name + } + hum791: human(id: $var791) { + name + } + hum792: human(id: $var792) { + name + } + hum793: human(id: $var793) { + name + } + hum794: human(id: $var794) { + name + } + hum795: human(id: $var795) { + name + } + hum796: human(id: $var796) { + name + } + hum797: human(id: $var797) { + name + } + hum798: human(id: $var798) { + name + } + hum799: human(id: $var799) { + name + } + hum800: human(id: $var800) { + name + } + hum801: human(id: $var801) { + name + } + hum802: human(id: $var802) { + name + } + hum803: human(id: $var803) { + name + } + hum804: human(id: $var804) { + name + } + hum805: human(id: $var805) { + name + } + hum806: human(id: $var806) { + name + } + hum807: human(id: $var807) { + name + } + hum808: human(id: $var808) { + name + } + hum809: human(id: $var809) { + name + } + hum810: human(id: $var810) { + name + } + hum811: human(id: $var811) { + name + } + hum812: human(id: $var812) { + name + } + hum813: human(id: $var813) { + name + } + hum814: human(id: $var814) { + name + } + hum815: human(id: $var815) { + name + } + hum816: human(id: $var816) { + name + } + hum817: human(id: $var817) { + name + } + hum818: human(id: $var818) { + name + } + hum819: human(id: $var819) { + name + } + hum820: human(id: $var820) { + name + } + hum821: human(id: $var821) { + name + } + hum822: human(id: $var822) { + name + } + hum823: human(id: $var823) { + name + } + hum824: human(id: $var824) { + name + } + hum825: human(id: $var825) { + name + } + hum826: human(id: $var826) { + name + } + hum827: human(id: $var827) { + name + } + hum828: human(id: $var828) { + name + } + hum829: human(id: $var829) { + name + } + hum830: human(id: $var830) { + name + } + hum831: human(id: $var831) { + name + } + hum832: human(id: $var832) { + name + } + hum833: human(id: $var833) { + name + } + hum834: human(id: $var834) { + name + } + hum835: human(id: $var835) { + name + } + hum836: human(id: $var836) { + name + } + hum837: human(id: $var837) { + name + } + hum838: human(id: $var838) { + name + } + hum839: human(id: $var839) { + name + } + hum840: human(id: $var840) { + name + } + hum841: human(id: $var841) { + name + } + hum842: human(id: $var842) { + name + } + hum843: human(id: $var843) { + name + } + hum844: human(id: $var844) { + name + } + hum845: human(id: $var845) { + name + } + hum846: human(id: $var846) { + name + } + hum847: human(id: $var847) { + name + } + hum848: human(id: $var848) { + name + } + hum849: human(id: $var849) { + name + } + hum850: human(id: $var850) { + name + } + hum851: human(id: $var851) { + name + } + hum852: human(id: $var852) { + name + } + hum853: human(id: $var853) { + name + } + hum854: human(id: $var854) { + name + } + hum855: human(id: $var855) { + name + } + hum856: human(id: $var856) { + name + } + hum857: human(id: $var857) { + name + } + hum858: human(id: $var858) { + name + } + hum859: human(id: $var859) { + name + } + hum860: human(id: $var860) { + name + } + hum861: human(id: $var861) { + name + } + hum862: human(id: $var862) { + name + } + hum863: human(id: $var863) { + name + } + hum864: human(id: $var864) { + name + } + hum865: human(id: $var865) { + name + } + hum866: human(id: $var866) { + name + } + hum867: human(id: $var867) { + name + } + hum868: human(id: $var868) { + name + } + hum869: human(id: $var869) { + name + } + hum870: human(id: $var870) { + name + } + hum871: human(id: $var871) { + name + } + hum872: human(id: $var872) { + name + } + hum873: human(id: $var873) { + name + } + hum874: human(id: $var874) { + name + } + hum875: human(id: $var875) { + name + } + hum876: human(id: $var876) { + name + } + hum877: human(id: $var877) { + name + } + hum878: human(id: $var878) { + name + } + hum879: human(id: $var879) { + name + } + hum880: human(id: $var880) { + name + } + hum881: human(id: $var881) { + name + } + hum882: human(id: $var882) { + name + } + hum883: human(id: $var883) { + name + } + hum884: human(id: $var884) { + name + } + hum885: human(id: $var885) { + name + } + hum886: human(id: $var886) { + name + } + hum887: human(id: $var887) { + name + } + hum888: human(id: $var888) { + name + } + hum889: human(id: $var889) { + name + } + hum890: human(id: $var890) { + name + } + hum891: human(id: $var891) { + name + } + hum892: human(id: $var892) { + name + } + hum893: human(id: $var893) { + name + } + hum894: human(id: $var894) { + name + } + hum895: human(id: $var895) { + name + } + hum896: human(id: $var896) { + name + } + hum897: human(id: $var897) { + name + } + hum898: human(id: $var898) { + name + } + hum899: human(id: $var899) { + name + } + hum900: human(id: $var900) { + name + } + hum901: human(id: $var901) { + name + } + hum902: human(id: $var902) { + name + } + hum903: human(id: $var903) { + name + } + hum904: human(id: $var904) { + name + } + hum905: human(id: $var905) { + name + } + hum906: human(id: $var906) { + name + } + hum907: human(id: $var907) { + name + } + hum908: human(id: $var908) { + name + } + hum909: human(id: $var909) { + name + } + hum910: human(id: $var910) { + name + } + hum911: human(id: $var911) { + name + } + hum912: human(id: $var912) { + name + } + hum913: human(id: $var913) { + name + } + hum914: human(id: $var914) { + name + } + hum915: human(id: $var915) { + name + } + hum916: human(id: $var916) { + name + } + hum917: human(id: $var917) { + name + } + hum918: human(id: $var918) { + name + } + hum919: human(id: $var919) { + name + } + hum920: human(id: $var920) { + name + } + hum921: human(id: $var921) { + name + } + hum922: human(id: $var922) { + name + } + hum923: human(id: $var923) { + name + } + hum924: human(id: $var924) { + name + } + hum925: human(id: $var925) { + name + } + hum926: human(id: $var926) { + name + } + hum927: human(id: $var927) { + name + } + hum928: human(id: $var928) { + name + } + hum929: human(id: $var929) { + name + } + hum930: human(id: $var930) { + name + } + hum931: human(id: $var931) { + name + } + hum932: human(id: $var932) { + name + } + hum933: human(id: $var933) { + name + } + hum934: human(id: $var934) { + name + } + hum935: human(id: $var935) { + name + } + hum936: human(id: $var936) { + name + } + hum937: human(id: $var937) { + name + } + hum938: human(id: $var938) { + name + } + hum939: human(id: $var939) { + name + } + hum940: human(id: $var940) { + name + } + hum941: human(id: $var941) { + name + } + hum942: human(id: $var942) { + name + } + hum943: human(id: $var943) { + name + } + hum944: human(id: $var944) { + name + } + hum945: human(id: $var945) { + name + } + hum946: human(id: $var946) { + name + } + hum947: human(id: $var947) { + name + } + hum948: human(id: $var948) { + name + } + hum949: human(id: $var949) { + name + } + hum950: human(id: $var950) { + name + } + hum951: human(id: $var951) { + name + } + hum952: human(id: $var952) { + name + } + hum953: human(id: $var953) { + name + } + hum954: human(id: $var954) { + name + } + hum955: human(id: $var955) { + name + } + hum956: human(id: $var956) { + name + } + hum957: human(id: $var957) { + name + } + hum958: human(id: $var958) { + name + } + hum959: human(id: $var959) { + name + } + hum960: human(id: $var960) { + name + } + hum961: human(id: $var961) { + name + } + hum962: human(id: $var962) { + name + } + hum963: human(id: $var963) { + name + } + hum964: human(id: $var964) { + name + } + hum965: human(id: $var965) { + name + } + hum966: human(id: $var966) { + name + } + hum967: human(id: $var967) { + name + } + hum968: human(id: $var968) { + name + } + hum969: human(id: $var969) { + name + } + hum970: human(id: $var970) { + name + } + hum971: human(id: $var971) { + name + } + hum972: human(id: $var972) { + name + } + hum973: human(id: $var973) { + name + } + hum974: human(id: $var974) { + name + } + hum975: human(id: $var975) { + name + } + hum976: human(id: $var976) { + name + } + hum977: human(id: $var977) { + name + } + hum978: human(id: $var978) { + name + } + hum979: human(id: $var979) { + name + } + hum980: human(id: $var980) { + name + } + hum981: human(id: $var981) { + name + } + hum982: human(id: $var982) { + name + } + hum983: human(id: $var983) { + name + } + hum984: human(id: $var984) { + name + } + hum985: human(id: $var985) { + name + } + hum986: human(id: $var986) { + name + } + hum987: human(id: $var987) { + name + } + hum988: human(id: $var988) { + name + } + hum989: human(id: $var989) { + name + } + hum990: human(id: $var990) { + name + } + hum991: human(id: $var991) { + name + } + hum992: human(id: $var992) { + name + } + hum993: human(id: $var993) { + name + } + hum994: human(id: $var994) { + name + } + hum995: human(id: $var995) { + name + } + hum996: human(id: $var996) { + name + } + hum997: human(id: $var997) { + name + } + hum998: human(id: $var998) { + name + } + hum999: human(id: $var999) { + name + } + hum1000: human(id: $var1000) { + name + } +} diff --git a/crates/apollo-parser/src/lexer/cursor.rs b/crates/apollo-parser/src/lexer/cursor.rs index f103d4c39..3136dcd8b 100644 --- a/crates/apollo-parser/src/lexer/cursor.rs +++ b/crates/apollo-parser/src/lexer/cursor.rs @@ -1,63 +1,131 @@ -use std::str::Chars; +use std::str::CharIndices; use crate::Error; + /// Peekable iterator over a char sequence. +#[derive(Debug, Clone)] pub(crate) struct Cursor<'a> { - chars: Chars<'a>, + index: usize, + offset: usize, + prev: usize, + source: &'a str, + chars: CharIndices<'a>, + pending: Option, pub(crate) err: Option, } impl<'a> Cursor<'a> { pub(crate) fn new(input: &'a str) -> Cursor<'a> { Cursor { - chars: input.chars(), + index: 0, + offset: 0, + prev: 0, + pending: None, + source: input, + chars: input.char_indices(), err: None, } } } -pub(crate) const EOF_CHAR: char = '\0'; - impl<'a> Cursor<'a> { - /// Returns nth character relative to the current cursor position. - fn nth_char(&self, n: usize) -> char { - self.chars().nth(n).unwrap_or(EOF_CHAR) + pub(crate) fn index(&self) -> usize { + self.index + } + + fn eof(&self) -> bool { + self.offset == self.source.len() } - /// Peeks the next char in input without consuming. - pub(crate) fn first(&self) -> char { - self.nth_char(0) + pub(crate) fn pending(&self) -> bool { + self.pending.is_some() } - /// Peeks the second char in input without consuming. - pub(crate) fn second(&self) -> char { - self.nth_char(1) + pub(crate) fn pending_len(&self) -> usize { + self.offset - self.index + } + + /// Moves to the next character. + pub(crate) fn prev_str(&mut self) -> &'a str { + let slice = &self.source[self.index..self.offset]; + + self.index = self.offset; + self.pending = self.source[self.offset..].chars().next(); + + slice } - /// Checks if there are chars to consume. - pub(crate) fn is_eof(&self) -> bool { - self.chars.as_str().is_empty() + /// Moves to the next character. + pub(crate) fn current_str(&mut self) -> &'a str { + self.pending = None; + if self.eof() { + return &self.source[self.index..]; + } + let slice = &self.source[self.index..=self.offset]; + + self.index = self.offset; + self.offset = self.offset; + if let Some((pos, next)) = self.chars.next() { + self.index = pos; + self.offset = pos; + self.pending = Some(next); + } + + slice } /// Moves to the next character. pub(crate) fn bump(&mut self) -> Option { - let c = self.chars.next()?; + if self.pending.is_some() { + return self.pending.take(); + } + + if self.offset == self.source.len() { + return None; + } + + let (pos, c) = self.chars.next()?; + self.prev = self.offset; + self.offset = pos; Some(c) } + /// Moves to the next character. + pub(crate) fn eatc(&mut self, c: char) -> bool { + if self.pending.is_some() { + panic!("dont call eatc when a character is pending"); + } + + if let Some((pos, c_in)) = self.chars.next() { + self.prev = self.offset; + self.offset = pos; + + if c_in == c { + return true; + } + + self.pending = Some(c_in); + } + + false + } + /// Get current error object in the cursor. pub(crate) fn err(&mut self) -> Option { self.err.clone() } + pub(crate) fn drain(&mut self) -> &'a str{ + self.pending = None; + let start = self.index; + self.index = self.source.len() - 1; + + &self.source[start..=self.index] + } + /// Add error object to the cursor. pub(crate) fn add_err(&mut self, err: Error) { self.err = Some(err) } - - /// Returns a `Chars` iterator over the remaining characters. - fn chars(&self) -> Chars<'_> { - self.chars.clone() - } } diff --git a/crates/apollo-parser/src/lexer/mod.rs b/crates/apollo-parser/src/lexer/mod.rs index c0532c279..c7d1aadf7 100644 --- a/crates/apollo-parser/src/lexer/mod.rs +++ b/crates/apollo-parser/src/lexer/mod.rs @@ -28,49 +28,25 @@ pub use token_kind::TokenKind; /// /// let tokens = lexer.tokens(); /// ``` -pub struct Lexer { - tokens: Vec, +pub struct Lexer<'a> { + tokens: Vec>, errors: Vec, } -impl Lexer { +impl<'a> Lexer<'a> { /// Create a new instance of `Lexer`. - pub fn new(mut input: &str) -> Self { + pub fn new(input: &'a str) -> Self { let mut tokens = Vec::new(); let mut errors = Vec::new(); - let mut index = 0; - - while !input.is_empty() { - let old_input = input; - - if old_input.len() == input.len() { - let mut c = Cursor::new(input); - let r = c.advance(); - - match r { - Ok(mut token) => { - token.index = index; - index += token.data.len(); - - input = &input[token.data.len()..]; - tokens.push(token); - } - Err(mut err) => { - err.index = index; - index += err.data.len(); - - input = &input[err.data.len()..]; - errors.push(err); - } - } + let mut token_stream = LexerIterator::new(input); + while let Some(result) = token_stream.next() { + match result { + Ok(t) => tokens.push(t), + Err(e) => errors.push(e), } } - let mut eof = Token::new(TokenKind::Eof, String::from("EOF")); - eof.index = index; - tokens.push(eof); - Self { tokens, errors } } @@ -85,280 +61,420 @@ impl Lexer { } } -impl Cursor<'_> { - fn advance(&mut self) -> Result { - let first_char = self.bump().unwrap(); - - match first_char { - '"' => self.string_value(first_char), - '#' => self.comment(first_char), - '.' => self.spread_operator(first_char), - c if is_whitespace(c) => self.whitespace(c), - c if is_ident_char(c) => self.ident(c), - c @ '-' | c @ '+' => self.number(c), - c if is_digit_char(c) => self.number(c), - '!' => Ok(Token::new(TokenKind::Bang, first_char.into())), - '$' => Ok(Token::new(TokenKind::Dollar, first_char.into())), - '&' => Ok(Token::new(TokenKind::Amp, first_char.into())), - '(' => Ok(Token::new(TokenKind::LParen, first_char.into())), - ')' => Ok(Token::new(TokenKind::RParen, first_char.into())), - ':' => Ok(Token::new(TokenKind::Colon, first_char.into())), - ',' => Ok(Token::new(TokenKind::Comma, first_char.into())), - '=' => Ok(Token::new(TokenKind::Eq, first_char.into())), - '@' => Ok(Token::new(TokenKind::At, first_char.into())), - '[' => Ok(Token::new(TokenKind::LBracket, first_char.into())), - ']' => Ok(Token::new(TokenKind::RBracket, first_char.into())), - '{' => Ok(Token::new(TokenKind::LCurly, first_char.into())), - '|' => Ok(Token::new(TokenKind::Pipe, first_char.into())), - '}' => Ok(Token::new(TokenKind::RCurly, first_char.into())), - c => Err(Error::new("Unexpected character", c.to_string())), +#[derive(Clone, Debug)] +pub struct LexerIterator<'a> { + cursor: Cursor<'a>, + finished: bool, +} + +impl<'a> LexerIterator<'a> { + pub fn new(input: &'a str) -> Self { + Self { + cursor: Cursor::new(input), + finished: false, } } +} - fn string_value(&mut self, first_char: char) -> Result { - // TODO @lrlna: consider using a 'terminated' bool to store whether a string - // character or block character are terminated (rust's lexer does this). - let mut buf = String::new(); - buf.push(first_char); // the first " we already matched on - - let c = match self.bump() { - None => { - return Err(Error::new( - "unexpected end of data while lexing string value", - "\"".to_string(), - )); - } - Some(c) => c, - }; - - match c { - '"' => self.block_string_value(buf, c), - t => { - buf.push(t); - let mut was_backslash = t == '\\'; - - while !self.is_eof() { - let c = self.bump().unwrap(); - - if was_backslash && !is_escaped_char(c) && c != 'u' { - self.add_err(Error::new("unexpected escaped character", c.to_string())); - } +impl<'a> Iterator for LexerIterator<'a> { + type Item = Result, Error>; - buf.push(c); - if c == '"' { - if !was_backslash { - break; - } - } else if is_line_terminator(c) { - self.add_err(Error::new("unexpected line terminator", c.to_string())); - } - was_backslash = c == '\\'; - } + fn next<'b>(&'b mut self) -> Option { + if self.finished { + return None; + } - if !buf.ends_with('"') { - // If it's an unclosed string then take all remaining tokens into this string value - while !self.is_eof() { - buf.push(self.bump().unwrap()); - } - self.add_err(Error::new("unterminated string value", buf.clone())); - } + match self.cursor.advance() { + Ok(token) => { + if matches!(token.kind(), TokenKind::Eof) { + self.finished = true; - if let Some(mut err) = self.err() { - err.data = buf; - return Err(err); + return Some(Ok(token)); } - Ok(Token::new(TokenKind::StringValue, buf)) + Some(Ok(token)) } - } - } - - fn block_string_value(&mut self, mut buf: String, char: char) -> Result { - buf.push(char); // the second " we already matched on - - let c = match self.bump() { - None => { - return Ok(Token::new(TokenKind::StringValue, buf)); - } - Some(c) => c, - }; - - if let first_char @ '"' = c { - buf.push(first_char); - - while !self.is_eof() { - let c = self.bump().unwrap(); - if c == '"' { - buf.push(c); - if ('"', '"') == (self.first(), self.second()) { - buf.push(self.first()); - buf.push(self.second()); - self.bump(); - self.bump(); - break; - } - } else if is_source_char(c) { - buf.push(c); - } else { - break; - } + Err(err) => { + Some(Err(err)) } } - - Ok(Token::new(TokenKind::StringValue, buf)) } +} - fn comment(&mut self, first_char: char) -> Result { - let mut buf = String::new(); - buf.push(first_char); - - while !self.is_eof() { - let first = self.bump().unwrap(); - if !is_line_terminator(first) { - buf.push(first); - } else { - break; - } +impl<'a> Cursor<'a> { + fn advance(&mut self) -> Result, Error> { + #[derive(Debug)] + enum State { + Start, + Done, + Ident, + StringLiteral, + StringLiteralStart, + BlockStringLiteral, + StringLiteralBackslash, + IntLiteral, + FloatLiteral, + ExponentLiteral, + Whitespace, + Comment, + SpreadOperator, + PlusMinus, } - Ok(Token::new(TokenKind::Comment, buf)) - } - - fn spread_operator(&mut self, first_char: char) -> Result { - let mut buf = String::new(); - buf.push(first_char); + let mut state = State::Start; + let mut token = Token { + kind: TokenKind::Eof, + data: "EOF", + index: self.index(), + }; - match (self.first(), self.second()) { - ('.', '.') => { - buf.push('.'); - buf.push('.'); - self.bump(); - self.bump(); - } - (a, b) => self.add_err(Error::new( - "Unterminated spread operator", - format!(".{}{}", a, b), - )), - } + while let Some(c) = self.bump() { + match state { + State::Start => { + match c { + '"' => { + token.kind = TokenKind::StringValue; + state = State::StringLiteralStart; + } + '#' => { + token.kind = TokenKind::Comment; + state = State::Comment; + } + '.' => { + token.kind = TokenKind::Spread; + state = State::SpreadOperator; + } + c if is_whitespace(c) => { + token.kind = TokenKind::Whitespace; + state = State::Whitespace; + } + c if is_ident_char(c) => { + token.kind = TokenKind::Name; + state = State::Ident; + } + '+' | '-' => { + token.kind = TokenKind::Int; + state = State::PlusMinus; + } + c if is_digit_char(c) => { + token.kind = TokenKind::Int; + state = State::IntLiteral; + } + '!' => { + token.kind = TokenKind::Bang; + token.data = self.current_str(); + return Ok(token); + } + '$' => { + token.kind = TokenKind::Dollar; + token.data = self.current_str(); + return Ok(token); + } + '&' => { + token.kind = TokenKind::Amp; + token.data = self.current_str(); + return Ok(token); + } + '(' => { + token.kind = TokenKind::LParen; + token.data = self.current_str(); + return Ok(token); + } + ')' => { + token.kind = TokenKind::RParen; + token.data = self.current_str(); + return Ok(token); + } + ':' => { + token.kind = TokenKind::Colon; + token.data = self.current_str(); + return Ok(token); + } + ',' => { + token.kind = TokenKind::Comma; + token.data = self.current_str(); + return Ok(token); + } + '=' => { + token.kind = TokenKind::Eq; + token.data = self.current_str(); + return Ok(token); + } + '@' => { + token.kind = TokenKind::At; + token.data = self.current_str(); + return Ok(token); + } + '[' => { + token.kind = TokenKind::LBracket; + token.data = self.current_str(); + return Ok(token); + } + ']' => { + token.kind = TokenKind::RBracket; + token.data = self.current_str(); + return Ok(token); + } + '{' => { + token.kind = TokenKind::LCurly; + token.data = self.current_str(); + return Ok(token); + } + '|' => { + token.kind = TokenKind::Pipe; + token.data = self.current_str(); + return Ok(token); + } + '}' => { + token.kind = TokenKind::RCurly; + token.data = self.current_str(); + return Ok(token); + } + c => { + return Err(Error::new( + format!("Unexpected character \"{}\"", c), + c.to_string(), + )) + } + }; + } + State::Ident => match c { + curr if is_ident_char(curr) || is_digit_char(curr) => {} + _ => { + token.data = self.prev_str(); - if let Some(mut err) = self.err() { - err.data = buf; - return Err(err); - } + state = State::Done; + break; + } + }, + State::Whitespace => match c { + curr if is_whitespace(curr) => {} + _ => { + token.data = self.prev_str(); - Ok(Token::new(TokenKind::Spread, buf)) - } + state = State::Done; + break; + } + }, + State::BlockStringLiteral => match c { + '"' => { + if self.eatc('"') { + if self.eatc('"') { + token.data = self.current_str(); + + state = State::Done; + break; + } + } + } + curr if is_source_char(curr) => {} + _ => { + state = State::Done; + break; + }, + }, + State::StringLiteralStart => match c { + '"' => { + if self.eatc('"') { + state = State::BlockStringLiteral; + + continue; + } - fn whitespace(&mut self, first_char: char) -> Result { - let mut buf = String::new(); - buf.push(first_char); + if self.pending() { + token.data = self.prev_str(); + } else { + token.data = self.current_str(); + } - while !self.is_eof() { - let first = self.bump().unwrap(); - if is_whitespace(first) { - buf.push(first); - } else { - break; - } - } + state = State::Done; + break; + } + '\\' => { + state = State::StringLiteralBackslash; + } + _ => { + state = State::StringLiteral; - Ok(Token::new(TokenKind::Whitespace, buf)) - } + continue; + } + }, + State::StringLiteral => match c { + '"' => { + token.data = self.current_str(); - fn ident(&mut self, first_char: char) -> Result { - let mut buf = String::new(); - buf.push(first_char); - - while !self.is_eof() { - let first = self.first(); - if is_ident_char(first) || is_digit_char(first) { - buf.push(first); - self.bump(); - } else { - break; - } - } + state = State::Done; + break; + } + curr if is_line_terminator(curr) => { + self.add_err(Error::new("unexpected line terminator", "".to_string())); + } + '\\' => { + state = State::StringLiteralBackslash; + } + curr if is_source_char(curr) => {} + _ => { + token.data = self.current_str(); - Ok(Token::new(TokenKind::Name, buf)) - } + state = State::Done; + break; + } + }, + State::StringLiteralBackslash => match c { + curr if is_escaped_char(curr) => { + state = State::StringLiteral; + } + 'u' => { + state = State::StringLiteral; + } + _ => { + self.add_err(Error::new("unexpected escaped character", c.to_string())); - fn number(&mut self, first_digit: char) -> Result { - let mut buf = String::new(); - buf.push(first_digit); - - let mut has_exponent = false; - let mut has_fractional = false; - let mut has_digit = is_digit_char(first_digit); - - while !self.is_eof() { - let first = self.first(); - match first { - 'e' | 'E' => { - buf.push(first); - self.bump(); - if !has_digit { - self.add_err(Error::new( - format!("Unexpected character `{}` in exponent", first), - first.to_string(), - )); + state = State::StringLiteral; } - if has_exponent { - self.add_err(Error::new( - format!("Unexpected character `{}`", first), - first.to_string(), - )); + }, + State::IntLiteral => match c { + curr if is_digit_char(curr) => {} + '.' => { + token.kind = TokenKind::Float; + state = State::FloatLiteral; } - has_exponent = true; - if matches!(self.first(), '+' | '-') { - buf.push(self.first()); - self.bump(); + 'e' | 'E' => { + token.kind = TokenKind::Float; + state = State::ExponentLiteral; } - } - '.' => { - buf.push(first); - self.bump(); + _ => { + token.data = self.prev_str(); - if !has_digit { + state = State::Done; + break; + } + }, + State::FloatLiteral => match c { + curr if is_digit_char(curr) => {} + '.' => { self.add_err(Error::new( - format!("Unexpected character `{}` before a digit", first), - first.to_string(), - )); + format!("Unexpected character `{}`", c), + c.to_string(), + )); + + continue; + } + 'e' | 'E' => { + state = State::ExponentLiteral; } + _ => { + token.data = self.prev_str(); - if has_fractional { + state = State::Done; + break; + } + }, + State::ExponentLiteral => match c { + curr if is_digit_char(curr) => { + state = State::FloatLiteral; + } + '+' | '-' => { + state = State::FloatLiteral; + } + _ => { + let err = self.current_str(); + return Err(Error::new( + format!("Unexpected character `{}`", err), + err.to_string(), + )); + } + }, + State::SpreadOperator => match c { + '.' => { + if self.pending_len() == 2 { + token.data = self.current_str(); + return Ok(token); + } + } + _ => { + let curr = self.current_str(); self.add_err(Error::new( - format!("Unexpected character `{}`", first), - first.to_string(), - )); + "Unterminated spread operator", + format!("{}", curr), + )) + } + }, + State::PlusMinus => match c { + curr if is_digit_char(curr) => { + state = State::IntLiteral; + } + _ => { + let curr = self.current_str(); + return Err(Error::new( + format!("Unexpected character `{}`", curr), + curr.to_string(), + )); } + }, + State::Comment => match c { + curr if is_line_terminator(curr) => { + token.data = self.prev_str(); - if has_exponent { - self.add_err(Error::new( - format!("Unexpected character `{}`", first), - first.to_string(), - )); + state = State::Done; + break; } + _ => {} + }, + State::Done => unreachable!("must finalize loop when State::Done"), + } + } - has_fractional = true; - } - first if is_digit_char(first) => { - buf.push(first); - self.bump(); - has_digit = true; + match state { + State::Done => { + if let Some(mut err) = self.err() { + err.data = token.data.to_string(); + err.index = token.index; + self.err = None; + + return Err(err); } - _ => break, + + Ok(token) } - } + State::Start => { + token.index += 1; + return Ok(token); + } + State::StringLiteralStart => { + let curr = self.current_str(); - if let Some(mut err) = self.err() { - err.data = buf; - return Err(err); - } + return Err(Error::new( + "unexpected end of data while lexing string value", + curr.to_string(), + )); + } + State::StringLiteral => { + let curr = self.drain(); + + return Err(Error::with_loc( + "unterminated string value", + curr.to_string(), + token.index, + )); + } + State::SpreadOperator => { + let curr = self.current_str(); + return Err(Error::new( + "Unterminated spread operator", + format!("{}", curr), + )); + } + _ => { + if let Some(mut err) = self.err() { + err.data = self.current_str().to_string(); + return Err(err); + } - if has_exponent || has_fractional { - Ok(Token::new(TokenKind::Float, buf)) - } else { - Ok(Token::new(TokenKind::Int, buf)) + token.data = self.current_str(); + + return Ok(token); + } } } } diff --git a/crates/apollo-parser/src/lexer/token.rs b/crates/apollo-parser/src/lexer/token.rs index 30046d8f5..833cd44e1 100644 --- a/crates/apollo-parser/src/lexer/token.rs +++ b/crates/apollo-parser/src/lexer/token.rs @@ -4,14 +4,14 @@ use crate::TokenKind; /// A token generated by the lexer. #[derive(Clone)] -pub struct Token { +pub struct Token<'a> { pub(crate) kind: TokenKind, - pub(crate) data: String, + pub(crate) data: &'a str, pub(crate) index: usize, } -impl Token { - pub(crate) fn new(kind: TokenKind, data: String) -> Self { +impl<'a> Token<'a> { + pub(crate) fn new(kind: TokenKind, data: &'a str) -> Self { Self { kind, data, @@ -26,7 +26,7 @@ impl Token { /// Get a reference to the token's data. pub fn data(&self) -> &str { - self.data.as_str() + self.data } /// Get a reference to the token's loc. @@ -35,7 +35,7 @@ impl Token { } } -impl fmt::Debug for Token { +impl<'a> fmt::Debug for Token<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let start = self.index; let end = self.index + self.data.len(); diff --git a/crates/apollo-parser/src/parser/grammar/ty.rs b/crates/apollo-parser/src/parser/grammar/ty.rs index 7e4319c02..d2ecb1a39 100644 --- a/crates/apollo-parser/src/parser/grammar/ty.rs +++ b/crates/apollo-parser/src/parser/grammar/ty.rs @@ -24,24 +24,24 @@ pub(crate) fn ty(p: &mut Parser) { } #[derive(Debug)] -enum TokenTy { +enum TokenTy<'a> { List { - nullable: Option, - open_token: Token, - close_token: Option, - inner: Box, - comma: Option, - trailing_ws: Option, + nullable: Option>, + open_token: Token<'a>, + close_token: Option>, + inner: Box>, + comma: Option>, + trailing_ws: Option>, }, Named { - nullable: Option, - token: Token, - comma: Option, - trailing_ws: Option, + nullable: Option>, + token: Token<'a>, + comma: Option>, + trailing_ws: Option>, }, } -fn parse(p: &mut Parser) -> TokenTy { +fn parse<'a>(p: &mut Parser<'a>) -> TokenTy<'a> { let token = p.pop(); let mut types = match token.kind() { T!['['] => { diff --git a/crates/apollo-parser/src/parser/mod.rs b/crates/apollo-parser/src/parser/mod.rs index 16cf7dd9c..afe4e3554 100644 --- a/crates/apollo-parser/src/parser/mod.rs +++ b/crates/apollo-parser/src/parser/mod.rs @@ -7,7 +7,7 @@ pub(crate) mod grammar; use std::{cell::RefCell, fmt, rc::Rc}; -use crate::{lexer::Lexer, Error, Token, TokenKind}; +use crate::{lexer::LexerIterator, Error, Token, TokenKind}; pub use generated::syntax_kind::SyntaxKind; pub use language::{SyntaxElement, SyntaxNode, SyntaxNodeChildren, SyntaxNodePtr, SyntaxToken}; @@ -70,9 +70,9 @@ pub(crate) use token_text::TokenText; /// let document = ast.document(); /// ``` #[derive(Debug)] -pub struct Parser { - /// Input tokens, including whitespace, in *reverse* order. - tokens: Vec, +pub struct Parser<'a> { + /// An iterator that lazily initializes the input as tokens. + lexer: LexerIterator<'a>, /// The in-progress tree. builder: Rc>, /// The list of syntax errors we've accumulated so far. @@ -81,39 +81,25 @@ pub struct Parser { recursion_limit: LimitTracker, /// Accept parsing errors? accept_errors: bool, + current_token: Option>, } -impl Parser { +impl<'a> Parser<'a> { /// Create a new instance of a parser given an input string. - pub fn new(input: &str) -> Self { - let lexer = Lexer::new(input); - - let mut tokens = Vec::new(); - let mut errors = Vec::new(); - - for s in lexer.tokens().iter().cloned() { - tokens.push(s); - } - - for e in lexer.errors().cloned() { - errors.push(e); - } - - tokens.reverse(); - errors.reverse(); - + pub fn new(input: &'a str) -> Self { Self { - tokens, + lexer: LexerIterator::new(input), builder: Rc::new(RefCell::new(SyntaxTreeBuilder::new())), - errors, + errors: Default::default(), recursion_limit: Default::default(), accept_errors: true, + current_token: None, } } /// Create a new resource limited instance of a parser given an input string /// and a recursion limit. - pub fn with_recursion_limit(input: &str, recursion_limit: usize) -> Self { + pub fn with_recursion_limit(input: &'a str, recursion_limit: usize) -> Self { let mut parser = Parser::new(input); parser.recursion_limit = LimitTracker::new(recursion_limit); parser @@ -171,10 +157,7 @@ impl Parser { /// Consume a token from the lexer and add it to the AST. fn eat(&mut self, kind: SyntaxKind) { - let token = self - .tokens - .pop() - .expect("Could not eat a token from the AST"); + let token = self.pop(); self.builder.borrow_mut().token(kind, token.data()); } @@ -212,8 +195,12 @@ impl Parser { /// Consume the next token if it is `kind` or emit an error /// otherwise. pub(crate) fn expect(&mut self, token: TokenKind, kind: SyntaxKind) { - let current = self.current().clone(); - let data = current.data().to_string(); + let (data, index) = { + let current = self.current().clone(); + + (current.data().to_string(), current.index()) + + }; if self.at(token) { self.bump(kind); @@ -223,7 +210,7 @@ impl Parser { let err = Error::with_loc( format!("expected {:?}, got {}", kind, data), data, - current.index(), + index, ); self.push_err(err); @@ -243,11 +230,29 @@ impl Parser { } } + /// Gets the next token from the lexer. + fn next_token(&mut self) -> Option> { + for res in &mut self.lexer { + match res { + Err(e) => { + self.errors.push(e); + } + Ok(token) => { + return Some(token); + } + } + } + + None + } + /// Consume a token from the lexer. - pub(crate) fn pop(&mut self) -> Token { - self.tokens - .pop() - .expect("Could not pop a token from the AST") + pub(crate) fn pop(&mut self) -> Token<'a> { + if let Some(token) = self.current_token.take() { + return token; + } + + self.next_token().expect("could not pop a token from the lexer") } /// Insert a token into the AST. @@ -270,47 +275,47 @@ impl Parser { } /// Peek the next Token and return its TokenKind. - pub(crate) fn peek(&self) -> Option { - self.tokens.last().map(|token| token.kind()) + pub(crate) fn peek(&mut self) -> Option { + self.peek_token().map(|token| token.kind()) } /// Peek the next Token and return it. - pub(crate) fn peek_token(&self) -> Option<&Token> { - self.tokens.last() + pub(crate) fn peek_token(&mut self) -> Option<&Token> { + if self.current_token.is_none() { + self.current_token = self.next_token(); + } + self.current_token.as_ref() } /// Peek Token `n` and return it. - pub(crate) fn peek_token_n(&self, n: usize) -> Option<&Token> { - self.tokens - .iter() - .rev() - .filter(|token| !matches!(token.kind(), TokenKind::Whitespace | TokenKind::Comment)) - .nth(n - 1) + pub(crate) fn peek_token_n(&self, n: usize) -> Option { + self.peek_n_inner(n) } /// Peek Token `n` and return its TokenKind. pub(crate) fn peek_n(&self, n: usize) -> Option { - self.tokens - .iter() - .rev() - .filter(|token| !matches!(token.kind(), TokenKind::Whitespace | TokenKind::Comment)) - .nth(n - 1) - .map(|token| token.kind()) + self.peek_n_inner(n).map(|token| token.kind()) } /// Peek next Token's `data` property. - pub(crate) fn peek_data(&self) -> Option { - self.tokens.last().map(|token| token.data().to_string()) + pub(crate) fn peek_data(&mut self) -> Option { + self.peek_token().map(|token| token.data().to_string()) } /// Peek `n` Token's `data` property. pub(crate) fn peek_data_n(&self, n: usize) -> Option { - self.tokens + self.peek_n_inner(n).map(|token| token.data().to_string()) + } + + fn peek_n_inner(&self, n: usize) -> Option { + self.current_token .iter() - .rev() + .cloned() + .map(Result::Ok) + .chain(self.lexer.clone()) + .filter_map(Result::ok) .filter(|token| !matches!(token.kind(), TokenKind::Whitespace | TokenKind::Comment)) .nth(n - 1) - .map(|token| token.data().to_string()) } } diff --git a/crates/apollo-parser/test_data/lexer/err/0002_unterminated_spread_operator_with_2.txt b/crates/apollo-parser/test_data/lexer/err/0002_unterminated_spread_operator_with_2.txt index f5a414928..911396e5d 100644 --- a/crates/apollo-parser/test_data/lexer/err/0002_unterminated_spread_operator_with_2.txt +++ b/crates/apollo-parser/test_data/lexer/err/0002_unterminated_spread_operator_with_2.txt @@ -1,3 +1,2 @@ EOF@2:2 -ERROR@0:1 "Unterminated spread operator" . -ERROR@1:2 "Unterminated spread operator" . +ERROR@0:2 "Unterminated spread operator" .. diff --git a/crates/apollo-parser/test_data/lexer/ok/0013_comment.graphql b/crates/apollo-parser/test_data/lexer/ok/0013_comment.graphql new file mode 100644 index 000000000..f31257fa9 --- /dev/null +++ b/crates/apollo-parser/test_data/lexer/ok/0013_comment.graphql @@ -0,0 +1,5 @@ +# A single line comment +query { + # A field comment + field +} diff --git a/crates/apollo-parser/test_data/lexer/ok/0013_comment.txt b/crates/apollo-parser/test_data/lexer/ok/0013_comment.txt new file mode 100644 index 000000000..9970a502c --- /dev/null +++ b/crates/apollo-parser/test_data/lexer/ok/0013_comment.txt @@ -0,0 +1,13 @@ +COMMENT@0:23 "# A single line comment" +WHITESPACE@23:24 "\n" +NAME@24:29 "query" +WHITESPACE@29:30 " " +L_CURLY@30:31 "{" +WHITESPACE@31:34 "\n " +COMMENT@34:51 "# A field comment" +WHITESPACE@51:54 "\n " +NAME@54:59 "field" +WHITESPACE@59:60 "\n" +R_CURLY@60:61 "}" +WHITESPACE@61:62 "\n" +EOF@62:62 diff --git a/crates/apollo-parser/test_data/parser/err/0034_unterminated_string_value_in_list.txt b/crates/apollo-parser/test_data/parser/err/0034_unterminated_string_value_in_list.txt index 812349551..6564f0c66 100644 --- a/crates/apollo-parser/test_data/parser/err/0034_unterminated_string_value_in_list.txt +++ b/crates/apollo-parser/test_data/parser/err/0034_unterminated_string_value_in_list.txt @@ -34,6 +34,10 @@ - ENUM_VALUE@96..98 - NAME@96..98 - IDENT@96..98 "id" +- ERROR@96:138 "unexpected line terminator" "@external]) + + +type Vehicle @key(fields: " - ERROR@140:237 "unterminated string value" ") { id: ID!, type: String, @@ -42,9 +46,5 @@ launchDate: String } -- ERROR@96:138 "unexpected line terminator" "@external]) - - -type Vehicle @key(fields: " - ERROR@237:237 "expected R_PAREN, got EOF" EOF recursion limit: 4096, high: 0 \ No newline at end of file diff --git a/crates/apollo-parser/test_data/parser/err/0035_unterminated_string_value_in_object_value.txt b/crates/apollo-parser/test_data/parser/err/0035_unterminated_string_value_in_object_value.txt index 1422631fe..3770bcf0b 100644 --- a/crates/apollo-parser/test_data/parser/err/0035_unterminated_string_value_in_object_value.txt +++ b/crates/apollo-parser/test_data/parser/err/0035_unterminated_string_value_in_object_value.txt @@ -46,12 +46,12 @@ - ENUM_VALUE@68..70 - NAME@68..70 - IDENT@68..70 "en" -- ERROR@108:116 "unterminated string value" ") - } -} - ERROR@68:106 "unexpected line terminator" "my store }] }) { name(locale: " +- ERROR@108:116 "unterminated string value" ") + } +} - ERROR@116:116 "expected }" EOF - ERROR@116:116 "expected }" EOF - ERROR@116:116 "expected R_PAREN, got EOF" EOF