578
585
static c_bool qlx_quotient(Styx_T styctx, GLS_Tok id)
580
styxQlxDfn_defn((styxQlxDfn)getDfn(styctx,id,C_True),_,_,_,_,_,&exp);
587
styxQlxDfn qd = (styxQlxDfn)getDfn(styctx,id,C_True);
588
if( !styxQlxDfn_defn(qd,_,_,_,_,_,&exp) )
581
590
return styxExp_quot(exp,_,_);
584
593
static c_bool qlx_dyck(Styx_T styctx, GLS_Tok id)
586
styxQlxDfn_defn((styxQlxDfn)getDfn(styctx,id,C_True),_,_,_,_,_,&exp);
595
styxQlxDfn qd = (styxQlxDfn)getDfn(styctx,id,C_True);
596
if( !styxQlxDfn_defn(qd,_,_,_,_,_,&exp) )
587
598
if( styxExp_quot(exp,&exp,_) )
589
600
return styxExp_dyck(exp,_,_,_);
592
603
static c_bool qlx_pattern(Styx_T styctx, GLS_Tok id)
594
styxQlxDfn_defn((styxQlxDfn)getDfn(styctx,id,C_True),_,_,_,_,_,&exp);
605
styxQlxDfn qd = (styxQlxDfn)getDfn(styctx,id,C_True);
606
if( !styxQlxDfn_defn(qd,_,_,_,_,_,&exp) )
595
608
if( styxExp_quot(exp,&exp,_) )
597
610
return styxExp_spat(exp,_,_,_) || styxExp_epat(exp,_,_,_);
600
613
static c_bool qlx_ica(Styx_T styctx, GLS_Tok id)
601
614
{ styxQlxOpt opt;
602
styxQlxDfn_defn((styxQlxDfn)getDfn(styctx,id,C_True),_,&opt,_,_,_,_);
615
styxQlxDfn qd = (styxQlxDfn)getDfn(styctx,id,C_True);
616
if( !styxQlxDfn_defn(qd,_,&opt,_,_,_,_) )
603
618
return styxQlxOpt_ignca(opt);
606
621
static void Pass1(Styx_T styctx, styxSource s)
607
622
/* Collecting definitions and scoping rules */
608
{ Styx_T lanctx, rootctx; bool startflg = False; int indcnt = 0, rc;
623
{ Styx_T lanctx, rootctx; bool startflg = False;
624
int indcnt = 0, dyncnt = 0, rc;
609
625
MAP(PT_Term,NULL) pro = MAP_newMap(styctx->gloty); /* Productions */
610
626
PT_Itr it; styxOptCfg optcfg; GLS_Lst(styxDfn) dfns;
611
627
rootctx = RootCtx(styctx);
617
633
{ PT_Term t = PT_termIT(it), st = (PT_Term)NULL;
618
634
if (PT_stateIT(it) == PT_POST)
619
635
{ styxQlxDfn qd; styxDfn pd; styxPrd p; GLS_Tok id, sgid, dgid;
620
637
/* Scope(Source): all identifiers in QLX definitions */
621
638
if (styx_QlxDfn(t,&qd) )
622
639
{ styxQlxOpt o; styxQlxCat c; styxQlxGrp gsrc, gdst; styxExp e, e1;
623
if( styxQlxDfn_igrp(qd,&id) || styxQlxDfn_xgrp(qd,&id) ||
640
if( styxQlxDfn_igrp(qd,&id) || styxQlxDfn_xgrp(qd,&id) ||
641
styxQlxDfn_tgrp(qd,&id) ||
624
642
styxQlxDfn_mgrp(qd,&id,_) )
625
643
{ GLS_Lst(GLS_Tok) ids, lst;
626
644
if (MAP_defined(styctx->grp,GLS_Tok_symbol(id)) ||
872
906
else MAP_dfndom(pro,id,NULL);
910
if (styx_Mbr(t,&mbr) )
912
if( styxMbr_dtok(mbr,_,_) )
917
mbr,styctx->diag,"production with more than one dynamic token members"
877
if( ! startflg && styxOptCfg_cfg(optcfg,&dfns) && ! GLS_EMPTY(dfns) )
922
if( ! startflg && styxOptCfg_cfg(optcfg,&dfns,_) && ! GLS_EMPTY(dfns) )
878
923
PT_diag_err(dfns,styctx->diag,"missing start production");
879
924
MAP_freeMap(pro);
882
static void Pass2_checkMbrIde(Styx_T styctx, GLS_Tok id, GLS_Lst(styxQlxDfn) qlxdfns)
883
/* check wether production member 'id' is a defined token or nonterminal */
927
static int Pass2_checkMbrIde(Styx_T styctx, GLS_Tok id, GLS_Lst(styxQlxDfn) qlxdfns)
928
/* check wether production or conflict member 'id' is a defined token or nonterminal
929
rc = -1 (unknown), 0 (token), 1 (nonterminal), 2 (embedded language token)
885
932
Styx_T rootctx = RootCtx(styctx);
886
933
if (!MAP_defined(styctx->glo,id) &&
887
934
!MAP_defined(rootctx->embed,GLS_Tok_symbol(id)))
889
if( !GLS_EMPTY(qlxdfns) )
892
id,styctx->diag,"identifier '%s' undefined",GLS_Tok_string(id)
936
if( GLS_EMPTY(qlxdfns) )
896
942
if (MAP_defined(styctx->glo,id))
897
943
{ PT_Term def = MAP_apply(PT_Term,styctx->glo,id);
898
944
styxQlxDfn qd; styxQlxCat qc;
899
if( ! ( styx_Dfn(def,_) ||
900
( styx_QlxDfn(def,&qd) &&
901
styxQlxDfn_defn(qd,&qc,_,_,_,_,_) &&
902
(styxQlxCat_tokC(qc) || styxQlxCat_lanC(qc)) ) ) )
945
if( ! ( styx_Dfn(def,_) ||
946
( styx_QlxDfn(def,&qd) &&
947
( styxQlxDfn_defd(qd,_) ||
948
styxQlxDfn_defn(qd,&qc,_,_,_,_,_) &&
949
(styxQlxCat_tokC(qc) || styxQlxCat_lanC(qc)) ) ) ) )
905
id,styctx->diag,"'%s' is no grammar symbol",GLS_Tok_string(id)
953
id,styctx->diag,"invalid production member symbol '%s'",GLS_Tok_string(id)
957
return styx_Dfn(def,_) ? 1 : 0;
960
if( MAP_defined(styctx->grp,GLS_Tok_symbol(id)) )
967
id,styctx->diag,"undefined grammar symbol '%s'",GLS_Tok_string(id)
910
972
static void Pass2_checkMbr(Styx_T styctx, styxMbr m, GLS_Lst(styxQlxDfn) qlxdfns)
911
973
/* check production member 'm' (Pass2) */
974
{ GLS_Tok id, did; int rc, flg;
913
975
if ( styxMbr_ntm(m,&id) )
915
Pass2_checkMbrIde(styctx,id,qlxdfns);
977
rc = Pass2_checkMbrIde(styctx,id,qlxdfns);
978
if( rc == 0 && MAP_defined(styctx->dyntok,GLS_Tok_symbol(id)) )
980
flg = MAP_apply(int,styctx->dyntok,GLS_Tok_symbol(id));
982
MAP_upddom(styctx->dyntok,GLS_Tok_symbol(id),(long)flg);
986
if ( styxMbr_dtok(m,&id,&did) )
988
rc = Pass2_checkMbrIde(styctx,id,qlxdfns);
989
if( rc == 1 || rc == 2 ||
990
MAP_defined(styctx->dyntok,GLS_Tok_symbol(id)) )
994
id,styctx->diag,"expected token '%s'",GLS_Tok_string(id)
997
if( !MAP_defined(styctx->dyntok,GLS_Tok_symbol(did)) )
1001
did,styctx->diag,"undefined dynamic token '%s'",GLS_Tok_string(did)
1006
flg = MAP_apply(int,styctx->dyntok,GLS_Tok_symbol(did));
1008
MAP_upddom(styctx->dyntok,GLS_Tok_symbol(did),(long)flg);
1021
static void Pass2_checkConflict
1023
Styx_T styctx, styxConflict conflict,
1024
GLS_Lst(styxQlxDfn) qlxdfns
1026
/* check wether conflict token, state and rules refer to defined
1027
token, nonterminals and productions.
1029
{ styxState state; styxToken token; GLS_Lst(styxRule) rules, itr;
1030
if( styxConflict_defn(conflict,&state,&token,&rules) )
1031
{ GLS_Tok id1, id2, pid;
1033
if( styxState_ide(state,&id1) )
1035
rc = Pass2_checkMbrIde(styctx,id1,qlxdfns);
1037
if( styxToken_ide(token,&id1) )
1039
rc = Pass2_checkMbrIde(styctx,id1,qlxdfns);
1040
if( rc == 1 ) /* nonterminal */
1044
id1,styctx->diag,"'%s' must be a token",GLS_Tok_string(id1)
1048
GLS_FORALL(itr,rules)
1050
styxRule rule = GLS_FIRST(styxRule,itr);
1051
if( styxRule_red(rule,&id1,&id2) )
1053
rc = Pass2_checkMbrIde(styctx,id1,qlxdfns);
1054
if( rc == 0 || rc == 2 ) /* token */
1058
id1,styctx->diag,"'%s' must be a nonterminal",GLS_Tok_string(id1)
1062
if( rc == 1 ) /* nonterminal */
1063
{ PT_Term def = MAP_apply(PT_Term,styctx->glo,id1);
1064
styxDfn pd; GLS_Lst(styxPrd) prds, prditr;
1065
if( styx_Dfn(def,&pd) && styxDfn_defn(pd,_,_,_,&prds) )
1067
c_bool found = C_False;
1068
GLS_FORALL(prditr,prds)
1069
{ styxPrd p = GLS_FIRST(styxPrd,prditr);
1070
if( styxPrd_prod(p,_,&pid,_) &&
1071
GLS_Tok_symbol(pid) == GLS_Tok_symbol(id2) );
1073
found = C_True; break;
1080
id2,styctx->diag,"'%s' must be a production name",GLS_Tok_string(id2)
927
1090
static void Pass2(Styx_T styctx, styxSource s)
928
1091
/* References */
929
1092
{ PT_Itr it; Styx_T rootctx = RootCtx(styctx), tokctx;
953
1116
if (PT_stateIT(it) == PT_POST)
1117
{ styxMbr m; styxConflict cr;
955
1118
if (styx_Exp(t,&exp) )
957
1120
if ( styxExp_ident(exp,&id) )
959
1122
tokctx = styctx;
960
1123
if( MAP_defined(lanexp,exp) )
961
1124
tokctx = MAP_apply(Styx_T,lanexp,exp);
962
1125
if (!MAP_defined(tokctx->glo,id))
965
id,styctx->diag,"identifier '%s' undefined",GLS_Tok_string(id)
1128
id,styctx->diag,"undefined identifier '%s'",GLS_Tok_string(id)
968
if (!styx_QlxDfn(MAP_apply(PT_Term,tokctx->glo,id),_))
1131
if (!styx_QlxDfn(MAP_apply(PT_Term,tokctx->glo,id),&qd))
971
id,styctx->diag,"'%s' is no QLX-identifier",
1134
id,styctx->diag,"undefined QLX-identifier '%s'", GLS_Tok_string(id)
975
if( qlx_usage(tokctx,id) == UsageLan ||
1137
if( styxQlxDfn_defd(qd,_) ||
1138
qlx_usage(tokctx,id) == UsageLan ||
976
1139
qlx_quotient(tokctx,id) || qlx_dyck(tokctx,id)
977
1140
/*|| qlx_pattern(tokctx,id)*/ )
1740
1908
ftoks = (MAP(_,_))NULL;
1741
1909
if( parctx == styctx )
1743
grpid = StrCopy(symbolToString(grpsym));
1911
if( styxQlxDfn_tgrp(d,_) )
1912
grpid = Str_printf("tok_%s",symbolToString(grpsym));
1914
grpid = StrCopy(symbolToString(grpsym));
1749
"%s__%s",styctx->language,symbolToString(grpsym)
1918
if( styxQlxDfn_tgrp(d,_) )
1921
"%s__tok_%s",styctx->language,symbolToString(grpsym)
1926
"%s__%s",styctx->language,symbolToString(grpsym)
1751
1928
lansym = stringToSymbol(styctx->language);
1752
1929
if( MAP_defined(g_ftoks,lansym) )
1753
1930
ftoks = MAP_apply(MAP(_,_),g_ftoks,lansym);
1788
1965
MAP_forItrAsg(id,rng,itr,styctx->tokgrp)
1790
1967
grpsym = MAP_apply(symbol,styctx->grptok,id);
1968
if( MAP_defined(styctx->grp,grpsym) )
1969
d = MAP_apply(styxQlxDfn,styctx->grp,grpsym);
1970
else d = (styxQlxDfn)NULL;
1791
1971
if( grpsym == InitialGroup )
1792
1972
grpid = StrCopy(igrpid);
1794
1974
if( parctx == styctx )
1795
grpid = StrCopy(symbolToString(grpsym));
1976
if( d != (styxQlxDfn)NULL && styxQlxDfn_tgrp(d,_) )
1977
grpid = Str_printf("tok_%s",symbolToString(grpsym));
1979
grpid = StrCopy(symbolToString(grpsym));
1799
"%s__%s",styctx->language,symbolToString(grpsym)
1983
if( d != (styxQlxDfn)NULL && styxQlxDfn_tgrp(d,_) )
1986
"%s__tok_%s",styctx->language,symbolToString(grpsym)
1991
"%s__%s",styctx->language,symbolToString(grpsym)
1994
if( MAP_defined(styctx->grp,rng) )
1995
d = MAP_apply(styxQlxDfn,styctx->grp,rng);
1801
1996
if( rng == InitialGroup )
1802
1997
sgrpid = StrCopy(igrpid);
1814
2009
if( parctx == styctx )
1815
sgrpid = StrCopy(symbolToString(rng));
2011
if( d != (styxQlxDfn)NULL && styxQlxDfn_tgrp(d,_) )
2012
sgrpid = Str_printf("tok_%s",symbolToString(rng));
2014
sgrpid = StrCopy(symbolToString(rng));
1819
"%s__%s",styctx->language,symbolToString(rng)
2018
if( d != (styxQlxDfn)NULL && styxQlxDfn_tgrp(d,_) )
2021
"%s__tok_%s",styctx->language,symbolToString(rng)
2026
"%s__%s",styctx->language,symbolToString(rng)
1821
2029
if( !MAP_defined(styctx->metagrp,grpsym) )
1823
2031
if( MAP_defined(patids,id) )
2187
static void Pass3_checkConflict
2189
Styx_T styctx, styxConflict conflict,
2190
GLS_Lst(styxQlxDfn) qlxdfns
2192
/* check wether conflict token, state and rules refer to defined
2193
token, nonterminals and productions.
2195
{ styxState state; styxToken token;
2196
if( styxConflict_defn(conflict,&state,&token,_) )
2198
if( styxState_seq(state,&seq) )
2200
Pass3_checkMbrSeq(styctx,seq,qlxdfns);
2202
if( styxToken_seq(token,&seq) )
2204
Pass3_checkMbrSeq(styctx,seq,qlxdfns);
1979
2209
static void Pass3(Styx_T styctx, styxSource src)
1981
2211
{ PT_Itr it; GLS_Lst(styxQlxDfn) qlxdfns;
2428
static void trans_Dfns_addConflict
2430
Styx_T styctx, PLR_Cfg Cfg,
2431
styxConflict conflict, GLS_Lst(styxQlxDfn) qlxdfns,
2432
MAP(symbol,NULL) key, MAP(symbol,NULL) exttok
2434
{ styxState state; styxToken token; GLS_Lst(styxRule) rules, itr;
2435
if( styxConflict_defn(conflict,&state,&token,&rules) )
2436
{ GLS_Tok seq, id1, id2, nat;
2437
string s; symbol statesym = NULL, tokensym = NULL;
2438
int idx = -1; c_bool ucs4;
2439
if( styxState_seq(state,&seq) )
2441
s = normalKeyword(styctx,seq,GLS_EMPTY(qlxdfns),&ucs4);
2442
statesym = stringToSymbol(s);
2444
if( !MAP_defined(key,statesym) )
2446
PT_diag_err(seq,styctx->diag,"unknown state symbol");
2451
if( styxState_ide(state,&id1) )
2453
statesym = GLS_Tok_symbol(id1);
2454
if( GLS_EMPTY(qlxdfns) && !MAP_defined(exttok,statesym) )
2456
PT_diag_err(id1,styctx->diag,"unknown state symbol");
2461
if( styxState_nat(state,&nat) )
2463
idx = atoi(GLS_Tok_string(nat));
2465
if( styxToken_seq(token,&seq) )
2467
s = normalKeyword(styctx,seq,GLS_EMPTY(qlxdfns),&ucs4);
2468
tokensym = stringToSymbol(s);
2470
if( !MAP_defined(key,tokensym) )
2472
PT_diag_err(seq,styctx->diag,"unknown token symbol");
2477
if( styxToken_ide(token,&id1) )
2479
tokensym = GLS_Tok_symbol(id1);
2480
if( GLS_EMPTY(qlxdfns) && !MAP_defined(exttok,tokensym) )
2482
PT_diag_err(id1,styctx->diag,"unknown token symbol");
2486
if( tokensym == NULL )
2488
PT_diag_err(token,styctx->diag,"unknown token symbol");
2491
if( statesym == NULL && idx == -1 )
2493
PT_diag_err(token,styctx->diag,"undefined conflict state");
2496
PLR_addCCtx(Cfg,idx,statesym==NULL?NULL:symbolToString(statesym),symbolToString(tokensym));
2497
GLS_FORALL(itr,rules)
2499
styxRule rule = GLS_FIRST(styxRule,itr);
2500
if( styxRule_red(rule,&id1,&id2) )
2502
PLR_addCRule(Cfg,GLS_Tok_string(id1),GLS_Tok_string(id2));
2192
2508
static void trans_Dfns_addMbr_Seq
2194
2510
Styx_T styctx, PLR_Cfg Cfg,
2323
2648
MAPTY keyty; MAP(symbol,NULL) key, exttok; /* reserved words */
2324
2649
PLR_Cfg Cfg; MAPIT itr; PT_Itr it;
2325
GLS_Lst(styxQlxDfn) qlxdfns; GLS_Lst(styxDfn) dfns, dfnitr;
2650
GLS_Lst(styxQlxDfn) qlxdfns;
2651
GLS_Lst(styxDfn) dfns, dfnitr;
2652
GLS_Lst(styxConflict) conflicts, critr;
2326
2653
styxOptCfg optcfg; styxDfn pd; styxMbr m;
2327
2654
GLS_Tok id, nt, elan;
2328
2655
c_bool tkother = C_False;
2329
2656
styxSource_root(src,_,&id,&qlxdfns,&optcfg);
2330
styxOptCfg_cfg(optcfg,&dfns);
2657
styxOptCfg_cfg(optcfg,&dfns,&conflicts);
2331
2658
Cfg = PLR_createCfg(symbolToString(GLS_Tok_symbol(id)),styctx->version);
2332
2659
keyty = MAP_newTyp(primCopy,primFree,primEqual,primHash,primCopy,primFree);
2333
2660
key = MAP_newMap(keyty);
2370
2713
PLR_addTK(Cfg,PLR_TOK_Other,PLR_TYP_TOK);
2372
2717
MAP_freeMap( key );
2373
2718
MAP_freeMap( exttok );
2374
2719
MAP_freeTyp( keyty );
2376
2722
PLR_endSD(Cfg); /* Sorting Token & Nonterminals */
2378
2724
MAP_forItr(id,itr,styctx->glo)
2379
if( styx_QlxDfn(MAP_apply(PT_Term,styctx->glo,id),_) &&
2726
if( styx_QlxDfn(MAP_apply(PT_Term,styctx->glo,id),&qd) &&
2727
styxQlxDfn_defn(qd,_,_,_,_,_,_) &&
2380
2728
qlx_usage(styctx,id) == UsageCom ) /* Special Token */
2381
2729
PLR_addST(Cfg,GLS_Tok_string(id));
2382
2731
GLS_FORALL(dfnitr,dfns)
2383
2732
{ styxCat c; GLS_Lst(styxPrd) prds, prditr;
2384
2733
pd = GLS_FIRST(styxDfn,dfnitr);