Commit 735a8582d7ea7317e4228c29a851d3e3061fe156

Authored by Alain Prouté
1 parent c88c38d6

-

anubis_dev/library/syntactic_analysis/anubis_output.anubis
... ... @@ -368,7 +368,7 @@ define List(APG_Scenario)
368 368 For each state, there is a longuest sequence of grammar symbols before the dot in the
369 369 scenarios of the state. This sequence is the 'longuest stack' for that state.
370 370  
371   -define List(String)
  371 +define List(APG_Symbol_Act)
372 372 get_longuest_stack
373 373 (
374 374 List(APG_Scenario) l
... ... @@ -518,6 +518,13 @@ type Conflict:
518 518 shift_reduce (String token,
519 519 Resolved_As resolution).
520 520  
  521 +define Bool
  522 + less
  523 + (
  524 + Conflict c1,
  525 + Conflict c2
  526 + ) =
  527 + token(c1) < token(c2).
521 528  
522 529 define (Word32,Word32)
523 530 number_of_conflicts
... ... @@ -622,7 +629,7 @@ define Resolved_As
622 629 List(AssocEntry) assoc_table
623 630 ) =
624 631 if get_rule(rule_id,rules) is grammar_rule(_,_,body,mb_prec) then
625   - if compute_rule_precedence(names_in(body),mb_prec,prec_table) is
  632 + if compute_rule_precedence(symbols_only(names_in(body)),mb_prec,prec_table) is
626 633 {
627 634 failure then if get_precedence(token,prec_table) is
628 635 {
... ... @@ -1154,7 +1161,7 @@ define One
1154 1161 then print(s," vmsg(\"Reducing using rule "+to_decimal(id)+"\");\n")
1155 1162 else unique);
1156 1163 print(s," "+put_do_ret(name+"("+val+")",
1157   - length(body))+".\n")
  1164 + length(symbols_only(body)))+".\n")
1158 1165 };
1159 1166 print_reduce_functions(s,other_rules,type_table,parser_name,mb_extra,options)
1160 1167 }.
... ... @@ -1193,10 +1200,10 @@ define One
1193 1200 if sc is scenario(rid,head,bd,ad,prop,hg,lh_v) then
1194 1201 print(s,right_pad(" ("+rid+")",10)+" ");
1195 1202 print(s,right_pad(head+":",15)+" ");
1196   - map_forget((String x) |-> print(s,x+" "),reverse(bd));
  1203 + map_forget((APG_Symbol_Act x) |-> print(s,x); print(s," "),reverse(bd));
1197 1204 print(s,". ");
1198   - map_forget((String x) |-> print(s,x+" "),ad);
1199   - print(s,"\n Lookaheads: ");
  1205 + map_forget((APG_Symbol_Act x) |-> print(s,x); print(s," "),ad);
  1206 + print(s,"\n Lookaheads: ");
1200 1207 map_forget((String n) |-> print(s," "+n),merge_sort(*lh_v,string_less));
1201 1208 print(s,"\n").
1202 1209  
... ... @@ -1239,7 +1246,7 @@ define One
1239 1246 if sym:all_tokens
1240 1247 then print(s,"\n "+right_pad(sym,20)+" shift and go to state "+id)
1241 1248 else print(s,"\n "+right_pad(sym,20)+" restart from state "+id),
1242   - transitions).
  1249 + merge_sort(transitions,less)).
1243 1250  
1244 1251  
1245 1252  
... ... @@ -1258,12 +1265,12 @@ define One
1258 1265 [ ] then unique,
1259 1266 [sc1 . others] then
1260 1267 if sc1 is scenario(rid,head,bd,ad,prop,hg,lh_v) then
1261   - if ad is
  1268 + if symbols_only(ad) is
1262 1269 {
1263 1270 [ ] then
1264 1271 map_forget((String lh) |->
1265 1272 print(s,"\n "+right_pad(lh,20)+" reduce using rule "+rid),
1266   - *lh_v),
  1273 + merge_sort(*lh_v,string_less)),
1267 1274 [_ . _] then print_reductions(s,others)
1268 1275 }
1269 1276 }.
... ... @@ -1301,7 +1308,7 @@ define One
1301 1308 ) =
1302 1309 print(s,"\n\ndefine List(Token_"+parser_name+") token_list_"+state_id+" =");
1303 1310 print(s,"\n [");
1304   - print_acceptable_tokens(s,map(symbol,behaviors) - non_terminals);
  1311 + print_acceptable_tokens(s,merge_sort(map(symbol,behaviors) - non_terminals,string_less));
