684 using syntax_t =
typename gen_t::syntax_t;
685 using syntaxes_t =
typename gen_t::syntaxes_t;
686 using error_t =
typename gen_t::error_t;
687 using capture_t =
typename gen_t::capture_t;
700 capture_t TrailingCapture;
701 explicit operator bool()
const {
702 return bool(TrailingStart);
704 void MoveFrom(trailing& Source) {
706 TrailingStart = Source.TrailingStart;
707 TrailingCapture = Source.TrailingCapture;
708 Source.TrailingStart =
nothing{};
713 struct block_t:
public block<syntaxes_t,capture_t> {
714 using block<syntaxes_t,capture_t>::block;
715 trailing BlockTrailing;
731 capture_t ExprLeading;
734 bool MarkupFinished, ExprStop;
735 struct expr* OuterMarkup;
737 expr* QualIdentTarget;
741 MarkupFinished(
false), ExprStop(
false), OuterMarkup(
nullptr),
759 Cursor.Token=ParseToken(Cursor.Pos,Cursor.TokenSize);
760 if(
IsAlpha(Cursor.Token->Symbol[0])) {
767 auto IsIdentifier = Cursor.Token==
token(u8
":=");
782 return (this->*OnError)(
Value);
789 return (this->*OnError)(
Close);
791 return Cursor=Start, S80(
Open);
795 snippet SnipFinished(
const cursor& Start,
const expr&
End) {
796 return Snip(Start,*
End.Finished);
798 snippet SnipFinished(
const cursor& Start,
const block_t&
End) {
799 return Snip(Start,*
End.BlockTrailing.TrailingStart);
805 Trailing.TrailingStart=Cursor;
812 Target.Trailing.MoveFrom(Source);
823 syntax_t ApplyTrailing(expr& Target,
bool FinishingNow=
false) {
826 Target.ExprSyntax = Gen.Trailing(*Target,Target.Trailing.TrailingCapture);
827 Target.Trailing = trailing{};
832 Gen.CaptureAppend(
Block0.PunctuationTrailing,
Block0.BlockTrailing.TrailingCapture);
834 Gen.CaptureAppend(
Block0.ElementsTrailing,
Block0.BlockTrailing.TrailingCapture);
836 Block0.BlockTrailing = trailing{};
840 auto S01() {
return Gen.Err(Snip(),
"S01",
"Source must be ASCII or Unicode UTF-8 format");}
841 auto S02() {
return Gen.Err(Snip(),
"S02",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" in block comment");}
842 auto S03() {
return Gen.Err(Snip(),
"S03",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" in line comment");}
843 auto S04() {
return Gen.Err(Snip(),
"S04",
"Block comment beginning at \"<#\" never ends");}
844 auto S05() {
return Gen.Err(Snip(),
"S05",
"Ending \"#>\" is outside of block comment");}
845 auto S06() {
return Gen.Err(Snip(),
"S06",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" in indented comment");}
848 auto S15() {
return Gen.Err(Snip(),
"S15",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" following number.");}
849 auto S16() {
return Gen.Err(Snip(),
"S15",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" following character.");}
850 auto S18() {
return Gen.Err(Snip(),
"S18",
"Character code unit octet must be 1-2 digits in the range 0o0 to 0oFF");}
851 auto S19() {
return Gen.Err(Snip(),
"S19",
"Unicode code point must be 1-6 digits in the range 0u0 to 0u10FFFF");}
854 auto S20(
text What) {
return Gen.Err(Snip(),
"S20",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" or missing identifier following \"",What,
"\"");}
855 auto S23(
text What) {
return Gen.Err(Snip(),
"S23",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" or missing \"",What,
"\" in qualifier");}
856 auto S24(
text What) {
return Gen.Err(Snip(),
"S24",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" or missing \"",What,
"\" in quoted identifier");}
857 auto S25(
text What) {
return Gen.Err(Snip(),
"S25",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" or missing \"",What,
"\" in path literal");}
858 auto S26(
text What) {
return Gen.Err(Snip(),
"S26",
"Missing label in path following \"",What,
"\"");}
861 auto S30() {
return Gen.Err(Snip(),
"S30",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" in character literal");}
862 auto S31(
text) {
return Gen.Err(Snip(),
"S31",
"Missing \"'\" in character literal");}
863 auto S32(
text) {
return Gen.Err(Snip(),
"S32",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" or missing end quote in string literal");}
864 auto S34() {
return Gen.Err(Snip(),
"S34",
"Bad character escape \"\\\" followed by ",CursorQuote(),CursorText(),CursorQuote());}
867 auto S40() {
return Gen.Err(Snip(),
"S40",
"Missing markup tag preceding ",CursorQuote(),CursorText(),CursorQuote());}
868 auto S41() {
return Gen.Err(Snip(),
"S41",
"Bad markup expression preceding ",CursorQuote(),CursorText(),CursorQuote());}
869 auto S42() {
return Gen.Err(Snip(),
"S42",
"Unexpected markup end tag outside of markup");}
870 auto S43(
text Tag,
text Id) {
return Gen.Err(Snip(),
"S43",
"Markup started with \"<",
Tag,
">\" tag but ended in mismatched \"</",
Id,
">\" tag");}
871 auto S44(
text What) {
return Gen.Err(Snip(),
"S44",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" or missing \"",What,
"\" in markup end tag");}
872 auto S46() {
return Gen.Err(Snip(),
"S46",
"Expected indented markup following \":>\" but got ",CursorQuote(),CursorText(),CursorQuote());}
875 auto S51(
text What) {
return Gen.Err(Snip(),
"S51",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" or missing \"",What,
"\" in markup");}
876 auto S52(
text) {
return Gen.Err(Snip(),
"S52",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" or missing markup end tag");}
877 auto S54() {
return Gen.Err(Snip(),
"S54",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" in indented markup");}
878 auto S57() {
return Gen.Err(Snip(),
"S57",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" or missing ending \";\" or newline following \"&\" markup escape expression");}
879 auto S58() {
return Gen.Err(Snip(),
"S58",
"Markup list separator \"~\" is only allowed in markup beginning with \"~\"; elsewhere escape it using \"\\~\"");}
882 auto S60(
text What,
text Op) {
return Gen.Err(Snip(),
"S60",
"Precedence doesn't allow \"",Op,
"\" following \"",What,
"\"");}
883 auto S61(
text Op) {
return Gen.Err(Snip(),
"S61",
"Precedence doesn't allow \"",Op,
"\" here");}
884 auto S62() {
return Gen.Err(Snip(),
"S62",
"Verse uses 'and', 'or', 'not' instead of '&&', '||', '!'.");};
885 auto S64(
text,
text Op) {
return Gen.Err(Snip(),
"S64",
"Precedence doesn't allow \"",Op,
"\" in markup tag expression");}
886 auto S65() {
return Gen.Err(Snip(),
"S65",
"Use a=b for comparison, not a==b");}
887 auto S66(
text Op) {
return Gen.Err(Snip(),
"S66",
"Use 'set' before \"",Op,
"\" to update variables");}
888 auto S67() {
return Gen.Err(Snip(),
"S67",
"Prefix attribute must be followed by identifier declaration");}
889 auto S68() {
return Gen.Err(Snip(),
"S68",
"Use # for line comment, not //");}
892 auto S70(
text) {
return Gen.Err(Snip(),
"S70",
"Expected expression, got ",CursorQuote(),CursorText(),CursorQuote(),
" at top level of program");}
893 auto S71(
text What) {
return Gen.Err(Snip(),
"S71",
"Expected expression, got ",CursorQuote(),CursorText(),CursorQuote(),
" following \"",What,
"\"");}
894 auto S74(
text) {
return Gen.Err(Snip(),
"S74",
"Expected markup tag expression, got ",CursorQuote(),CursorText(),CursorQuote());}
895 auto S76(
text What) {
return Gen.Err(Snip(),
"S76",
"Expected block, got ",CursorQuote(),CursorText(),CursorQuote(),
" following \"",What,
"\"");}
896 auto S77() {
return Gen.Err(Snip(),
"S77",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
" following expression");}
897 auto S78() {
return Gen.Err(Snip(),
"S78",
"Expected <specifier> following \"with\"");}
898 auto S79() {
return Gen.Err(Snip(),
"S79",
"Unexpected ",CursorQuote(),CursorText(),CursorQuote(),
"or missing \">\" following specifier");}
901 auto S80(
text What) {
return Gen.Err(Snip(),
"S80",
"Block starting in \"",What,
"\" never ends");}
902 auto S81(
text What) {
return Gen.Err(Snip(),
"S81",
"Expected expression or \"",What,
"\", got ",CursorQuote(),CursorText(),CursorQuote(),
" in parenthesis");}
903 auto S82(
text What) {
return Gen.Err(Snip(),
"S82",
"Expected expression or \"",What,
"\", got ",CursorQuote(),CursorText(),CursorQuote(),
" in parenthesized parameter list");}
904 auto S83(
text What) {
return Gen.Err(Snip(),
"S83",
"Expected expression or \"",What,
"\", got ",CursorQuote(),CursorText(),CursorQuote(),
" in bracketed parameters");}
905 auto S84(
text What) {
return Gen.Err(Snip(),
"S84",
"Expected expression or \"",What,
"\", got ",CursorQuote(),CursorText(),CursorQuote(),
" in braced block");}
906 auto S85(
text What) {
return Gen.Err(Snip(),
"S85",
"Expected \"",What,
"\", got ",CursorQuote(),CursorText(),CursorQuote(),
" in prefix brackets");}
907 auto S86(
text What) {
return Gen.Err(Snip(),
"S86",
"Expected expression or \"",What,
"\", got ",CursorQuote(),CursorText(),CursorQuote(),
" in string interpolation");}
908 auto S88(
text) {
return Gen.Err(Snip(),
"S88",
"Expected expression, got ",CursorQuote(),CursorText(),CursorQuote(),
" in indented block");}
909 auto S88void() {
return Gen.Err(Snip(),
"S88",
"Expected expression, got ",CursorQuote(),CursorText(),CursorQuote(),
" in indented block");}
910 auto S89() {
return Gen.Err(Snip(),
"S89",
"Indentation mismatch: expected ",
Context.BlockInd[point(Cursor).Column]==
' '?
"space":
"tab",
", got ",CursorQuote(),CursorText(),CursorQuote());}
913 auto S97() {
return Gen.Err(Snip(),
"S97",
"Unexpected error");}
914 auto S98() {
return Gen.Err(Snip(),
"S98",
"Feature is not currently supported");}
915 auto S99() {
return Gen.Err(Snip(),
"S99",
"Exceeded maximum expression depth"); }
920 if(!Cursor.SnippedNewLine() && (Cursor[0]==0x0D || Cursor[0]==0x0A)) {
922 Cursor.NextLineStart = Cursor.Pos+1+(Cursor[0]==0x0D && Cursor[1]==0x0A);
929 if(Cursor.SnippedNewLine()) {
930 Cursor.Pos = Cursor.NextLineStart;
931 Cursor.LineStart = Cursor.Pos;
939 return Cursor.SnippedNewLine() ||
IsEnding(Cursor[0]);
946 return UpdateToken(),
nothing{};
957 Context.BlockInd = Cursor.LineStart;
958 Context.TrimInd = Cursor.LineStart;
966 return (this->*OnError)();
967 return UpdateToken(),
nothing{};
1030 if(Cursor.SnippedNewLine()) {
1060 return UpdateToken(),
nothing{};
1083 return Gen.CaptureAppend(
Capture,
More), Cursor.Token;
1086 else if(
TokenSet.Has(Cursor.Token))
1087 return Gen.CaptureAppend(
Capture,
More), Cursor.Token;
1094 while(
IsHex(Cursor[0])) {
1098 if(i<=MaxValue && i/16==
i0) {
1103 return (this->*OnError)();
1108 bool GotDot=Cursor[0]==
'.';
1114 bool GotDot=Cursor[0]==
'.';
1126 if(Cursor[0]==
'0' && Cursor[1]==
'x' &&
IsHex(Cursor[2])) {
1133 return Gen.NumHex(Snip(Start),
text(Start.Pos+2,Cursor.Pos));
1138 if(Cursor[0]==
'.' &&
IsDigit(Cursor[1])) {
1145 if(Cursor[0]==
'e' || Cursor[0]==
'E') {
1150 Exponent.
Start=Cursor.Pos;
1153 Exponent.
Stop=Cursor.Pos;
1158 auto Pos0=Cursor.Pos;
1178 auto Backslash = Cursor[0]==
'\\' && Cursor[1] && Cursor[2]==
'\'';
1182 Char32=
char32(Cursor[0]==
'r'?
'\r': Cursor[0]==
'n'?
'\n': Cursor[0]==
't'?
'\t': Cursor[0]);
1190 return Gen.Char32(Snip(Start),Char32,
false,Backslash);
1205 GRAMMAR_LET(n,ParseHex(6,0x10FFFFULL,&parser::S19));
1213 auto Pos0=Cursor.Pos;
1228 if(Cursor[0]==
'/' || (Cursor[0]==
' ' && Cursor.Pos>InputString && Cursor[-1]==
'/'))
1247 return text(Start.Pos,Cursor.Pos);
1252 auto Pos0=Cursor.Pos;
1255 while(
IsAlnum(Cursor[0]) || Cursor[0]==
'-' || Cursor[0]==
'.')
1281 if(Cursor[0]==
'#' && Cursor[1]==
'>')
1283 else if(Cursor[0]==0)
1284 return Cursor=Start, S04();
1325 if(Cursor.Pos!=Start.Pos)
1329 case '\r':
case '\n':
1342 if(Cursor[1]!=
'>') {
1352 if(Cursor[1]!=
'#') {
1355 else if(Cursor[2]!=
'>') {
1395 GRAMMAR_RUN(RequireClose(Start,u8
"{",u8
"}",&parser::S86));
1407 ApplyTrailing(
Expr,
true);
1409 bool Semicolon = Eat(u8
";");
1411 if(!Ending() && !Semicolon)
1415 ApplyTrailing(
Block0,Cursor);
1427 if(Cursor.Pos!=TextStart.Pos) {
1428 GRAMMAR_LET(
S,Gen.StringLiteral(Snip(TextStart),Leading));
1448 if(Cursor[1]!=
'/') {
1450 Gen.SyntaxesAppend(
Splices,e);
1458 Leading=capture_t();
1468 Gen.MarkupTrim(Leading);
1470 if(Cursor[0]!=
'~') {
1474 return Gen.Content(Snip(Start),
Splices);
1478 Gen.MarkupTrim(Leading);
1484 Gen.SyntaxesAppend(Results,
S);
1487 return Gen.Contents(Snip(Start),Leading,Results);
1493 Context.TrimInd = Cursor.LineStart;
1503 Block0.PunctuationLeading = PunctuationLeading;
1504 Block0.Punctuation = Punctuation;
1505 Gen.SyntaxesAppend(
Block0.Elements,Syntax);
1509 auto Block0=SingletonBlock(SnipFinished(BlockStart,
Expr),*
Expr,PunctuationLeading,Punctuation);
1510 Block0.BlockTrailing.MoveFrom(
Expr.Trailing);
1527 switch(
nat8(Cursor.Token)) {
1537 case token(u8
"{"): {
1542 Block0.BlockSnippet=Snip(BlockStart);
1546 case token(u8
"."): {
1559 case token(u8
":"): {
1574 return Commas(What,Prec,BlockStart,PunctuationLeading,&parser::S71);
1577 return SingletonBlock(BlockStart,
Right);
1584 return *
Fails=
true, block_t{};
1589 return BlockHelper(What,
prec::Nothing,OuterExpr,BlockStart,PunctuationLeading,
true,
false,
false,&
Fails);
1593 auto BlockStart=Cursor;
1595 return BlockHelper(What,Prec,OuterExpr,BlockStart,PunctuationLeading,
false,
true,
false);
1597 result_t<block_t> KeyBlock(
prec Prec,expr& OuterExpr,cursor BlockStart,
const capture_t& TokenLeading,
text Token,
const capture_t& PunctuationLeading) {
1599 GRAMMAR_LET(
Block0,BlockHelper(Token,Prec,OuterExpr,BlockStart,PunctuationLeading,
true,
false,
false));
1601 Block0.TokenLeading = TokenLeading;
1604 result_t<block_t> KeyBlockDefs(expr& OuterExpr,cursor BlockStart,
const capture_t& TokenLeading,
text Token) {
1609 Block0.TokenLeading = TokenLeading;
1616 auto BlockStart=Cursor;
1619 GRAMMAR_LET(
RightBlock,BlockHelper(What,Prec,OuterExpr,BlockStart,PunctuationLeading,
false,
false,
false));
1631 Block0.BlockSnippet = Snip(Start);
1635 Target.MarkupTag=
Id;
1636 return Gen.QualIdent(Snip(Start),
Block0,
Id);
1638 else return S23(u8
":)");
1645 Target.MarkupTag=
Id;
1646 return Gen.Ident(Snip(Start),
Id,u8
"",u8
"");
1648 else if(Cursor[0]==
'(') {
1652 return QualIdentQualified(Target,Start,
Block0);
1654 GRAMMAR_RUN(RequireClose(Start,u8
"(",u8
")",&parser::S81));
1655 Block0.BlockSnippet = Snip(Start);
1656 return Gen.Parenthesis(
Block0);
1658 else return S23(u8
":)");
1666 cursor CallTrailingStop;
1668 block_t& CallParameter;
1669 call* OuterCall =
nullptr;
1671 struct invoke: expr {
1675 call *FirstCall, *LastCall;
1677 block_t* Clauses[3];
1678 block_t* PriorClause;
1684 Of(
nullptr), Clauses{
nullptr,
nullptr,
nullptr}, PriorClause(
nullptr) {}
1685 void UpdateLastCall(call*
NewCall) {
1687 LastCall->OuterCall =
NewCall;
1693 Parser.CheckToken();
1694 this->Trailing = trailing{
1696 ? *LastCall->CallParameter.BlockTrailing.TrailingStart
1698 ? *PriorClause->BlockTrailing.TrailingStart:
1705 GRAMMAR_RUN(Parser.UpdateFrom(*this->OuterExpr,PriorClause->BlockTrailing,Parser.Gen.Invoke(
1706 Parser.SnipFinished(this->Start,*PriorClause),
1707 Parser.ApplyTrailing(*this->OuterExpr),
1708 *Clauses[0],Clauses[1],Clauses[2])));
1716 return Parser.Invoke(
NewTarget,Parser.Cursor,capture_t());
1720 else if(!StartToken) {
1723 if (!this->OuterExpr) {
return nothing{}; }
1726 return Parser.S61(FirstCall? FirstCall->CallWhat: u8
"macro end");
1728 Call->CallParameter.BlockSnippet=Snip(point::Start(
Call->CallParameter.BlockSnippet),*
Call->CallParameter.BlockTrailing.TrailingStart);
1730 Snip(
InsertCall->Start,point::Stop(
Call->CallParameter.BlockSnippet)),
Call->CallMode,
1735 else return Parser.S76(What);
1740 auto Specifiers = syntaxes_t{};
1742 while(
auto Call=Target.FirstCall) {
1743 Target.FirstCall=Target.FirstCall->OuterCall;
1744 ApplyTrailing(
Call->CallParameter,
Call->CallTrailingStop);
1746 GRAMMAR_ASSERT(!Target.Clauses[0] && !Target.Clauses[1] && !Target.Clauses[2]);
1748 Call->CallParameter.BlockSnippet = Snip(point::Start(*
FirstSpecifier),point::Stop(
Call->CallParameter.BlockSnippet));
1749 Call->CallParameter.Specifiers = Specifiers;
1750 Target.Clauses[0] = &
Call->CallParameter;
1751 Target.Of =
nullptr;
1755 if(!Gen.SyntaxesLength(Specifiers))
1758 Gen.SyntaxesAppend(Specifiers,
E);
1762 if(Target.PriorClause)
1766 Block0.Specifiers = Specifiers;
1767 Target.LastCall =
nullptr;
1769 Target.PriorClause =
Block0.BlockSnippet? &
Block0: Target.PriorClause;
1770 if(!Target.ExprStop)
1773 return Target.OnFinish(*
this);
1775 result_t<nothing> Invoke(invoke& Target,cursor BlockStart,capture_t TokenLeading=capture_t()) {
1786 if(!Target.AllowPostfixes.Has(PostfixToken))
1787 return Target.OnFinish(*
this);
1790 switch(
nat8(PostfixToken)) {
1791 case token(u8
"("): {
1799 return parser::S82(u8
":)");
1806 Block0.BlockSnippet = Snip(BlockStart);
1809 NewCall.CallTrailingStop = Cursor;
1810 Target.UpdateLastCall(&
NewCall);
1812 Target.AllowPostfixes = (Target.AllowPostfixes &
~ParenPostfixes) | Target.InTokens;
1813 if(Target.StartToken==
token(u8
"if"))
1815 return Invoke(Target,Cursor);
1820 capture_t PunctuationLeading;
1821 if(PostfixToken==
token(u8
"with")) {
1825 if(Cursor.Token!=
token(u8
"<"))
1855 NewCall.CallTrailingStop = Cursor;
1856 Target.UpdateLastCall(&
NewCall);
1857 return Invoke(Target,Cursor);
1859 else if(PostfixToken!=
token(u8
"with")) {
1877 Target.AllowPostfixes = Target.AllowPostfixes &
~Target.InTokens;
1878 if(Target.StartToken==
token(u8
"if"))
1880 return InvokeClause(Target,Target.Of!=0,BlockStart,
Block0,Cursor);
1882 return Target.OnFinish(*
this);
1890 Target.AllowPostfixes = (Target.AllowPostfixes &
~Target.InTokens) | Target.PostTokens;
1891 return InvokeClause(Target,1,BlockStart,
Block0,Cursor);
1893 case token(u8
"until"): {
1899 return InvokeClause(Target,2,BlockStart,
Block0,Cursor);
1901 case token(u8
"catch"): {
1916 case token(u8
"else"): {
1921 if(Cursor.Token==
token(u8
"if")) {
1925 Target.ExprStop =
ElseExpr.ExprStop;
1929 return InvokeClause(Target,2,BlockStart,
ElseBlock,Cursor);
1934 return InvokeClause(Target,2,BlockStart,
ElseBlock,Cursor);
1938 if(!Target.Clauses[0] || Target.FirstCall) {
1941 return InvokeClause(Target,Target.FirstCall!=
nullptr,BlockStart,
Block0,BlockStart,TokenLeading);
1944 if(!Target.OuterExpr->MarkupTag)
1946 if(Target.PriorClause)
1947 ApplyTrailing(*Target.PriorClause,BlockStart);
1948 Target.OuterExpr->MarkupFinished=
true;
1950 switch(
nat8(PostfixToken)) {
1951 case token(u8
","): {
1953 return InvokeMarkup(Target,TokenLeading,capture_t(),
InnerContent,capture_t());
1955 case token(u8
";"): {
1963 case token(u8
">"): {
1986 case token(u8
":>"): {
2004 Target.AllowPostfixes&
token_set{u8
"catch",u8
"do",u8
"else",u8
"then",u8
"until",u8
"with",u8
"{",u8
">",u8
":>",u8
",",u8
";"}));
2006 return Invoke(Target,BlockStart,TokenLeading);
2007 return Target.OnFinish(*
this);
2018 auto NoTrailing = trailing{Cursor, capture_t()};
2020 Snip(*MarkupExpr.MarkupStart),
2021 !MarkupExpr.OuterMarkup? u8
"<": u8
",",
2022 MarkupExpr.ExprLeading,
2023 ApplyTrailing(MarkupExpr),
2028 MarkupExpr.ExprLeading = capture_t();
2029 return MarkupExpr.OnFinish(*
this);
2035 return MarkupExpr(
nullptr,Start);
2039 struct ins {cursor Start;
token InToken; cursor NextStart; capture_t NextLeading;
const ins* NextIns;};
2048 auto InToken = Cursor.Token;
2051 auto NextStart=Cursor;
2053 auto NextIn=ins{Start,InToken,NextStart,NextLeading,
Ins};
2061 SnipFinished(
Ins->Start,
Right),
Ins->InToken->PrefixMode,
Ins->InToken->Symbol,
2070 auto DefineToken=Cursor.Token;
2075 SnipFinished(Target.Start,
Right),
2076 ApplyTrailing(Target),DefineToken->Symbol,
Right)));
2085 switch(
nat8(Cursor.Token)) {
2087 if(Cursor[0]==
'0' && Cursor[1]==
'o' &&
IsHex(Cursor[2])) {
2089 return UpdateSpaceTrailing(Target,Gen.Char8(Snip(Target.Start),c));
2091 else if(Cursor[0]==
'0' && Cursor[1]==
'u' &&
IsHex(Cursor[2])) {
2093 return UpdateSpaceTrailing(Target,Gen.Char32(Snip(Target.Start),c,
true,
false));
2095 else return UpdateSpaceTrailing(Target,Num());
2097 case token(u8
"\""): {
2102 return UpdateSpaceTrailing(Target,Gen.String(Snip(Target.Start),
Capture));
2104 case token(u8
"'"): {
2106 return UpdateSpaceTrailing(Target,CharLit());
2118 return UpdateSpaceTrailing(Target,QualIdent(What,Target,
true));
2120 case token(u8
"@"): {
2127 return UpdateFrom(Target,
RightExpr.Trailing,Gen.PrefixAttribute(
2144 if(Cursor[0]!=
'@' && Cursor[0]!=
'(' && !
IsAlnum(Cursor[0]))
2151 case token(u8
"<"): {
2153 return UpdateSpaceTrailing(Target,Markup());
2155 case token(u8
"/"): {
2158 return UpdateSpaceTrailing(Target,Gen.Path(Snip(Target.Start),P));
2168 return DefPostfix(Target);
2180 bool bIsSet = Cursor.Token ==
token(u8
"set");
2181 bool bLive = Cursor.Token ==
token(u8
"live");
2183 syntaxes_t Attributes;
2190 if (Cursor.Token !=
token(u8
"<"))
2198 ApplyTrailing(
Expr,
true);
2199 Gen.SyntaxesAppend(Attributes,*
Expr);
2203 GRAMMAR_RUN(RequireClose(Cursor,u8
"<",u8
">",&parser::S85));
2211 if (Cursor.Token ==
token(u8
"live"))
2220 auto ChooseBlock=SingletonBlock(ChooseStart,Choose);
2221 GRAMMAR_RUN(UpdateFrom(Target,ChooseBlock.BlockTrailing,Gen.PrefixToken(
2222 SnipFinished(Target.Start,Choose),
2223 BaseToken->PrefixMode,BaseToken->Symbol,
2224 ChooseBlock, false, Attributes, bLive)));
2225 if(DefPostfixes.Has(Cursor.Token))
2226 return DefPostfix(Target);
2234 auto RightStart=Cursor;
2237 auto RightBlock=SingletonBlock(RightStart,RightExpr);
2238 return UpdateFrom(Target,RightBlock.BlockTrailing,Gen.PrefixToken(
2239 SnipFinished(Target.Start,RightExpr),
2240 BaseToken->PrefixMode,BaseToken->Symbol,
2244 case token(u8
"&"): {
2249 return UpdateFrom(Target,Right.Trailing,Gen.Escape(
2250 SnipFinished(Target.Start,Right),*Right));
2257 return UpdateFrom(Target,RightBlock.BlockTrailing,Gen.PrefixToken(
2258 SnipFinished(Target.Start,RightBlock),
2259 BaseToken->PrefixMode,BaseToken->Symbol,
2260 RightBlock,RightBlock.Punctuation==punctuation::Braces));
2263 case token(u8
"["): {
2267 GRAMMAR_RUN(RequireClose(Target.Start,u8
"[",u8
"]",&parser::S85));
2269 return UpdateFrom(Target,Right.BlockTrailing,Gen.PrefixBrackets(
2270 SnipFinished(Target.Start,Right),
2274 case token(u8
"if"): {
2276 Target.MarkupTag=u8
"if";
2278 GRAMMAR_RUN(UpdateSpaceTrailing(Target,Gen.Native(Snip(Target.Start),u8
"if")));
2282 case token(u8
"return"):
case token(u8
"yield"):
case token(u8
"break"):
case token(u8
"continue"): {
2286 Right.BlockTrailing.TrailingStart=Cursor;
2290 return UpdateFrom(Target,
Right.BlockTrailing,Gen.PrefixToken(
2291 SnipFinished(Target.Start,
Right),
2308 while(!Target.Finished) {
2310 auto TokenLeading = capture_t();
2311 auto PostfixToken = Cursor.Token;
2317 return Target.OnFinish(*
this);
2319 if(!Target.AllowPostfixes.Has(Cursor.Token))
2320 return S61(PostfixToken->Symbol);
2321 switch(
nat8(Cursor.Token)) {
2331 if(Target.MarkupStart)
2335 case token(u8
"*"):
case token(u8
"/"):
2336 case token(u8
"+"):
case token(u8
"-"):
2337 case token(u8
"to"):
case token(u8
".."):
case token(u8
"->"):
2342 case token(u8
"and"):
2343 case token(u8
"or"): {
2354 Target.MarkupTag=u8
"";
2358 GRAMMAR_RUN(WhenExpr(PostfixToken->Symbol,PostfixToken->PostfixRightPrec(),PostfixToken->PostfixRightPrec(),&Target,Leading,[&](expr&
Right)->result_t<nothing> {
2359 return UpdateFrom(Target,Right.Trailing,Gen.InfixToken(
2360 SnipFinished(Target.Start,Right),PostfixToken->PostfixMode,
2361 ApplyTrailing(Target),PostfixToken->Symbol,*Right
2363 },PostfixToken->PostfixAllowMask));
2366 case token(u8
"^"):
case token(u8
"?"):
case token(u8
"ref"): {
2369 Target.MarkupTag=u8
"";
2371 GRAMMAR_RUN(UpdateSpaceTrailing(Target,Gen.PostfixToken(
2372 Snip(Target.Start),PostfixToken->PostfixMode,
2373 ApplyTrailing(Target),PostfixToken->Symbol)));
2376 case token(u8
"["): {
2386 ApplyTrailing(Target),
Block0)));
2389 case token(u8
"@"): {
2394 return UpdateFrom(Target,Right.Trailing,Gen.PostfixAttribute(
2395 SnipFinished(Target.Start,Right),
2396 ApplyTrailing(Target),*Right));
2400 case token(u8
"at"):
case token(u8
"of"): {
2407 SnipFinished(
Target.Start,
Right),PostfixToken->PostfixMode,
2408 ApplyTrailing(Target),
Right)));
2411 case token(u8
"=>"):
case token(u8
":="):
case token(u8
"next"): {
2415 GRAMMAR_LET(
Right,BraceInd(PostfixToken->Symbol,PostfixToken->PostfixRightPrec(),Target));
2418 ApplyTrailing(Target),PostfixToken->Symbol,
Right)));
2421 case token(u8
"."): {
2426 Gen.CaptureAppend(
Target.Trailing.TrailingCapture,TokenLeading);
2428 GRAMMAR_RUN(UpdateSpaceTrailing(Target,Gen.InfixToken(
2429 Snip(
Target.Start),PostfixToken->PostfixMode,
2430 ApplyTrailing(Target),PostfixToken->Symbol,
Id)));
2435 case token(u8
"{"):
case token(u8
":"):
case token(u8
"<"):
case token(u8
"("):
2436 case token(u8
"in"):
case token(u8
"with"):
2448 return UpdateFrom(Target,
InBlock.BlockTrailing,Gen.InfixBlock(
2450 ApplyTrailing(Target),u8
"",
InBlock));
2455 case token(u8
"is"): {
2462 ApplyTrailing(Target),u8
"is",
Right)));
2465 case token(u8
"over"):
case token(u8
"when"):
case token(u8
"where"):
case token(u8
"while"): {
2472 ApplyTrailing(Target),PostfixToken->Symbol,
Right)));
2476 GRAMMAR_SET(PostfixToken,ScanKey(TokenLeading,token_set{u8
"is",u8
"with",u8
"{",u8
">",u8
":>",u8
".",u8
",",u8
";"}));
2480 case token(u8
"+="):
case token(u8
"-="):
case token(u8
"*="):
case token(u8
"/="):
2481 return S66(PostfixToken->Symbol);
2493 if(
Expr->FinishPrec<=FinishPrec)
2496 Expr->ExprStop=
true;
2502 template<
class f>
struct when_expr: expr {
2503 using result_type =
decltype((*(f*)
nullptr)(*(expr*)
nullptr));
2512 scoped_guard
ExprDepthGuard(Parser.ExprDepth, Parser.ExprDepth + 1);
2514 return Parser.S99();
2522 this->ExprSyntax = Parser.Gen.Leading(this->ExprLeading,**
this);
2528 template<
class f> when_expr(
prec,expr*,token_set,
const cursor&,
const capture_t&,
const f&,expr* e=
nullptr,
bool b=
false)->when_expr<f>;
2529 template<
class f>
typename when_expr<f>::result_type WhenExpr(text What,
prec ParsePrec,
prec FinishPrec,expr* OuterExpr,
2530 const capture_t& ExprLeading,
const f&
F,
2543 Expr.Trailing = trailing{};
2546 Expr.MarkupStart = MarkupStart;
2547 Expr.OuterMarkup = OuterMarkup;
2549 if(!
Expr.MarkupFinished)
2563 ApplyTrailing(
Expr,
true);
2565 Block0.BlockSnippet=Snip(Start,*
Expr.Trailing.TrailingStart),
2566 Block0.BlockTrailing.MoveFrom(
Expr.Trailing);
2567 Leading=capture_t();
2585 ListBlock.PunctuationLeading = PunctuationLeading;
2595 if(Cursor.Token==token(u8
";") || Ending()) {
2628 ListBlock.BlockSnippet = Snip(BlockStart);
2635 if(
nat8(Cursor[0])==0xEF) {
2636 if(
nat8(Cursor[1])==0xBB &&
nat8(Cursor[2])==0xBF)
Next(3);
2646 if(
nat(Cursor.Pos-InputString)!=InputLength)