1305 1312 print(s,"\n ].").
1306 1313  
1307 1314  
... ... @@ -1348,13 +1355,13 @@ define List(String)
1348 1355 [h . t] then
1349 1356 with rest = get_longuest_stack_for(tok_name,t),
1350 1357 if h is scenario(id,head,bd,ad,prop,hg,_) then
1351   - if ad is
  1358 + if symbols_only(ad) is
1352 1359 {
1353 1360 [ ] then rest,
1354 1361 [sym . _] then
1355   - if sym = tok_name
  1362 + if sym = tok_name
1356 1363 then if length(bd) > length(rest)
1357   - then bd
  1364 + then symbols_only(bd)
1358 1365 else rest
1359 1366 else rest
1360 1367 }
... ... @@ -1488,10 +1495,10 @@ define One
1488 1495 define One
1489 1496 print_state_function_args
1490 1497 (
1491   - Stream s,
1492   - List(String) stack,
1493   - List(TypeEntry) type_table,
1494   - Word32 rank // of next argument to be printed
  1498 + Stream s,
  1499 + List(String) stack,
  1500 + List(TypeEntry) type_table,
  1501 + Word32 rank // of next argument to be printed
1495 1502 ) =
1496 1503 if stack is
1497 1504 {
... ... @@ -1520,12 +1527,12 @@ define One
1520 1527 define One
1521 1528 print_state_function_beginning
1522 1529 (
1523   - Stream s,
1524   - Word32 state_id,
1525   - String parser_name,
1526   - List(String) stack,
1527   - List(TypeEntry) type_table,
1528   - Maybe(Extra) mb_extra
  1530 + Stream s,
  1531 + Word32 state_id,
  1532 + String parser_name,
  1533 + List(String) stack,
  1534 + List(TypeEntry) type_table,
  1535 + Maybe(Extra) mb_extra
1529 1536 ) =
1530 1537 print(s,"\n\ndefine Ret_"+parser_name+"(Non_Terminal_Value_"+parser_name+")\n");
1531 1538 print(s," state_"+state_id+"\n");
... ... @@ -1549,7 +1556,7 @@ define One
1549 1556 print_state_function_declaration
1550 1557 (
1551 1558 Stream s,
1552   - Word32 state_id,
  1559 + Word32 state_id,
1553 1560 String parser_name,
1554 1561 List(String) stack,
1555 1562 List(TypeEntry) type_table,
... ... @@ -1609,7 +1616,7 @@ define One
1609 1616  
1610 1617 success(sc) then if sc is scenario(rid,_,bd,_,_,_,_) then
1611 1618 print(s," unput_token(input)(next);\n");
1612   - with nargs = length(bd),
  1619 + with nargs = length(symbols_only(bd)),
1613 1620 (if nargs = 0
1614 1621 then print(s," if reduce_"+rid+
1615 1622 if mb_extra is
... ... @@ -1652,7 +1659,7 @@ define One
1652 1659 List(String) all_tokens,
1653 1660 List(APG_Scenario) scs,
1654 1661 List(APG_Transition) transitions,
1655   - Word32 state_id,
  1662 + Word32 state_id,
1656 1663 List(String) stack,
1657 1664 List(Conflict) conflicts,
1658 1665 List(APG_Option) options,
... ... @@ -1712,14 +1719,35 @@ define One
1712 1719 }.
1713 1720  
1714 1721  
  1722 +define Maybe(String)
  1723 + has_immediate_action
  1724 + (
  1725 + List(APG_Scenario) l
  1726 + ) =
  1727 + if l is
  1728 + {
  1729 + [ ] then failure,
  1730 + [h . t] then if h is
  1731 + scenario(_,_,bd,ad,_,_,_) then
  1732 + if ad is
  1733 + {
  1734 + [ ] then failure,
  1735 + [u . v] then if u is
  1736 + {
  1737 + symbol(_) then has_immediate_action(t),
  1738 + command(text) then success(text)
  1739 + }
  1740 + }
  1741 + }.
  1742 +
1715 1743  
1716 1744 define One
1717 1745 print_state_function
1718 1746 (
1719 1747 Stream s,
1720   - Word32 state_id,
  1748 + Word32 state_id,
1721 1749 String parser_name,
1722   - List(String) stack,
  1750 + List(APG_Symbol_Act) stack,
1723 1751 List(TypeEntry) type_table,
1724 1752 List(String) all_tokens,
1725 1753 List(APG_Transition) transitions,
... ... @@ -1729,15 +1757,21 @@ define One
1729 1757 Bool has_restarts,
1730 1758 Maybe(Extra) mb_extra
1731 1759 ) =
1732   - print_state_function_beginning(s,state_id,parser_name,stack,type_table,mb_extra);
  1760 + print_state_function_beginning(s,state_id,parser_name,symbols_only(stack),type_table,mb_extra);
1733 1761 print(s," =\n");
1734 1762 (if trace:options
1735 1763 then print(s," vmsg(\"Entering state "+state_id+"\");\n")
1736 1764 else unique);
  1765 + if has_immediate_action(scs) is
  1766 + {
  1767 + failure then unique,
  1768 + success(text) then print(s," // immediate action\n");
  1769 + print(s," ("+text+");\n")
  1770 + };
1737 1771 print(s," with next = read_token(input)(unique),\n");
1738 1772 print(s," if next is\n");
1739 1773 print(s," {\n");
1740   - print_state_function_cases(s,all_tokens,scs,transitions,state_id,stack,cfls,options,
  1774 + print_state_function_cases(s,all_tokens,scs,transitions,state_id,symbols_only(stack),cfls,options,
1741 1775 has_restarts,mb_extra);
1742 1776 print(s," }.\n").
1743 1777  
... ... @@ -1783,11 +1817,11 @@ define One
1783 1817 print_scenarios(s,classes);
1784 1818 print_transitions(s,transitions,all_tokens);
1785 1819 print_reductions(s,scs);
1786   - print_conflicts(s,conflicts);
  1820 + print_conflicts(s,merge_sort(conflicts,less));
1787 1821 //print_conflicts(make_stream(stdout),conflicts);
1788 1822 print_acceptable_tokens(s,st_id,parser_name,behaviors,non_terminals);
1789 1823 (if has_rest
1790   - then print_restart_function(s,st_id,parser_name,stack,scs,
  1824 + then print_restart_function(s,st_id,parser_name,symbols_only(stack),scs,
1791 1825 type_table,non_terminals,transitions,options,mb_extra)
1792 1826 else unique);
1793 1827 print_state_function(s,st_id,parser_name,stack,type_table,
... ... @@ -1855,7 +1889,7 @@ define One
1855 1889 print_state_function_declaration(s,
1856 1890 state_id,
1857 1891 parser_name,
1858   - get_longuest_stack(scs),
  1892 + symbols_only(get_longuest_stack(scs)),
1859 1893 type_table,
1860 1894 mb_extra),
1861 1895 auto);
... ...
anubis_dev/library/syntactic_analysis/calculator_example.apg
... ... @@ -94,7 +94,7 @@ TEXT(print(&quot;Try again !\n&quot;)): .
94 94 TERM(x): number(x).
95 95 TERM(x): lpar TERM(x) rpar.
96 96 TERM(0-x): minus TERM(x).
97   -TERM(x-y): TERM(x) minus $(ta(ga)da) TERM(y).
  97 +TERM(x-y): TERM(x) minus TERM(y).
98 98 TERM(x+y): TERM(x) plus TERM(y).
99 99 TERM(x*y): TERM(x) times TERM(y).
100 100 TERM(x^y): TERM(x) power TERM(y).
... ...
anubis_dev/library/syntactic_analysis/common.anubis
... ... @@ -90,6 +90,7 @@ public type APG_Error:
90 90 cannot_read_after_dollar (Word32 line),
91 91 dollar_not_followed_by_paren (Word32 line),
92 92 unexpected_end_of_file_in_command (Word32 line),
  93 + consecutive_commands (Word32 line),
93 94 incorrect_rule_precedence (Word32 line),
94 95 misclosed_rule_precedence (Word32 line),
95 96 incorrect_end_of_rule (Word32 line),
... ... @@ -200,14 +201,18 @@ public type APG_Propagation:
200 201 propagates_to_derived,
201 202 dont_propagate_to_derived.
202 203  
  204 +public type APG_Symbol_Act:
  205 + symbol (String name), // grammar symbol appearing in the body of a rule
  206 + command (String text). // immediate command
  207 +
203 208 public type APG_Scenario:
204   - scenario(Word32 rule_id,
205   - String head,
206   - List(String) before_dot,
207   - List(String) after_dot,
208   - APG_Propagation propagation,
209   - Var(Bool) has_generated,
210   - Var(List(String)) lookaheads_v).
  209 + scenario(Word32 rule_id,
  210 + String head,
  211 + List(APG_Symbol_Act) before_dot,
  212 + List(APG_Symbol_Act) after_dot,
  213 + APG_Propagation propagation,
  214 + Var(Bool) has_generated,
  215 + Var(List(String)) lookaheads_v).
211 216  
212 217 public type APG_Class:
213 218 class(String transition,
... ... @@ -216,28 +221,53 @@ public type APG_Class:
216 221  
217 222 public type APG_State:
218 223 state(Word32 state_id,
  224 + //Maybe(String) preaction, // action $(term) to execute before reading the lookahead
219 225 List(APG_Class) classes,
220 226 List(APG_Transition) transitions).
221 227  
222 228  
  229 +
  230 +public define Bool
  231 + less
  232 + (
  233 + APG_Transition t1,
  234 + APG_Transition t2
  235 + ) =
  236 + symbol(t1) < symbol(t2).
  237 +
223 238 Getting all symbol names from a grammar.
224 239  
225   -define List(String)
  240 +define List(APG_Symbol_Act)
226 241 names_in
227 242 (
228 243 TailItem i
229 244 ) =
230 245 if i is
231 246 {
232   - symbol_value(name,value) then [name],
  247 + symbol_value(name,value) then [symbol(name)],
233 248 plus(items,sym,v) then no_doubles(flat(map(names_in,items))),
234 249 star(items,sym,v) then no_doubles(flat(map(names_in,items))),
235 250 maybe(items,sym,v) then no_doubles(flat(map(names_in,items))),
236   - command(text) then [ ]
  251 + command(text) then [command(text)]
237 252 }.
238 253  
239 254  
240   -public define List(String)
  255 +public define List(APG_Symbol_Act)
  256 + drop_leading_command // if any
  257 + (
  258 + List(APG_Symbol_Act) l
  259 + ) =
  260 + if l is
  261 + {
  262 + [ ] then [ ],
  263 + [h . t] then if h is
  264 + {
  265 + symbol(_) then l,
  266 + command(_) then t
  267 + }
  268 + }.
  269 +
  270 +public define List(APG_Symbol_Act)
241 271 names_in
242 272 (
243 273 List(APG_Tail_Symbol_Value) l
... ... @@ -247,12 +277,44 @@ public define List(String)
247 277 [ ] then [ ],
248 278 [h . t] then if h is
249 279 {
250   - symbol_value(n,_) then [n . names_in(t)],
251   - command(_) then names_in(t)
  280 + symbol_value(n,_) then [symbol(n) . names_in(t)],
  281 + command(text) then [command(text) . names_in(t)]
252 282 }
253 283 }.
254 284  
255 285 public define List(String)
  286 + symbols_only
  287 + (
  288 + List(APG_Tail_Symbol_Value) l
  289 + ) =
  290 + if l is
  291 + {
  292 + [ ] then [ ],
  293 + [h . t] then if h is
  294 + {
  295 + symbol_value(name,_) then [name . symbols_only(t)],
  296 + command(_) then symbols_only(t)
  297 + }
  298 + }.
  299 +
  300 +
  301 +
  302 +public define List(String)
  303 + symbols_only
  304 + (
  305 + List(APG_Symbol_Act) l
  306 + ) =
  307 + if l is
  308 + {
  309 + [ ] then [ ],
  310 + [h . t] then if h is
  311 + {
  312 + symbol(name) then [name . symbols_only(t)],
  313 + command(_) then symbols_only(t)
  314 + }
  315 + }.
  316 +
  317 +public define List(String)
256 318 all_symbols_aux
257 319 (
258 320 List(APG_Grammar_Rule) rules
... ... @@ -263,9 +325,10 @@ public define List(String)
263 325 [rule1 . other_rules] then
264 326 if rule1 is grammar_rule(_,head,body,_) then
265 327 no_doubles(merge([name(head)],
266   - merge(no_doubles(names_in(body)),all_symbols_aux(other_rules))))
  328 + merge(no_doubles(symbols_only(names_in(body))),all_symbols_aux(other_rules))))
267 329 }.
268 330  
  331 +
269 332 public define List(String)
270 333 all_symbols
271 334 (
... ... @@ -366,6 +429,17 @@ define String
366 429 }.
367 430  
368 431  
  432 +public define One
  433 + print
  434 + (
  435 + APG_Symbol_Act s
  436 + ) =
  437 + if s is
  438 + {
  439 + symbol(x) then print(x),
  440 + command(text) then print("$("+text+")")
  441 + }.
  442 +
369 443 define One
370 444 print
371 445 (
... ... @@ -448,6 +522,9 @@ public define One
448 522 unexpected_end_of_file_in_command(Word32 line) then
449 523 print(to_decimal(line)+": Unexpected end of file within an immediate command.\n"),
450 524  
  525 + consecutive_commands(Word32 line) then
  526 + print(to_decimal(line)+": Consecutive immediate commands are forbidden.\n"),
  527 +
451 528 incorrect_rule_precedence(Word32 line) then
452 529 print(to_decimal(line)+": Incorrect rule precedence.\n"),
453 530  
... ... @@ -555,6 +632,18 @@ public define String
555 632 right_pad(to_decimal(s),n).
556 633  
557 634  
  635 +public define One
  636 + print
  637 + (
  638 + Stream s,
  639 + APG_Symbol_Act x
  640 + ) =
  641 + if x is
  642 + {
  643 + symbol(a) then print(s,a),
  644 + command(t) then print(s,"$("+t+")")
  645 + }.
  646 +
558 647 define One
559 648 print
560 649 (
... ...
anubis_dev/library/syntactic_analysis/make_automaton.anubis
... ... @@ -202,15 +202,15 @@ define List(FirstEntry)
202 202 define List(String)
203 203 get_first_tokens
204 204 (
205   - String key,
  205 + APG_Symbol_Act key,
206 206 List(FirstEntry) first
207 207 ) =
208 208 if first is
209 209 {
210   - [ ] then [ ], // will never happen since all symbols have entries
  210 + [ ] then [ ], // will happen only if key is a command
211 211 [e1 . other_entries] then
212 212 if e1 is first_entry(name,value) then
213   - if key = name
  213 + if key = symbol(name)
214 214 then value
215 215 else get_first_tokens(key,other_entries)
216 216 }.
... ... @@ -220,15 +220,14 @@ define List(String)
220 220 define List(String)
221 221 get_first_tokens
222 222 (
223   - List(String) sequence,
224   - List(FirstEntry) first
  223 + List(APG_Symbol_Act) sequence,
  224 + List(FirstEntry) first
225 225 ) =
226 226 if sequence is
227 227 {
228 228 [ ] then ["empty"],
229 229 [_X1 . _Xs] then
230 230 with first_X1 = get_first_tokens(_X1,first),
231   - //if member(first_X1,"empty")
232 231 if "empty":first_X1
233 232 then merge(first_X1 - ["empty"],get_first_tokens(_Xs,first))
234 233 else first_X1
... ... @@ -262,7 +261,7 @@ define List(FirstEntry)
262 261 [_X . w] then if _X is
263 262 {
264 263 symbol_value(nameX,_) then
265   - with first_X = get_first_tokens(nameX,first),
  264 + with first_X = get_first_tokens(symbol(nameX),first),
266 265 if "empty":first_X
267 266 then saturate_one_step(
268 267 add_first_tokens(_A,
... ... @@ -287,7 +286,7 @@ define List(FirstEntry)
287 286 [_Y . k] then if _Y is
288 287 {
289 288 symbol_value(nameY,_) then
290   - with first_Y = get_first_tokens(nameY,first),
  289 + with first_Y = get_first_tokens(symbol(nameY),first),
291 290 if "empty":first_Y
292 291 then saturate_one_step(
293 292 add_first_tokens(_A,
... ... @@ -400,10 +399,10 @@ define One
400 399 is a type 1 scenario.
401 400  
402 401 type Scenario1:
403   - scenario1(Word32 rule_id, // id of grammar rule
404   - String head, // A
405   - List(String) before_dot, // u in reverse order
406   - List(String) after_dot). // v in natural order
  402 + scenario1(Word32 rule_id, // id of grammar rule
  403 + String head, // A
  404 + List(APG_Symbol_Act) before_dot, // u in reverse order
  405 + List(APG_Symbol_Act) after_dot). // v in natural order
407 406  
408 407 A type 1 scenario may have one of the following two forms:
409 408  
... ... @@ -534,11 +533,29 @@ define List(Scenario1)
534 533 if after_dot is
535 534 {
536 535 [ ] then saturate([sc1 . already_used],already_used_Bs,scs,rules),
537   - [_B . v] then
538   - if _B : already_used_Bs
539   - then saturate([sc1 . already_used],already_used_Bs,scs,rules)
540   - else with new = derived_scenarios(_B,rules) - already_used - not_yet_used,
541   - saturate([sc1 . already_used],[_B . already_used_Bs],new+scs,rules)
  536 + [sa . v] then
  537 + if sa is
  538 + {
  539 + symbol(_B) then
  540 + if _B : already_used_Bs
  541 + then saturate([sc1 . already_used],already_used_Bs,scs,rules)
  542 + else with new = derived_scenarios(_B,rules) - already_used - not_yet_used,
  543 + saturate([sc1 . already_used],[_B . already_used_Bs],new+scs,rules)
  544 + command(_) then if v is
  545 + {
  546 + [ ] then saturate([sc1 . already_used],already_used_Bs,scs,rules),
  547 + [k . _] then
  548 + if k is
  549 + {
  550 + symbol(_B) then
  551 + if _B : already_used_Bs
  552 + then saturate([sc1 . already_used],already_used_Bs,scs,rules)
  553 + else with new = derived_scenarios(_B,rules) - already_used - not_yet_used,
  554 + saturate([sc1 . already_used],[_B . already_used_Bs],new+scs,rules),
  555 + command(_) then should_not_happen([])
  556 + }
  557 + }
  558 + }
542 559 }
543 560 }.
544 561  
... ... @@ -561,7 +578,20 @@ define List(Class1)
561 578 with transition = if ad is
562 579 {
563 580 [ ] then "empty",
564   - [_X . _] then _X
  581 + [_X . l] then if _X is
  582 + {
  583 + symbol(x) then x,
  584 + command(_) then if l is
  585 + {
  586 + [ ] then "empty",
  587 + [k . z] then if k is
  588 + {
  589 + symbol(y) then y,
  590 + command(_) then should_not_happen("")
  591 + // because no consecutive commands
  592 + }
  593 + }
  594 + }
565 595 },
566 596 if classes is
567 597 {
... ... @@ -621,8 +651,16 @@ define Scenario1
621 651 if ad is
622 652 {
623 653 [ ] then should_not_happen(sc),
624   - [_X . v] then
625   - scenario1(id,_A,[_X . bd],v)
  654 + [k . v] then
  655 + if k is
  656 + {
  657 + symbol(_) then scenario1(id,_A,[k . bd],v),
  658 + command(_) then if v is
  659 + {
  660 + [ ] then should_not_happen(sc),
  661 + [h . t] then scenario1(id,_A,[h , k . bd],t),
  662 + }
  663 + }
626 664 }.
627 665  
628 666  
... ... @@ -777,7 +815,7 @@ define List(State1)
777 815 if rule1 is grammar_rule(id1,_A,_,_) then
778 816 with initial_state = dispatch(saturate([],
779 817 [],
780   - [scenario1(0,"start",[],[name(_A)])],
  818 + [scenario1(0,"start",[],[symbol(name(_A))])],
781 819 rules)),
782 820 saturate([],[],[initial_state],rules,0,verbose : options)
783 821 },
... ... @@ -853,19 +891,37 @@ define Word32
853 891 define APG_Propagation
854 892 compute_propagation
855 893 (
856   - List(String) after_dot,
857   - List(String) non_terminals,
858   - List(FirstEntry) first
  894 + List(APG_Symbol_Act) after_dot,
  895 + List(String) non_terminals,
  896 + List(FirstEntry) first
859 897 ) =
860 898 if after_dot is
861 899 {
862 900 [ ] then dont_propagate_to_derived,
863   - [_Y . v] then
864   - if _Y:non_terminals
865   - then if "empty":get_first_tokens(v,first)
866   - then propagates_to_derived
867   - else dont_propagate_to_derived
868   - else dont_propagate_to_derived
  901 + [u . v] then
  902 + if u is
  903 + {
  904 + symbol(_Y) then
  905 + if _Y:non_terminals
  906 + then if "empty":get_first_tokens(v,first)
  907 + then propagates_to_derived
  908 + else dont_propagate_to_derived
  909 + else dont_propagate_to_derived
  910 + command(_) then if v is
  911 + {
  912 + [ ] then dont_propagate_to_derived,
  913 + [h . _] then if h is
  914 + {
  915 + symbol(_Z) then
  916 + if _Z:non_terminals
  917 + then if "empty":get_first_tokens(v,first)
  918 + then propagates_to_derived
  919 + else dont_propagate_to_derived
  920 + else dont_propagate_to_derived
  921 + command(_) then should_not_happen(dont_propagate_to_derived)
  922 + }
  923 + }
  924 + }
869 925 }.
870 926  
871 927  
... ... @@ -941,9 +997,9 @@ define One
941 997 if sc is scenario1(id,head,bd,ad) then
942 998 print("\n ["+right_pad(id,4)+"] ");
943 999 print(right_pad(head+":",14));
944   - map_forget((String s) |-> print(s+" "),reverse(bd));
  1000 + map_forget((APG_Symbol_Act s) |-> print(s); print(" "),reverse(bd));
945 1001 print(". ");
946   - map_forget((String s) |-> print(s+" "),ad).
  1002 + map_forget((APG_Symbol_Act s) |-> print(s); print(" "),ad).
947 1003  
948 1004 define One
949 1005 print
... ... @@ -953,9 +1009,9 @@ define One
953 1009 if sc is scenario(id,head,bd,ad,prop,hg,l) then
954 1010 print("\n ["+right_pad(id,4)+"] ");
955 1011 print(right_pad(head+":",14));
956   - map_forget((String s) |-> print(s+" "),reverse(bd));
  1012 + map_forget((APG_Symbol_Act s) |-> print(s); print(" "),reverse(bd));
957 1013 print(". ");
958   - map_forget((String s) |-> print(s+" "),ad);
  1014 + map_forget((APG_Symbol_Act s) |-> print(s); print(" "),ad);
959 1015 print("\n { ");
960 1016 map_forget((String s) |-> print(s+" "),*l);
961 1017 print("}").
... ... @@ -1087,15 +1143,15 @@ define One
1087 1143 define List(String)
1088 1144 v_star_E
1089 1145 (
1090   - List(String) v,
1091   - List(String) _E,
1092   - List(FirstEntry) first
  1146 + List(APG_Symbol_Act) v,
  1147 + List(String) _E,
  1148 + List(FirstEntry) first
1093 1149 ) =
1094 1150 if _E is
1095 1151 {
1096 1152 [ ] then [ ],
1097 1153 [a . others] then
1098   - merge(get_first_tokens(v+[a],first),v_star_E(v,others,first))
  1154 + merge(get_first_tokens(v+[symbol(a)],first),v_star_E(v,others,first))
1099 1155 }.
1100 1156  
1101 1157  
... ... @@ -1176,7 +1232,7 @@ define List((APG_Scenario,APG_State))
1176 1232 APG_State st
1177 1233 ) =
1178 1234 if sc is scenario(_,_,bd,ad,_,_,_) then
1179   - if ad is
  1235 + if symbols_only(ad) is
1180 1236 {
1181 1237 [ ] then [ ],
1182 1238 [_B . v] then
... ... @@ -1210,16 +1266,16 @@ define APG_State
1210 1266 define Maybe(APG_Scenario)
1211 1267 find_successor
1212 1268 (
1213   - Word32 rule_id,
1214   - List(String) after_dot,
1215   - List(APG_Scenario) scs
  1269 + Word32 rule_id,
  1270 + List(APG_Symbol_Act) after_dot,
  1271 + List(APG_Scenario) scs
1216 1272 ) =
1217 1273 if scs is
1218 1274 {
1219 1275 [ ] then failure,
1220 1276 [sc1 . others] then
1221 1277 if sc1 is scenario(id,_,_,ad,_,_,_) then
1222   - if (rule_id,after_dot) = (id,ad)
  1278 + if rule_id = id & after_dot = ad
1223 1279 then success(sc1)
1224 1280 else find_successor(rule_id,after_dot,others)
1225 1281 }.
... ... @@ -1227,9 +1283,9 @@ define Maybe(APG_Scenario)
1227 1283 define APG_Scenario
1228 1284 find_successor
1229 1285 (
1230   - Word32 rule_id,
1231   - List(String) after_dot,
1232   - List(APG_Class) classes
  1286 + Word32 rule_id,
  1287 + List(APG_Symbol_Act) after_dot,
  1288 + List(APG_Class) classes
1233 1289 ) =
1234 1290 if classes is
1235 1291 {
... ... @@ -1251,13 +1307,18 @@ define List((APG_Scenario,APG_State))
1251 1307 List(APG_State) auto
1252 1308 ) =
1253 1309 if from is scenario(rule_id,_,bd,ad,prop,hg,lh_v) then
1254   - if ad is
  1310 + if symbols_only(ad) is
1255 1311 {
1256 1312 [ ] then [ ], // no successor for a reducing scenario
1257 1313 [_X . v] then
1258 1314 if source is state(_,_,transitions) then
1259 1315 with target = find_state(get_transition(_X,transitions),auto),
1260   - [(find_successor(rule_id,v,classes(target)),target)]
  1316 + if drop_leading_command(ad) is
  1317 + {
  1318 + [ ] then should_not_happen([]),
  1319 + [_ . t] then
  1320 + [(find_successor(rule_id,t,classes(target)),target)]
  1321 + }
1261 1322 }.
1262 1323  
1263 1324  
... ... @@ -1297,14 +1358,14 @@ define One
1297 1358 else unique);
1298 1359 */
1299 1360 if from is scenario(_,_,bd1,ad1,prop1,hg1,lh1_v) then
1300   - with tail_ad1 = if ad1 is
  1361 + with tail_ad1 = if drop_leading_command(ad1) is
1301 1362 {
1302 1363 [ ] then should_not_happen([]), // ad1 cannot be empty
1303 1364 [_ . t] then t
1304 1365 },
1305 1366 if to is scenario(_,_,bd2,ad2,prop2,hg2,lh2_v) then
1306 1367 with previous = *lh2_v,
1307   - if bd2 is
  1368 + if drop_leading_command(bd2) is
1308 1369 {
1309 1370 [ ] then // 'to' is a derived scenario
1310 1371 //(if *lh1_v = [] then should_not_happen(unique) else unique);
... ... @@ -1318,7 +1379,7 @@ define One
1318 1379 };
1319 1380 if length(*lh2_v) = length(previous)
1320 1381 then unique // stop propagation if nothing changed in 'to'
1321   - else if ad2 is
  1382 + else if drop_leading_command(ad2) is
1322 1383 {
1323 1384 [ ] then unique, // reducing scenarios don't propagate
1324 1385 [_ . _] then propagate_lookaheads(to,target,auto,first,verbose)
... ...
anubis_dev/library/syntactic_analysis/read_grammar.anubis
... ... @@ -1135,6 +1135,7 @@ define Result(APG_Error,TailItem)
1135 1135 }.
1136 1136  
1137 1137  
  1138 +
1138 1139 After having read the head of a grammar rule (including the colon), we have to read the
1139 1140 body of the rule. This body is right delimited either by a dot or an opening square
1140 1141 bracket if there is a precedence level for that rule.
... ... @@ -1160,7 +1161,15 @@ define Result(APG_Error,APG_Extended_Grammar_Rule)
1160 1161 then if read_command_term(s) is
1161 1162 {
1162 1163 error(msg) then error(msg),
1163   - ok(ct) then read_grammar_rule_tail(s,_A,rule_id,[ct . so_far],typed_symbols,options)
  1164 + ok(ct) then
  1165 + if so_far is
  1166 + {
  1167 + [ ] then read_grammar_rule_tail(s,_A,rule_id,[ct],typed_symbols,options),
  1168 + [h . t] then
  1169 + if h is command(_)
  1170 + then error(consecutive_commands(current_line(s)))
  1171 + else read_grammar_rule_tail(s,_A,rule_id,[ct . so_far],typed_symbols,options)
  1172 + }
1164 1173 }
1165 1174 else if byte = '[' // precedence
1166 1175 then read_rule_precedence(s,_A,rule_id,reverse(so_far))
... ...